summaryrefslogtreecommitdiff
path: root/src/script
diff options
context:
space:
mode:
Diffstat (limited to 'src/script')
-rw-r--r--src/script/common/c_content.cpp86
-rw-r--r--src/script/common/c_content.h3
-rw-r--r--src/script/common/c_converter.cpp45
-rw-r--r--src/script/common/c_converter.h2
-rw-r--r--src/script/common/c_internal.cpp20
-rw-r--r--src/script/common/c_internal.h20
-rw-r--r--src/script/common/helper.cpp60
-rw-r--r--src/script/common/helper.h8
-rw-r--r--src/script/cpp_api/s_async.cpp29
-rw-r--r--src/script/cpp_api/s_async.h6
-rw-r--r--src/script/cpp_api/s_entity.cpp26
-rw-r--r--src/script/cpp_api/s_entity.h1
-rw-r--r--src/script/cpp_api/s_node.cpp19
-rw-r--r--src/script/cpp_api/s_node.h1
-rw-r--r--src/script/cpp_api/s_player.cpp13
-rw-r--r--src/script/cpp_api/s_player.h1
-rw-r--r--src/script/cpp_api/s_security.cpp11
-rw-r--r--src/script/lua_api/l_base.cpp60
-rw-r--r--src/script/lua_api/l_base.h21
-rw-r--r--src/script/lua_api/l_camera.cpp3
-rw-r--r--src/script/lua_api/l_env.cpp254
-rw-r--r--src/script/lua_api/l_env.h13
-rw-r--r--src/script/lua_api/l_http.cpp29
-rw-r--r--src/script/lua_api/l_http.h4
-rw-r--r--src/script/lua_api/l_internal.h11
-rw-r--r--src/script/lua_api/l_inventory.cpp1
-rw-r--r--src/script/lua_api/l_item.cpp14
-rw-r--r--src/script/lua_api/l_item.h3
-rw-r--r--src/script/lua_api/l_localplayer.cpp4
-rw-r--r--src/script/lua_api/l_mainmenu.cpp259
-rw-r--r--src/script/lua_api/l_mainmenu.h12
-rw-r--r--src/script/lua_api/l_mapgen.cpp13
-rw-r--r--src/script/lua_api/l_metadata.cpp8
-rw-r--r--src/script/lua_api/l_minimap.cpp24
-rw-r--r--src/script/lua_api/l_noise.cpp2
-rw-r--r--src/script/lua_api/l_object.cpp1362
-rw-r--r--src/script/lua_api/l_object.h68
-rw-r--r--src/script/lua_api/l_server.cpp124
-rw-r--r--src/script/lua_api/l_server.h2
-rw-r--r--src/script/lua_api/l_settings.cpp2
-rw-r--r--src/script/lua_api/l_util.cpp18
-rw-r--r--src/script/lua_api/l_util.h6
-rw-r--r--src/script/scripting_mainmenu.cpp1
43 files changed, 1362 insertions, 1307 deletions
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index 3dfd7ce61..6995f6b61 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -56,6 +56,7 @@ void read_item_definition(lua_State* L, int index,
es_ItemType, ITEM_NONE);
getstringfield(L, index, "name", def.name);
getstringfield(L, index, "description", def.description);
+ getstringfield(L, index, "short_description", def.short_description);
getstringfield(L, index, "inventory_image", def.inventory_image);
getstringfield(L, index, "inventory_overlay", def.inventory_overlay);
getstringfield(L, index, "wield_image", def.wield_image);
@@ -82,9 +83,6 @@ void read_item_definition(lua_State* L, int index,
getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
- warn_if_field_exists(L, index, "tool_digging_properties",
- "Obsolete; use tool_capabilities");
-
lua_getfield(L, index, "tool_capabilities");
if(lua_istable(L, -1)){
def.tool_capabilities = new ToolCapabilities(
@@ -142,6 +140,10 @@ void push_item_definition_full(lua_State *L, const ItemDefinition &i)
lua_setfield(L, -2, "name");
lua_pushstring(L, i.description.c_str());
lua_setfield(L, -2, "description");
+ if (!i.short_description.empty()) {
+ lua_pushstring(L, i.short_description.c_str());
+ lua_setfield(L, -2, "short_description");
+ }
lua_pushstring(L, type.c_str());
lua_setfield(L, -2, "type");
lua_pushstring(L, i.inventory_image.c_str());
@@ -310,6 +312,17 @@ void read_object_properties(lua_State *L, int index,
prop->nametag_color = color;
}
lua_pop(L, 1);
+ lua_getfield(L, -1, "nametag_bgcolor");
+ if (!lua_isnil(L, -1)) {
+ if (lua_toboolean(L, -1)) {
+ video::SColor color;
+ if (read_color(L, -1, &color))
+ prop->nametag_bgcolor = color;
+ } else {
+ prop->nametag_bgcolor = nullopt;
+ }
+ }
+ lua_pop(L, 1);
lua_getfield(L, -1, "automatic_face_movement_max_rotation_per_sec");
if (lua_isnumber(L, -1)) {
@@ -328,6 +341,7 @@ void read_object_properties(lua_State *L, int index,
getfloatfield(L, -1, "zoom_fov", prop->zoom_fov);
getboolfield(L, -1, "use_texture_alpha", prop->use_texture_alpha);
getboolfield(L, -1, "shaded", prop->shaded);
+ getboolfield(L, -1, "show_on_minimap", prop->show_on_minimap);
getstringfield(L, -1, "damage_texture_modifier", prop->damage_texture_modifier);
}
@@ -400,6 +414,13 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
lua_setfield(L, -2, "nametag");
push_ARGB8(L, prop->nametag_color);
lua_setfield(L, -2, "nametag_color");
+ if (prop->nametag_bgcolor) {
+ push_ARGB8(L, prop->nametag_bgcolor.value());
+ lua_setfield(L, -2, "nametag_bgcolor");
+ } else {
+ lua_pushboolean(L, false);
+ lua_setfield(L, -2, "nametag_bgcolor");
+ }
lua_pushnumber(L, prop->automatic_face_movement_max_rotation_per_sec);
lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec");
lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size());
@@ -416,6 +437,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
lua_setfield(L, -2, "shaded");
lua_pushlstring(L, prop->damage_texture_modifier.c_str(), prop->damage_texture_modifier.size());
lua_setfield(L, -2, "damage_texture_modifier");
+ lua_pushboolean(L, prop->show_on_minimap);
+ lua_setfield(L, -2, "show_on_minimap");
}
/******************************************************************************/
@@ -488,13 +511,11 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
}
/******************************************************************************/
-ContentFeatures read_content_features(lua_State *L, int index)
+void read_content_features(lua_State *L, ContentFeatures &f, int index)
{
if(index < 0)
index = lua_gettop(L) + 1 + index;
- ContentFeatures f;
-
/* Cache existence of some callbacks */
lua_getfield(L, index, "on_construct");
if(!lua_isnil(L, -1)) f.has_on_construct = true;
@@ -617,22 +638,39 @@ ContentFeatures read_content_features(lua_State *L, int index)
}
lua_pop(L, 1);
- f.alpha = getintfield_default(L, index, "alpha", 255);
+ /* alpha & use_texture_alpha */
+ // This is a bit complicated due to compatibility
+
+ f.setDefaultAlphaMode();
+
+ warn_if_field_exists(L, index, "alpha",
+ "Obsolete, only limited compatibility provided; "
+ "replaced by \"use_texture_alpha\"");
+ if (getintfield_default(L, index, "alpha", 255) != 255)
+ f.alpha = ALPHAMODE_BLEND;
+
+ lua_getfield(L, index, "use_texture_alpha");
+ if (lua_isboolean(L, -1)) {
+ warn_if_field_exists(L, index, "use_texture_alpha",
+ "Boolean values are deprecated; use the new choices");
+ if (lua_toboolean(L, -1))
+ f.alpha = (f.drawtype == NDT_NORMAL) ? ALPHAMODE_CLIP : ALPHAMODE_BLEND;
+ } else if (check_field_or_nil(L, -1, LUA_TSTRING, "use_texture_alpha")) {
+ int result = f.alpha;
+ string_to_enum(ScriptApiNode::es_TextureAlphaMode, result,
+ std::string(lua_tostring(L, -1)));
+ f.alpha = static_cast<enum AlphaMode>(result);
+ }
+ lua_pop(L, 1);
- bool usealpha = getboolfield_default(L, index,
- "use_texture_alpha", false);
- if (usealpha)
- f.alpha = 0;
+ /* Other stuff */
- // Read node color.
lua_getfield(L, index, "color");
read_color(L, -1, &f.color);
lua_pop(L, 1);
getstringfield(L, index, "palette", f.palette_name);
- /* Other stuff */
-
lua_getfield(L, index, "post_effect_color");
read_color(L, -1, &f.post_effect_color);
lua_pop(L, 1);
@@ -649,20 +687,6 @@ ContentFeatures read_content_features(lua_State *L, int index)
warningstream << "Node " << f.name.c_str()
<< " has a palette, but not a suitable paramtype2." << std::endl;
- // Warn about some obsolete fields
- warn_if_field_exists(L, index, "wall_mounted",
- "Obsolete; use paramtype2 = 'wallmounted'");
- warn_if_field_exists(L, index, "light_propagates",
- "Obsolete; determined from paramtype");
- warn_if_field_exists(L, index, "dug_item",
- "Obsolete; use 'drop' field");
- warn_if_field_exists(L, index, "extra_dug_item",
- "Obsolete; use 'drop' field");
- warn_if_field_exists(L, index, "extra_dug_item_rarity",
- "Obsolete; use 'drop' field");
- warn_if_field_exists(L, index, "metadata_name",
- "Obsolete; use on_add and metadata callbacks");
-
// True for all ground-like things like stone and mud, false for eg. trees
getboolfield(L, index, "is_ground_content", f.is_ground_content);
f.light_propagates = (f.param_type == CPT_LIGHT);
@@ -797,7 +821,6 @@ ContentFeatures read_content_features(lua_State *L, int index)
getstringfield(L, index, "node_dig_prediction",
f.node_dig_prediction);
- return f;
}
void push_content_features(lua_State *L, const ContentFeatures &c)
@@ -1959,9 +1982,10 @@ void push_hud_element(lua_State *L, HudElement *elem)
HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
{
HudElementStat stat = HUD_STAT_NUMBER;
+ std::string statstr;
if (lua_isstring(L, 3)) {
int statint;
- std::string statstr = lua_tostring(L, 3);
+ statstr = lua_tostring(L, 3);
stat = string_to_enum(es_HudElementStat, statint, statstr) ?
(HudElementStat)statint : stat;
}
@@ -1989,6 +2013,8 @@ HudElementStat read_hud_change(lua_State *L, HudElement *elem, void **value)
break;
case HUD_STAT_ITEM:
elem->item = luaL_checknumber(L, 4);
+ if (elem->type == HUD_ELEM_WAYPOINT && statstr == "precision")
+ elem->item++;
*value = &elem->item;
break;
case HUD_STAT_DIR:
diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h
index 8f32e58eb..29d576355 100644
--- a/src/script/common/c_content.h
+++ b/src/script/common/c_content.h
@@ -67,7 +67,8 @@ struct collisionMoveResult;
extern struct EnumString es_TileAnimationType[];
-ContentFeatures read_content_features (lua_State *L, int index);
+void read_content_features (lua_State *L, ContentFeatures &f,
+ int index);
void push_content_features (lua_State *L,
const ContentFeatures &c);
diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp
index eb6ab5331..c00401b58 100644
--- a/src/script/common/c_converter.cpp
+++ b/src/script/common/c_converter.cpp
@@ -679,48 +679,3 @@ size_t write_array_slice_float(
return elem_index - 1;
}
-
-
-size_t write_array_slice_u16(
- lua_State *L,
- int table_index,
- u16 *data,
- v3u16 data_size,
- v3u16 slice_offset,
- v3u16 slice_size)
-{
- v3u16 pmin, pmax(data_size);
-
- if (slice_offset.X > 0) {
- slice_offset.X--;
- pmin.X = slice_offset.X;
- pmax.X = MYMIN(slice_offset.X + slice_size.X, data_size.X);
- }
-
- if (slice_offset.Y > 0) {
- slice_offset.Y--;
- pmin.Y = slice_offset.Y;
- pmax.Y = MYMIN(slice_offset.Y + slice_size.Y, data_size.Y);
- }
-
- if (slice_offset.Z > 0) {
- slice_offset.Z--;
- pmin.Z = slice_offset.Z;
- pmax.Z = MYMIN(slice_offset.Z + slice_size.Z, data_size.Z);
- }
-
- const u32 ystride = data_size.X;
- const u32 zstride = data_size.X * data_size.Y;
-
- u32 elem_index = 1;
- for (u32 z = pmin.Z; z != pmax.Z; z++)
- for (u32 y = pmin.Y; y != pmax.Y; y++)
- for (u32 x = pmin.X; x != pmax.X; x++) {
- u32 i = z * zstride + y * ystride + x;
- lua_pushinteger(L, data[i]);
- lua_rawseti(L, table_index, elem_index);
- elem_index++;
- }
-
- return elem_index - 1;
-}
diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h
index a4a7079fd..6ad6f3212 100644
--- a/src/script/common/c_converter.h
+++ b/src/script/common/c_converter.h
@@ -136,5 +136,3 @@ void warn_if_field_exists(lua_State *L, int table,
size_t write_array_slice_float(lua_State *L, int table_index, float *data,
v3u16 data_size, v3u16 slice_offset, v3u16 slice_size);
-size_t write_array_slice_u16(lua_State *L, int table_index, u16 *data,
- v3u16 data_size, v3u16 slice_offset, v3u16 slice_size);
diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp
index 6df1f8b7b..ad5f836c5 100644
--- a/src/script/common/c_internal.cpp
+++ b/src/script/common/c_internal.cpp
@@ -155,24 +155,28 @@ static void script_log(lua_State *L, const std::string &message,
infostream << script_get_backtrace(L) << std::endl;
}
-void log_deprecated(lua_State *L, const std::string &message, int stack_depth)
+DeprecatedHandlingMode get_deprecated_handling_mode()
{
static thread_local bool configured = false;
- static thread_local bool do_log = false;
- static thread_local bool do_error = false;
+ static thread_local DeprecatedHandlingMode ret = DeprecatedHandlingMode::Ignore;
// Only read settings on first call
if (!configured) {
std::string value = g_settings->get("deprecated_lua_api_handling");
if (value == "log") {
- do_log = true;
+ ret = DeprecatedHandlingMode::Log;
} else if (value == "error") {
- do_log = true;
- do_error = true;
+ ret = DeprecatedHandlingMode::Error;
}
configured = true;
}
- if (do_log)
- script_log(L, message, warningstream, do_error, stack_depth);
+ return ret;
+}
+
+void log_deprecated(lua_State *L, const std::string &message, int stack_depth)
+{
+ DeprecatedHandlingMode mode = get_deprecated_handling_mode();
+ if (mode != DeprecatedHandlingMode::Ignore)
+ script_log(L, message, warningstream, mode == DeprecatedHandlingMode::Error, stack_depth);
}
diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h
index 442546332..452c2dd5e 100644
--- a/src/script/common/c_internal.h
+++ b/src/script/common/c_internal.h
@@ -114,5 +114,25 @@ void script_error(lua_State *L, int pcall_result, const char *mod, const char *f
void script_run_callbacks_f(lua_State *L, int nargs,
RunCallbacksMode mode, const char *fxn);
+enum class DeprecatedHandlingMode {
+ Ignore,
+ Log,
+ Error
+};
+
+/**
+ * Reads `deprecated_lua_api_handling` in settings, returns cached value.
+ *
+ * @return DeprecatedHandlingMode
+ */
+DeprecatedHandlingMode get_deprecated_handling_mode();
+
+/**
+ * Handles a deprecation warning based on user settings
+ *
+ * @param L Lua State
+ * @param message The deprecation method
+ * @param stack_depth How far on the stack to the first user function (ie: not builtin or core)
+ */
void log_deprecated(lua_State *L, const std::string &message,
int stack_depth=1);
diff --git a/src/script/common/helper.cpp b/src/script/common/helper.cpp
index f53a2b7e8..fbf24e1b7 100644
--- a/src/script/common/helper.cpp
+++ b/src/script/common/helper.cpp
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cmath>
#include <sstream>
#include <irr_v2d.h>
+#include <irr_v3d.h>
#include "c_types.h"
#include "c_internal.h"
@@ -49,25 +50,26 @@ bool LuaHelper::isNaN(lua_State *L, int idx)
/*
* Read template functions
*/
-template <> bool LuaHelper::readParam(lua_State *L, int index)
+template <>
+bool LuaHelper::readParam(lua_State *L, int index)
{
return lua_toboolean(L, index) != 0;
}
-template <> bool LuaHelper::readParam(lua_State *L, int index, const bool &default_value)
+template <>
+s16 LuaHelper::readParam(lua_State *L, int index)
{
- if (lua_isnil(L, index))
- return default_value;
-
- return lua_toboolean(L, index) != 0;
+ return lua_tonumber(L, index);
}
-template <> s16 LuaHelper::readParam(lua_State *L, int index)
+template <>
+int LuaHelper::readParam(lua_State *L, int index)
{
- return lua_tonumber(L, index);
+ return luaL_checkint(L, index);
}
-template <> float LuaHelper::readParam(lua_State *L, int index)
+template <>
+float LuaHelper::readParam(lua_State *L, int index)
{
if (isNaN(L, index))
throw LuaError("NaN value is not allowed.");
@@ -75,7 +77,8 @@ template <> float LuaHelper::readParam(lua_State *L, int index)
return (float)luaL_checknumber(L, index);
}
-template <> v2s16 LuaHelper::readParam(lua_State *L, int index)
+template <>
+v2s16 LuaHelper::readParam(lua_State *L, int index)
{
v2s16 p;
CHECK_POS_TAB(index);
@@ -90,7 +93,8 @@ template <> v2s16 LuaHelper::readParam(lua_State *L, int index)
return p;
}
-template <> v2f LuaHelper::readParam(lua_State *L, int index)
+template <>
+v2f LuaHelper::readParam(lua_State *L, int index)
{
v2f p;
CHECK_POS_TAB(index);
@@ -105,24 +109,32 @@ template <> v2f LuaHelper::readParam(lua_State *L, int index)
return p;
}
-template <> std::string LuaHelper::readParam(lua_State *L, int index)
+template <>
+v3f LuaHelper::readParam(lua_State *L, int index)
{
- size_t length;
- std::string result;
- const char *str = luaL_checklstring(L, index, &length);
- result.assign(str, length);
- return result;
+ v3f p;
+ CHECK_POS_TAB(index);
+ lua_getfield(L, index, "x");
+ CHECK_POS_COORD("x");
+ p.X = readParam<float>(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, index, "y");
+ CHECK_POS_COORD("y");
+ p.Y = readParam<float>(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, index, "z");
+ CHECK_POS_COORD("z");
+ p.Z = readParam<float>(L, -1);
+ lua_pop(L, 1);
+ return p;
}
template <>
-std::string LuaHelper::readParam(
- lua_State *L, int index, const std::string &default_value)
+std::string LuaHelper::readParam(lua_State *L, int index)
{
+ size_t length;
std::string result;
- const char *str = lua_tostring(L, index);
- if (str)
- result.append(str);
- else
- result = default_value;
+ const char *str = luaL_checklstring(L, index, &length);
+ result.assign(str, length);
return result;
}
diff --git a/src/script/common/helper.h b/src/script/common/helper.h
index d639d6e16..6491e73cf 100644
--- a/src/script/common/helper.h
+++ b/src/script/common/helper.h
@@ -38,7 +38,8 @@ protected:
* @param index Lua Index to read
* @return read value from Lua
*/
- template <typename T> static T readParam(lua_State *L, int index);
+ template <typename T>
+ static T readParam(lua_State *L, int index);
/**
* Read a value using a template type T from Lua State L and index
@@ -50,5 +51,8 @@ protected:
* @return read value from Lua or default value if nil
*/
template <typename T>
- static T readParam(lua_State *L, int index, const T &default_value);
+ static inline T readParam(lua_State *L, int index, const T &default_value)
+ {
+ return lua_isnoneornil(L, index) ? default_value : readParam<T>(L, index);
+ }
};
diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp
index 5f1f9297e..0619b32c0 100644
--- a/src/script/cpp_api/s_async.cpp
+++ b/src/script/cpp_api/s_async.cpp
@@ -158,35 +158,6 @@ void AsyncEngine::step(lua_State *L)
}
/******************************************************************************/
-void AsyncEngine::pushFinishedJobs(lua_State* L) {
- // Result Table
- MutexAutoLock l(resultQueueMutex);
-
- unsigned int index = 1;
- lua_createtable(L, resultQueue.size(), 0);
- int top = lua_gettop(L);
-
- while (!resultQueue.empty()) {
- LuaJobInfo jobDone = resultQueue.front();
- resultQueue.pop_front();
-
- lua_createtable(L, 0, 2); // Pre-allocate space for two map fields
- int top_lvl2 = lua_gettop(L);
-
- lua_pushstring(L, "jobid");
- lua_pushnumber(L, jobDone.id);
- lua_settable(L, top_lvl2);
-
- lua_pushstring(L, "retval");
- lua_pushlstring(L, jobDone.serializedResult.data(),
- jobDone.serializedResult.size());
- lua_settable(L, top_lvl2);
-
- lua_rawseti(L, top, index++);
- }
-}
-
-/******************************************************************************/
void AsyncEngine::prepareEnvironment(lua_State* L, int top)
{
for (StateInitializer &stateInitializer : stateInitializers) {
diff --git a/src/script/cpp_api/s_async.h b/src/script/cpp_api/s_async.h
index b1f4bf45f..99a4f891c 100644
--- a/src/script/cpp_api/s_async.h
+++ b/src/script/cpp_api/s_async.h
@@ -98,12 +98,6 @@ public:
*/
void step(lua_State *L);
- /**
- * Push a list of finished jobs onto the stack
- * @param L The Lua stack
- */
- void pushFinishedJobs(lua_State *L);
-
protected:
/**
* Get a Job from queue to be processed
diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp
index ea9320051..746f7013e 100644
--- a/src/script/cpp_api/s_entity.cpp
+++ b/src/script/cpp_api/s_entity.cpp
@@ -103,6 +103,32 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
lua_pop(L, 2); // Pop object and error handler
}
+void ScriptApiEntity::luaentity_Deactivate(u16 id)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ verbosestream << "scriptapi_luaentity_deactivate: id=" << id << std::endl;
+
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
+ // Get the entity
+ luaentity_get(L, id);
+ int object = lua_gettop(L);
+
+ // Get on_deactivate
+ lua_getfield(L, -1, "on_deactivate");
+ if (!lua_isnil(L, -1)) {
+ luaL_checktype(L, -1, LUA_TFUNCTION);
+ lua_pushvalue(L, object);
+
+ setOriginFromTable(object);
+ PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+ } else {
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 2); // Pop object and error handler
+}
+
void ScriptApiEntity::luaentity_Remove(u16 id)
{
SCRIPTAPI_PRECHECKHEADER
diff --git a/src/script/cpp_api/s_entity.h b/src/script/cpp_api/s_entity.h
index b5f7a6586..b52f6e447 100644
--- a/src/script/cpp_api/s_entity.h
+++ b/src/script/cpp_api/s_entity.h
@@ -33,6 +33,7 @@ public:
bool luaentity_Add(u16 id, const char *name);
void luaentity_Activate(u16 id,
const std::string &staticdata, u32 dtime_s);
+ void luaentity_Deactivate(u16 id);
void luaentity_Remove(u16 id);
std::string luaentity_GetStaticdata(u16 id);
void luaentity_GetProperties(u16 id,
diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp
index e0f9bcd78..f23fbfbde 100644
--- a/src/script/cpp_api/s_node.cpp
+++ b/src/script/cpp_api/s_node.cpp
@@ -93,6 +93,14 @@ struct EnumString ScriptApiNode::es_NodeBoxType[] =
{0, NULL},
};
+struct EnumString ScriptApiNode::es_TextureAlphaMode[] =
+ {
+ {ALPHAMODE_OPAQUE, "opaque"},
+ {ALPHAMODE_CLIP, "clip"},
+ {ALPHAMODE_BLEND, "blend"},
+ {0, NULL},
+ };
+
bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
ServerActiveObject *puncher, const PointedThing &pointed)
{
@@ -133,9 +141,14 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
push_v3s16(L, p);
pushnode(L, node, ndef);
objectrefGetOrCreate(L, digger);
- PCALL_RES(lua_pcall(L, 3, 0, error_handler));
- lua_pop(L, 1); // Pop error handler
- return true;
+ PCALL_RES(lua_pcall(L, 3, 1, error_handler));
+
+ // nil is treated as true for backwards compat
+ bool result = lua_isnil(L, -1) || lua_toboolean(L, -1);
+
+ lua_pop(L, 2); // Pop error handler and result
+
+ return result;
}
void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
diff --git a/src/script/cpp_api/s_node.h b/src/script/cpp_api/s_node.h
index 81b44f0f0..3f771c838 100644
--- a/src/script/cpp_api/s_node.h
+++ b/src/script/cpp_api/s_node.h
@@ -54,4 +54,5 @@ public:
static struct EnumString es_ContentParamType2[];
static struct EnumString es_LiquidType[];
static struct EnumString es_NodeBoxType[];
+ static struct EnumString es_TextureAlphaMode[];
};
diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp
index 712120c61..d3e6138dc 100644
--- a/src/script/cpp_api/s_player.cpp
+++ b/src/script/cpp_api/s_player.cpp
@@ -77,6 +77,19 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
return readParam<bool>(L, -1);
}
+void ScriptApiPlayer::on_rightclickplayer(ServerActiveObject *player,
+ ServerActiveObject *clicker)
+{
+ SCRIPTAPI_PRECHECKHEADER
+ // Get core.registered_on_rightclickplayers
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_rightclickplayers");
+ // Call callbacks
+ objectrefGetOrCreate(L, player);
+ objectrefGetOrCreate(L, clicker);
+ runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
+}
+
s32 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
s32 hp_change, const PlayerHPChangeReason &reason)
{
diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h
index a337f975b..c0f141862 100644
--- a/src/script/cpp_api/s_player.h
+++ b/src/script/cpp_api/s_player.h
@@ -47,6 +47,7 @@ public:
bool on_punchplayer(ServerActiveObject *player, ServerActiveObject *hitter,
float time_from_last_punch, const ToolCapabilities *toolcap,
v3f dir, s16 damage);
+ void on_rightclickplayer(ServerActiveObject *player, ServerActiveObject *clicker);
s32 on_player_hpchange(ServerActiveObject *player, s32 hp_change,
const PlayerHPChangeReason &reason);
void on_playerReceiveFields(ServerActiveObject *player,
diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp
index 2afa3a191..63058d7c3 100644
--- a/src/script/cpp_api/s_security.cpp
+++ b/src/script/cpp_api/s_security.cpp
@@ -398,10 +398,9 @@ bool ScriptApiSecurity::safeLoadFile(lua_State *L, const char *path, const char
lua_pushfstring(L, "%s: %s", path, strerror(errno));
return false;
}
- chunk_name = new char[strlen(display_name) + 2];
- chunk_name[0] = '@';
- chunk_name[1] = '\0';
- strcat(chunk_name, display_name);
+ size_t len = strlen(display_name) + 2;
+ chunk_name = new char[len];
+ snprintf(chunk_name, len, "@%s", display_name);
}
size_t start = 0;
@@ -629,7 +628,11 @@ int ScriptApiSecurity::sl_g_loadfile(lua_State *L)
{
#ifndef SERVER
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
+#if INDIRECT_SCRIPTAPI_RIDX
+ ScriptApiBase *script = (ScriptApiBase *) *(void**)(lua_touserdata(L, -1));
+#else
ScriptApiBase *script = (ScriptApiBase *) lua_touserdata(L, -1);
+#endif
lua_pop(L, 1);
// Client implementation
diff --git a/src/script/lua_api/l_base.cpp b/src/script/lua_api/l_base.cpp
index 2bee09436..f842671b8 100644
--- a/src/script/lua_api/l_base.cpp
+++ b/src/script/lua_api/l_base.cpp
@@ -100,32 +100,21 @@ bool ModApiBase::registerFunction(lua_State *L, const char *name,
return true;
}
-std::unordered_map<std::string, luaL_Reg> ModApiBase::m_deprecated_wrappers;
-bool ModApiBase::m_error_deprecated_calls = false;
-
-int ModApiBase::l_deprecated_function(lua_State *L)
+int ModApiBase::l_deprecated_function(lua_State *L, const char *good, const char *bad, lua_CFunction func)
{
thread_local std::vector<u64> deprecated_logged;
+ DeprecatedHandlingMode dep_mode = get_deprecated_handling_mode();
+ if (dep_mode == DeprecatedHandlingMode::Ignore)
+ return func(L);
+
u64 start_time = porting::getTimeUs();
lua_Debug ar;
- // Get function name for lookup
- FATAL_ERROR_IF(!lua_getstack(L, 0, &ar), "lua_getstack() failed");
- FATAL_ERROR_IF(!lua_getinfo(L, "n", &ar), "lua_getinfo() failed");
-
- // Combine name with line and script backtrace
+ // Get caller name with line and script backtrace
FATAL_ERROR_IF(!lua_getstack(L, 1, &ar), "lua_getstack() failed");
FATAL_ERROR_IF(!lua_getinfo(L, "Sl", &ar), "lua_getinfo() failed");
- // Get parent class to get the wrappers map
- luaL_checktype(L, 1, LUA_TUSERDATA);
- void *ud = lua_touserdata(L, 1);
- ModApiBase *o = *(ModApiBase**)ud;
-
- // New function and new function name
- auto it = o->m_deprecated_wrappers.find(ar.name);
-
// Get backtrace and hash it to reduce the warning flood
std::string backtrace = ar.short_src;
backtrace.append(":").append(std::to_string(ar.currentline));
@@ -135,45 +124,16 @@ int ModApiBase::l_deprecated_function(lua_State *L)
== deprecated_logged.end()) {
deprecated_logged.emplace_back(hash);
- warningstream << "Call to deprecated function '" << ar.name << "', please use '"
- << it->second.name << "' at " << backtrace << std::endl;
+ warningstream << "Call to deprecated function '" << bad << "', please use '"
+ << good << "' at " << backtrace << std::endl;
- if (m_error_deprecated_calls)
+ if (dep_mode == DeprecatedHandlingMode::Error)
script_error(L, LUA_ERRRUN, NULL, NULL);
}
u64 end_time = porting::getTimeUs();
g_profiler->avg("l_deprecated_function", end_time - start_time);
- return it->second.func(L);
+ return func(L);
}
-void ModApiBase::markAliasDeprecated(luaL_Reg *reg)
-{
- std::string value = g_settings->get("deprecated_lua_api_handling");
- m_error_deprecated_calls = value == "error";
-
- if (!m_error_deprecated_calls && value != "log")
- return;
-
- const char *last_name = nullptr;
- lua_CFunction last_func = nullptr;
-
- // ! Null termination !
- while (reg->func) {
- if (last_func == reg->func) {
- // Duplicate found
- luaL_Reg original_reg;
- // Do not inline struct. Breaks MSVC or is error-prone
- original_reg.name = last_name;
- original_reg.func = reg->func;
- m_deprecated_wrappers.emplace(
- std::pair<std::string, luaL_Reg>(reg->name, original_reg));
- reg->func = l_deprecated_function;
- }
-
- last_func = reg->func;
- last_name = reg->name;
- ++reg;
- }
-}
diff --git a/src/script/lua_api/l_base.h b/src/script/lua_api/l_base.h
index 65fce8481..aa5905d26 100644
--- a/src/script/lua_api/l_base.h
+++ b/src/script/lua_api/l_base.h
@@ -41,7 +41,6 @@ class Environment;
class ServerInventoryManager;
class ModApiBase : protected LuaHelper {
-
public:
static ScriptApiBase* getScriptApiBase(lua_State *L);
static Server* getServer(lua_State *L);
@@ -75,10 +74,18 @@ public:
lua_CFunction func,
int top);
- static int l_deprecated_function(lua_State *L);
- static void markAliasDeprecated(luaL_Reg *reg);
-private:
- // <old_name> = { <new_name>, <new_function> }
- static std::unordered_map<std::string, luaL_Reg> m_deprecated_wrappers;
- static bool m_error_deprecated_calls;
+ /**
+ * A wrapper for deprecated functions.
+ *
+ * When called, handles the deprecation according to user settings and then calls `func`.
+ *
+ * @throws Lua Error if required by the user settings.
+ *
+ * @param L Lua state
+ * @param good Name of good function/method
+ * @param bad Name of deprecated function/method
+ * @param func Actual implementation of function
+ * @return value from `func`
+ */
+ static int l_deprecated_function(lua_State *L, const char *good, const char *bad, lua_CFunction func);
};
diff --git a/src/script/lua_api/l_camera.cpp b/src/script/lua_api/l_camera.cpp
index bfa60be67..40251154c 100644
--- a/src/script/lua_api/l_camera.cpp
+++ b/src/script/lua_api/l_camera.cpp
@@ -63,7 +63,8 @@ int LuaCamera::l_set_camera_mode(lua_State *L)
return 0;
camera->setCameraMode((CameraMode)((int)lua_tonumber(L, 2)));
- playercao->setVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
+ // Make the player visible depending on camera mode.
+ playercao->updateMeshCulling();
playercao->setChildrenVisible(camera->getCameraMode() > CAMERA_MODE_FIRST);
return 0;
}
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 89ec9dc7e..c75fc8dc7 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -407,6 +407,46 @@ int ModApiEnvMod::l_get_node_light(lua_State *L)
return 1;
}
+
+// get_natural_light(pos, timeofday)
+// pos = {x=num, y=num, z=num}
+// timeofday: nil = current time, 0 = night, 0.5 = day
+int ModApiEnvMod::l_get_natural_light(lua_State *L)
+{
+ GET_ENV_PTR;
+
+ v3s16 pos = read_v3s16(L, 1);
+
+ bool is_position_ok;
+ MapNode n = env->getMap().getNode(pos, &is_position_ok);
+ if (!is_position_ok)
+ return 0;
+
+ // If the daylight is 0, nothing needs to be calculated
+ u8 daylight = n.param1 & 0x0f;
+ if (daylight == 0) {
+ lua_pushinteger(L, 0);
+ return 1;
+ }
+
+ u32 time_of_day;
+ if (lua_isnumber(L, 2)) {
+ time_of_day = 24000.0 * lua_tonumber(L, 2);
+ time_of_day %= 24000;
+ } else {
+ time_of_day = env->getTimeOfDay();
+ }
+ u32 dnr = time_to_daynight_ratio(time_of_day, true);
+
+ // If it's the same as the artificial light, the sunlight needs to be
+ // searched for because the value may not emanate from the sun
+ if (daylight == n.param1 >> 4)
+ daylight = env->findSunlight(pos);
+
+ lua_pushinteger(L, dnr * daylight / 1000);
+ return 1;
+}
+
// place_node(pos, node)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_place_node(lua_State *L)
@@ -703,6 +743,31 @@ int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
return 1;
}
+// get_objects_in_area(pos, minp, maxp)
+int ModApiEnvMod::l_get_objects_in_area(lua_State *L)
+{
+ GET_ENV_PTR;
+ ScriptApiBase *script = getScriptApiBase(L);
+
+ v3f minp = read_v3f(L, 1) * BS;
+ v3f maxp = read_v3f(L, 2) * BS;
+ aabb3f box(minp, maxp);
+ box.repair();
+ std::vector<ServerActiveObject *> objs;
+
+ auto include_obj_cb = [](ServerActiveObject *obj){ return !obj->isGone(); };
+ env->getObjectsInArea(objs, box, include_obj_cb);
+
+ int i = 0;
+ lua_createtable(L, objs.size(), 0);
+ for (const auto obj : objs) {
+ // Insert object reference into table
+ script->objectrefGetOrCreate(L, obj);
+ lua_rawseti(L, -2, ++i);
+ }
+ return 1;
+}
+
// set_timeofday(val)
// val = 0...1
int ModApiEnvMod::l_set_timeofday(lua_State *L)
@@ -711,8 +776,9 @@ int ModApiEnvMod::l_set_timeofday(lua_State *L)
// Do it
float timeofday_f = readParam<float>(L, 1);
- sanity_check(timeofday_f >= 0.0 && timeofday_f <= 1.0);
- int timeofday_mh = (int)(timeofday_f * 24000.0);
+ luaL_argcheck(L, timeofday_f >= 0.0f && timeofday_f <= 1.0f, 1,
+ "value must be between 0 and 1");
+ int timeofday_mh = (int)(timeofday_f * 24000.0f);
// This should be set directly in the environment but currently
// such changes aren't immediately sent to the clients, so call
// the server instead.
@@ -752,29 +818,36 @@ int ModApiEnvMod::l_get_gametime(lua_State *L)
return 1;
}
-
-// 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)
+void ModApiEnvMod::collectNodeIds(lua_State *L, int idx, const NodeDefManager *ndef,
+ std::vector<content_t> &filter)
{
- GET_PLAIN_ENV_PTR;
-
- const NodeDefManager *ndef = env->getGameDef()->ndef();
- v3s16 pos = read_v3s16(L, 1);
- int radius = luaL_checkinteger(L, 2);
- std::vector<content_t> filter;
- if (lua_istable(L, 3)) {
+ if (lua_istable(L, idx)) {
lua_pushnil(L);
- while (lua_next(L, 3) != 0) {
+ while (lua_next(L, idx) != 0) {
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TSTRING);
ndef->getIds(readParam<std::string>(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, idx)) {
ndef->getIds(readParam<std::string>(L, 3), filter);
}
+}
+
+// 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_PLAIN_ENV_PTR;
+
+ const NodeDefManager *ndef = env->getGameDef()->ndef();
+ Map &map = env->getMap();
+
+ v3s16 pos = read_v3s16(L, 1);
+ int radius = luaL_checkinteger(L, 2);
+ std::vector<content_t> filter;
+ collectNodeIds(L, 3, ndef, filter);
int start_radius = (lua_isboolean(L, 4) && readParam<bool>(L, 4)) ? 0 : 1;
@@ -785,10 +858,10 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
#endif
for (int d = start_radius; d <= radius; d++) {
- std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
+ const std::vector<v3s16> &list = FacePositionCache::getFacePositions(d);
for (const v3s16 &i : list) {
v3s16 p = pos + i;
- content_t c = env->getMap().getNode(p).getContent();
+ content_t c = map.getNode(p).getContent();
if (CONTAINS(filter, c)) {
push_v3s16(L, p);
return 1;
@@ -798,8 +871,7 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
return 0;
}
-// find_nodes_in_area(minp, maxp, nodenames) -> list of positions
-// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
+// find_nodes_in_area(minp, maxp, nodenames, [grouped])
int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
{
GET_PLAIN_ENV_PTR;
@@ -809,6 +881,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
sortBoxVerticies(minp, maxp);
const NodeDefManager *ndef = env->getGameDef()->ndef();
+ Map &map = env->getMap();
#ifndef SERVER
if (Client *client = getClient(L)) {
@@ -826,45 +899,79 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
}
std::vector<content_t> filter;
- if (lua_istable(L, 3)) {
- lua_pushnil(L);
- while (lua_next(L, 3) != 0) {
- // key at index -2 and value at index -1
- luaL_checktype(L, -1, LUA_TSTRING);
- ndef->getIds(readParam<std::string>(L, -1), filter);
- // removes value, keeps key for next iteration
- lua_pop(L, 1);
+ collectNodeIds(L, 3, ndef, filter);
+
+ bool grouped = lua_isboolean(L, 4) && readParam<bool>(L, 4);
+
+ if (grouped) {
+ // create the table we will be returning
+ lua_createtable(L, 0, filter.size());
+ int base = lua_gettop(L);
+
+ // create one table for each filter
+ std::vector<u32> idx;
+ idx.resize(filter.size());
+ for (u32 i = 0; i < filter.size(); i++)
+ lua_newtable(L);
+
+ v3s16 p;
+ for (p.X = minp.X; p.X <= maxp.X; p.X++)
+ for (p.Y = minp.Y; p.Y <= maxp.Y; p.Y++)
+ for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) {
+ content_t c = map.getNode(p).getContent();
+
+ auto it = std::find(filter.begin(), filter.end(), c);
+ if (it != filter.end()) {
+ // Calculate index of the table and append the position
+ u32 filt_index = it - filter.begin();
+ push_v3s16(L, p);
+ lua_rawseti(L, base + 1 + filt_index, ++idx[filt_index]);
+ }
}
- } else if (lua_isstring(L, 3)) {
- ndef->getIds(readParam<std::string>(L, 3), filter);
- }
- std::vector<u32> individual_count;
- individual_count.resize(filter.size());
+ // last filter table is at top of stack
+ u32 i = filter.size() - 1;
+ do {
+ if (idx[i] == 0) {
+ // No such node found -> drop the empty table
+ lua_pop(L, 1);
+ } else {
+ // This node was found -> put table into the return table
+ lua_setfield(L, base, ndef->get(filter[i]).name.c_str());
+ }
+ } while (i-- != 0);
- lua_newtable(L);
- u64 i = 0;
- for (s16 x = minp.X; x <= maxp.X; x++)
- for (s16 y = minp.Y; y <= maxp.Y; y++)
- for (s16 z = minp.Z; z <= maxp.Z; z++) {
- v3s16 p(x, y, z);
- content_t c = env->getMap().getNode(p).getContent();
-
- std::vector<content_t>::iterator it = std::find(filter.begin(), filter.end(), c);
- if (it != filter.end()) {
- push_v3s16(L, p);
- lua_rawseti(L, -2, ++i);
+ assert(lua_gettop(L) == base);
+ return 1;
+ } else {
+ std::vector<u32> individual_count;
+ individual_count.resize(filter.size());
+
+ lua_newtable(L);
+ u32 i = 0;
+ v3s16 p;
+ for (p.X = minp.X; p.X <= maxp.X; p.X++)
+ for (p.Y = minp.Y; p.Y <= maxp.Y; p.Y++)
+ for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) {
+ content_t c = env->getMap().getNode(p).getContent();
- u32 filt_index = it - filter.begin();
- individual_count[filt_index]++;
+ auto it = std::find(filter.begin(), filter.end(), c);
+ if (it != filter.end()) {
+ push_v3s16(L, p);
+ lua_rawseti(L, -2, ++i);
+
+ u32 filt_index = it - filter.begin();
+ individual_count[filt_index]++;
+ }
}
+
+ lua_createtable(L, 0, filter.size());
+ for (u32 i = 0; i < filter.size(); i++) {
+ lua_pushinteger(L, individual_count[i]);
+ lua_setfield(L, -2, ndef->get(filter[i]).name.c_str());
+ }
+ return 2;
}
- lua_newtable(L);
- for (u32 i = 0; i < filter.size(); i++) {
- lua_pushnumber(L, individual_count[i]);
- lua_setfield(L, -2, ndef->get(filter[i]).name.c_str());
- }
- return 2;
}
// find_nodes_in_area_under_air(minp, maxp, nodenames) -> list of positions
@@ -885,6 +992,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
sortBoxVerticies(minp, maxp);
const NodeDefManager *ndef = env->getGameDef()->ndef();
+ Map &map = env->getMap();
#ifndef SERVER
if (Client *client = getClient(L)) {
@@ -902,33 +1010,21 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
}
std::vector<content_t> filter;
-
- if (lua_istable(L, 3)) {
- lua_pushnil(L);
- while (lua_next(L, 3) != 0) {
- // key at index -2 and value at index -1
- luaL_checktype(L, -1, LUA_TSTRING);
- ndef->getIds(readParam<std::string>(L, -1), filter);
- // removes value, keeps key for next iteration
- lua_pop(L, 1);
- }
- } else if (lua_isstring(L, 3)) {
- ndef->getIds(readParam<std::string>(L, 3), filter);
- }
+ collectNodeIds(L, 3, ndef, filter);
lua_newtable(L);
- u64 i = 0;
- for (s16 x = minp.X; x <= maxp.X; x++)
- for (s16 z = minp.Z; z <= maxp.Z; z++) {
- s16 y = minp.Y;
- v3s16 p(x, y, z);
- content_t c = env->getMap().getNode(p).getContent();
- for (; y <= maxp.Y; y++) {
- v3s16 psurf(x, y + 1, z);
- content_t csurf = env->getMap().getNode(psurf).getContent();
+ u32 i = 0;
+ v3s16 p;
+ for (p.X = minp.X; p.X <= maxp.X; p.X++)
+ for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) {
+ p.Y = minp.Y;
+ content_t c = map.getNode(p).getContent();
+ for (; p.Y <= maxp.Y; p.Y++) {
+ v3s16 psurf(p.X, p.Y + 1, p.Z);
+ content_t csurf = map.getNode(psurf).getContent();
if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
CONTAINS(filter, c)) {
- push_v3s16(L, v3s16(x, y, z));
+ push_v3s16(L, p);
lua_rawseti(L, -2, ++i);
}
c = csurf;
@@ -1310,9 +1406,9 @@ int ModApiEnvMod::l_get_translated_string(lua_State * L)
GET_ENV_PTR;
std::string lang_code = luaL_checkstring(L, 1);
std::string string = luaL_checkstring(L, 2);
- getServer(L)->loadTranslationLanguage(lang_code);
- string = wide_to_utf8(translate_string(utf8_to_wide(string),
- &(*g_server_translations)[lang_code]));
+
+ auto *translations = getServer(L)->getTranslationLanguage(lang_code);
+ string = wide_to_utf8(translate_string(utf8_to_wide(string), translations));
lua_pushstring(L, string.c_str());
return 1;
}
@@ -1328,6 +1424,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(get_node);
API_FCT(get_node_or_nil);
API_FCT(get_node_light);
+ API_FCT(get_natural_light);
API_FCT(place_node);
API_FCT(dig_node);
API_FCT(punch_node);
@@ -1341,6 +1438,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(get_node_timer);
API_FCT(get_connected_players);
API_FCT(get_player_by_name);
+ API_FCT(get_objects_in_area);
API_FCT(get_objects_inside_radius);
API_FCT(set_timeofday);
API_FCT(get_timeofday);
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index 9050b4306..42c2d64f8 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -56,6 +56,11 @@ private:
// timeofday: nil = current time, 0 = night, 0.5 = day
static int l_get_node_light(lua_State *L);
+ // get_natural_light(pos, timeofday)
+ // pos = {x=num, y=num, z=num}
+ // timeofday: nil = current time, 0 = night, 0.5 = day
+ static int l_get_natural_light(lua_State *L);
+
// place_node(pos, node)
// pos = {x=num, y=num, z=num}
static int l_place_node(lua_State *L);
@@ -109,6 +114,9 @@ private:
// get_objects_inside_radius(pos, radius)
static int l_get_objects_inside_radius(lua_State *L);
+
+ // get_objects_in_area(pos, minp, maxp)
+ static int l_get_objects_in_area(lua_State *L);
// set_timeofday(val)
// val = 0...1
@@ -190,6 +198,11 @@ private:
// Get a string translated server side
static int l_get_translated_string(lua_State * L);
+ /* Helpers */
+
+ static void collectNodeIds(lua_State *L, int idx,
+ const NodeDefManager *ndef, std::vector<content_t> &filter);
+
public:
static void Initialize(lua_State *L, int top);
static void InitializeClient(lua_State *L, int top);
diff --git a/src/script/lua_api/l_http.cpp b/src/script/lua_api/l_http.cpp
index ec43bf174..5ea3b3f99 100644
--- a/src/script/lua_api/l_http.cpp
+++ b/src/script/lua_api/l_http.cpp
@@ -49,17 +49,40 @@ void ModApiHttp::read_http_fetch_request(lua_State *L, HTTPFetchRequest &req)
req.multipart = getboolfield_default(L, 1, "multipart", false);
req.timeout = getintfield_default(L, 1, "timeout", 3) * 1000;
- // post_data: if table, post form data, otherwise raw data
+ lua_getfield(L, 1, "method");
+ if (lua_isstring(L, -1)) {
+ std::string mth = getstringfield_default(L, 1, "method", "");
+ if (mth == "GET")
+ req.method = HTTP_GET;
+ else if (mth == "POST")
+ req.method = HTTP_POST;
+ else if (mth == "PUT")
+ req.method = HTTP_PUT;
+ else if (mth == "DELETE")
+ req.method = HTTP_DELETE;
+ }
+ lua_pop(L, 1);
+
+ // post_data: if table, post form data, otherwise raw data DEPRECATED use data and method instead
lua_getfield(L, 1, "post_data");
+ if (lua_isnil(L, 2)) {
+ lua_pop(L, 1);
+ lua_getfield(L, 1, "data");
+ }
+ else {
+ req.method = HTTP_POST;
+ }
+
if (lua_istable(L, 2)) {
lua_pushnil(L);
while (lua_next(L, 2) != 0) {
- req.post_fields[readParam<std::string>(L, -2)] = readParam<std::string>(L, -1);
+ req.fields[readParam<std::string>(L, -2)] = readParam<std::string>(L, -1);
lua_pop(L, 1);
}
} else if (lua_isstring(L, 2)) {
- req.post_data = readParam<std::string>(L, 2);
+ req.raw_data = readParam<std::string>(L, 2);
}
+
lua_pop(L, 1);
lua_getfield(L, 1, "extra_headers");
diff --git a/src/script/lua_api/l_http.h b/src/script/lua_api/l_http.h
index de6e51b37..c3a2a5276 100644
--- a/src/script/lua_api/l_http.h
+++ b/src/script/lua_api/l_http.h
@@ -32,10 +32,10 @@ private:
static void read_http_fetch_request(lua_State *L, HTTPFetchRequest &req);
static void push_http_fetch_result(lua_State *L, HTTPFetchResult &res, bool completed = true);
- // http_fetch_sync({url=, timeout=, post_data=})
+ // http_fetch_sync({url=, timeout=, data=})
static int l_http_fetch_sync(lua_State *L);
- // http_fetch_async({url=, timeout=, post_data=})
+ // http_fetch_async({url=, timeout=, data=})
static int l_http_fetch_async(lua_State *L);
// http_fetch_async_get(handle)
diff --git a/src/script/lua_api/l_internal.h b/src/script/lua_api/l_internal.h
index a86eeaf79..672e535ca 100644
--- a/src/script/lua_api/l_internal.h
+++ b/src/script/lua_api/l_internal.h
@@ -29,7 +29,16 @@ 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 luamethod_aliased(class, name, alias) {#name, class::l_##name}, {#alias, class::l_##name}
+
+#define luamethod_dep(class, good, bad) \
+ {#bad, [](lua_State *L) -> int { \
+ return l_deprecated_function(L, #good, #bad, &class::l_##good); \
+ }}
+
+#define luamethod_aliased(class, good, bad) \
+ luamethod(class, good), \
+ luamethod_dep(class, good, bad)
+
#define API_FCT(name) registerFunction(L, #name, l_##name, top)
// For future use
diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp
index e41b5cb41..434d0a76c 100644
--- a/src/script/lua_api/l_inventory.cpp
+++ b/src/script/lua_api/l_inventory.cpp
@@ -280,6 +280,7 @@ int InvRef::l_set_lists(lua_State *L)
Server *server = getServer(L);
lua_pushnil(L);
+ luaL_checktype(L, 2, LUA_TTABLE);
while (lua_next(L, 2)) {
const char *listname = lua_tostring(L, -2);
read_inventory_list(L, -1, tempInv, listname, server);
diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp
index d67cab76f..9e0da4034 100644
--- a/src/script/lua_api/l_item.cpp
+++ b/src/script/lua_api/l_item.cpp
@@ -193,6 +193,16 @@ int LuaItemStack::l_get_description(lua_State *L)
return 1;
}
+// get_short_description(self)
+int LuaItemStack::l_get_short_description(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ LuaItemStack *o = checkobject(L, 1);
+ std::string desc = o->m_stack.getShortDescription(getGameDef(L)->idef());
+ lua_pushstring(L, desc.c_str());
+ return 1;
+}
+
// clear(self) -> true
int LuaItemStack::l_clear(lua_State *L)
{
@@ -493,6 +503,7 @@ const luaL_Reg LuaItemStack::methods[] = {
luamethod(LuaItemStack, get_metadata),
luamethod(LuaItemStack, set_metadata),
luamethod(LuaItemStack, get_description),
+ luamethod(LuaItemStack, get_short_description),
luamethod(LuaItemStack, clear),
luamethod(LuaItemStack, replace),
luamethod(LuaItemStack, to_string),
@@ -559,7 +570,8 @@ int ModApiItemMod::l_register_item_raw(lua_State *L)
// Read the node definition (content features) and register it
if (def.type == ITEM_NODE) {
- ContentFeatures f = read_content_features(L, table);
+ ContentFeatures f;
+ read_content_features(L, f, table);
// when a mod reregisters ignore, only texture changes and such should
// be done
if (f.name == "ignore")
diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h
index 98744c071..16878c101 100644
--- a/src/script/lua_api/l_item.h
+++ b/src/script/lua_api/l_item.h
@@ -72,6 +72,9 @@ private:
// get_description(self)
static int l_get_description(lua_State *L);
+ // get_short_description(self)
+ static int l_get_short_description(lua_State *L);
+
// clear(self) -> true
static int l_clear(lua_State *L);
diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp
index 851ede535..33fa27c8b 100644
--- a/src/script/lua_api/l_localplayer.cpp
+++ b/src/script/lua_api/l_localplayer.cpp
@@ -231,8 +231,8 @@ int LuaLocalPlayer::l_get_control(lua_State *L)
set("aux1", c.aux1);
set("sneak", c.sneak);
set("zoom", c.zoom);
- set("LMB", c.LMB);
- set("RMB", c.RMB);
+ set("dig", c.dig);
+ set("place", c.place);
return 1;
}
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index f32c477c2..ba7f708a4 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "porting.h"
#include "filesys.h"
#include "convert_json.h"
-#include "content/packages.h"
#include "content/content.h"
#include "content/subgames.h"
#include "serverlist.h"
@@ -276,207 +275,6 @@ int ModApiMainMenu::l_get_worlds(lua_State *L)
}
/******************************************************************************/
-int ModApiMainMenu::l_get_favorites(lua_State *L)
-{
- std::string listtype = "local";
-
- if (!lua_isnone(L, 1)) {
- listtype = luaL_checkstring(L, 1);
- }
-
- std::vector<ServerListSpec> servers;
-
- if(listtype == "online") {
- servers = ServerList::getOnline();
- } else {
- servers = ServerList::getLocal();
- }
-
- lua_newtable(L);
- int top = lua_gettop(L);
- unsigned int index = 1;
-
- for (const Json::Value &server : servers) {
-
- lua_pushnumber(L, index);
-
- lua_newtable(L);
- int top_lvl2 = lua_gettop(L);
-
- if (!server["clients"].asString().empty()) {
- std::string clients_raw = server["clients"].asString();
- char* endptr = 0;
- int numbervalue = strtol(clients_raw.c_str(), &endptr,10);
-
- if ((!clients_raw.empty()) && (*endptr == 0)) {
- lua_pushstring(L, "clients");
- lua_pushnumber(L, numbervalue);
- lua_settable(L, top_lvl2);
- }
- }
-
- if (!server["clients_max"].asString().empty()) {
-
- std::string clients_max_raw = server["clients_max"].asString();
- char* endptr = 0;
- int numbervalue = strtol(clients_max_raw.c_str(), &endptr,10);
-
- if ((!clients_max_raw.empty()) && (*endptr == 0)) {
- lua_pushstring(L, "clients_max");
- lua_pushnumber(L, numbervalue);
- lua_settable(L, top_lvl2);
- }
- }
-
- if (!server["version"].asString().empty()) {
- lua_pushstring(L, "version");
- std::string topush = server["version"].asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["proto_min"].asString().empty()) {
- lua_pushstring(L, "proto_min");
- lua_pushinteger(L, server["proto_min"].asInt());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["proto_max"].asString().empty()) {
- lua_pushstring(L, "proto_max");
- lua_pushinteger(L, server["proto_max"].asInt());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["password"].asString().empty()) {
- lua_pushstring(L, "password");
- lua_pushboolean(L, server["password"].asBool());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["creative"].asString().empty()) {
- lua_pushstring(L, "creative");
- lua_pushboolean(L, server["creative"].asBool());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["damage"].asString().empty()) {
- lua_pushstring(L, "damage");
- lua_pushboolean(L, server["damage"].asBool());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["pvp"].asString().empty()) {
- lua_pushstring(L, "pvp");
- lua_pushboolean(L, server["pvp"].asBool());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["description"].asString().empty()) {
- lua_pushstring(L, "description");
- std::string topush = server["description"].asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["name"].asString().empty()) {
- lua_pushstring(L, "name");
- std::string topush = server["name"].asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["address"].asString().empty()) {
- lua_pushstring(L, "address");
- std::string topush = server["address"].asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl2);
- }
-
- if (!server["port"].asString().empty()) {
- lua_pushstring(L, "port");
- std::string topush = server["port"].asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl2);
- }
-
- if (server.isMember("ping")) {
- float ping = server["ping"].asFloat();
- lua_pushstring(L, "ping");
- lua_pushnumber(L, ping);
- lua_settable(L, top_lvl2);
- }
-
- if (server["clients_list"].isArray()) {
- unsigned int index_lvl2 = 1;
- lua_pushstring(L, "clients_list");
- lua_newtable(L);
- int top_lvl3 = lua_gettop(L);
- for (const Json::Value &client : server["clients_list"]) {
- lua_pushnumber(L, index_lvl2);
- std::string topush = client.asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl3);
- index_lvl2++;
- }
- lua_settable(L, top_lvl2);
- }
-
- if (server["mods"].isArray()) {
- unsigned int index_lvl2 = 1;
- lua_pushstring(L, "mods");
- lua_newtable(L);
- int top_lvl3 = lua_gettop(L);
- for (const Json::Value &mod : server["mods"]) {
-
- lua_pushnumber(L, index_lvl2);
- std::string topush = mod.asString();
- lua_pushstring(L, topush.c_str());
- lua_settable(L, top_lvl3);
- index_lvl2++;
- }
- lua_settable(L, top_lvl2);
- }
-
- lua_settable(L, top);
- index++;
- }
- return 1;
-}
-
-/******************************************************************************/
-int ModApiMainMenu::l_delete_favorite(lua_State *L)
-{
- std::vector<ServerListSpec> servers;
-
- std::string listtype = "local";
-
- if (!lua_isnone(L,2)) {
- listtype = luaL_checkstring(L,2);
- }
-
- if ((listtype != "local") &&
- (listtype != "online"))
- return 0;
-
-
- if(listtype == "online") {
- servers = ServerList::getOnline();
- } else {
- servers = ServerList::getLocal();
- }
-
- int fav_idx = luaL_checkinteger(L,1) -1;
-
- if ((fav_idx >= 0) &&
- (fav_idx < (int) servers.size())) {
-
- ServerList::deleteEntry(servers[fav_idx]);
- }
-
- return 0;
-}
-
-/******************************************************************************/
int ModApiMainMenu::l_get_games(lua_State *L)
{
std::vector<SubgameSpec> games = getAvailableGames();
@@ -618,7 +416,7 @@ int ModApiMainMenu::l_create_world(lua_State *L)
std::string path = porting::path_user + DIR_DELIM
"worlds" + DIR_DELIM
- + name;
+ + sanitizeDirName(name, "world_");
std::vector<SubgameSpec> games = getAvailableGames();
@@ -626,10 +424,11 @@ int ModApiMainMenu::l_create_world(lua_State *L)
(gameidx < (int) games.size())) {
// Create world if it doesn't exist
- if (!loadGameConfAndInitWorld(path, games[gameidx])) {
- lua_pushstring(L, "Failed to initialize world");
- } else {
+ try {
+ loadGameConfAndInitWorld(path, name, games[gameidx], true);
lua_pushnil(L);
+ } catch (const BaseException &e) {
+ lua_pushstring(L, (std::string("Failed to initialize world: ") + e.what()).c_str());
}
} else {
lua_pushstring(L, "Invalid game index");
@@ -687,6 +486,14 @@ int ModApiMainMenu::l_get_mapgen_names(lua_State *L)
/******************************************************************************/
+int ModApiMainMenu::l_get_user_path(lua_State *L)
+{
+ std::string path = fs::RemoveRelativePathComponents(porting::path_user);
+ lua_pushstring(L, path.c_str());
+ return 1;
+}
+
+/******************************************************************************/
int ModApiMainMenu::l_get_modpath(lua_State *L)
{
std::string modpath = fs::RemoveRelativePathComponents(
@@ -722,6 +529,7 @@ int ModApiMainMenu::l_get_texturepath(lua_State *L)
return 1;
}
+/******************************************************************************/
int ModApiMainMenu::l_get_texturepath_share(lua_State *L)
{
std::string gamepath = fs::RemoveRelativePathComponents(
@@ -730,6 +538,7 @@ int ModApiMainMenu::l_get_texturepath_share(lua_State *L)
return 1;
}
+/******************************************************************************/
int ModApiMainMenu::l_get_cache_path(lua_State *L)
{
lua_pushstring(L, fs::RemoveRelativePathComponents(porting::path_cache).c_str());
@@ -737,6 +546,13 @@ int ModApiMainMenu::l_get_cache_path(lua_State *L)
}
/******************************************************************************/
+int ModApiMainMenu::l_get_temp_path(lua_State *L)
+{
+ lua_pushstring(L, fs::TempPath().c_str());
+ return 1;
+}
+
+/******************************************************************************/
int ModApiMainMenu::l_create_dir(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
@@ -796,6 +612,15 @@ int ModApiMainMenu::l_copy_dir(lua_State *L)
}
/******************************************************************************/
+int ModApiMainMenu::l_is_dir(lua_State *L)
+{
+ const char *path = luaL_checkstring(L, 1);
+
+ lua_pushboolean(L, fs::IsDir(path));
+ return 1;
+}
+
+/******************************************************************************/
int ModApiMainMenu::l_extract_zip(lua_State *L)
{
const char *zipfile = luaL_checkstring(L, 1);
@@ -1067,7 +892,15 @@ int ModApiMainMenu::l_get_max_supp_proto(lua_State *L)
int ModApiMainMenu::l_open_url(lua_State *L)
{
std::string url = luaL_checkstring(L, 1);
- lua_pushboolean(L, porting::openURL(url));
+ lua_pushboolean(L, porting::open_url(url));
+ return 1;
+}
+
+/******************************************************************************/
+int ModApiMainMenu::l_open_dir(lua_State *L)
+{
+ std::string path = luaL_checkstring(L, 1);
+ lua_pushboolean(L, porting::open_directory(path));
return 1;
}
@@ -1105,23 +938,24 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
API_FCT(get_content_info);
API_FCT(start);
API_FCT(close);
- API_FCT(get_favorites);
API_FCT(show_keys_menu);
API_FCT(create_world);
API_FCT(delete_world);
- API_FCT(delete_favorite);
API_FCT(set_background);
API_FCT(set_topleft_text);
API_FCT(get_mapgen_names);
+ API_FCT(get_user_path);
API_FCT(get_modpath);
API_FCT(get_clientmodpath);
API_FCT(get_gamepath);
API_FCT(get_texturepath);
API_FCT(get_texturepath_share);
API_FCT(get_cache_path);
+ API_FCT(get_temp_path);
API_FCT(create_dir);
API_FCT(delete_dir);
API_FCT(copy_dir);
+ API_FCT(is_dir);
API_FCT(extract_zip);
API_FCT(may_modify_path);
API_FCT(get_mainmenu_path);
@@ -1134,6 +968,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
API_FCT(get_min_supp_proto);
API_FCT(get_max_supp_proto);
API_FCT(open_url);
+ API_FCT(open_dir);
API_FCT(do_async_callback);
}
@@ -1142,19 +977,23 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top)
{
API_FCT(get_worlds);
API_FCT(get_games);
- API_FCT(get_favorites);
API_FCT(get_mapgen_names);
+ API_FCT(get_user_path);
API_FCT(get_modpath);
API_FCT(get_clientmodpath);
API_FCT(get_gamepath);
API_FCT(get_texturepath);
API_FCT(get_texturepath_share);
API_FCT(get_cache_path);
+ API_FCT(get_temp_path);
API_FCT(create_dir);
API_FCT(delete_dir);
API_FCT(copy_dir);
+ API_FCT(is_dir);
//API_FCT(extract_zip); //TODO remove dependency to GuiEngine
API_FCT(may_modify_path);
API_FCT(download_file);
+ API_FCT(get_min_supp_proto);
+ API_FCT(get_max_supp_proto);
//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 5a16b3bfe..49ce7c251 100644
--- a/src/script/lua_api/l_mainmenu.h
+++ b/src/script/lua_api/l_mainmenu.h
@@ -74,10 +74,6 @@ private:
static int l_get_mapgen_names(lua_State *L);
- static int l_get_favorites(lua_State *L);
-
- static int l_delete_favorite(lua_State *L);
-
static int l_gettext(lua_State *L);
//packages
@@ -112,6 +108,8 @@ private:
static int l_get_mainmenu_path(lua_State *L);
+ static int l_get_user_path(lua_State *L);
+
static int l_get_modpath(lua_State *L);
static int l_get_clientmodpath(lua_State *L);
@@ -124,12 +122,16 @@ private:
static int l_get_cache_path(lua_State *L);
+ static int l_get_temp_path(lua_State *L);
+
static int l_create_dir(lua_State *L);
static int l_delete_dir(lua_State *L);
static int l_copy_dir(lua_State *L);
+ static int l_is_dir(lua_State *L);
+
static int l_extract_zip(lua_State *L);
static int l_may_modify_path(lua_State *L);
@@ -148,6 +150,8 @@ private:
// other
static int l_open_url(lua_State *L);
+ static int l_open_dir(lua_State *L);
+
// async
static int l_do_async_callback(lua_State *L);
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 834938e56..12a497b1e 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -873,9 +873,6 @@ int ModApiMapgen::l_set_mapgen_params(lua_State *L)
if (lua_isnumber(L, -1))
settingsmgr->setMapSetting("chunksize", readParam<std::string>(L, -1), true);
- warn_if_field_exists(L, 1, "flagmask",
- "Obsolete: flags field now includes unset flags.");
-
lua_getfield(L, 1, "flags");
if (lua_isstring(L, -1))
settingsmgr->setMapSetting("mg_flags", readParam<std::string>(L, -1), true);
@@ -985,7 +982,7 @@ int ModApiMapgen::l_set_noiseparams(lua_State *L)
bool set_default = !lua_isboolean(L, 3) || readParam<bool>(L, 3);
- g_settings->setNoiseParams(name, np, set_default);
+ Settings::getLayer(set_default ? SL_DEFAULTS : SL_GLOBAL)->setNoiseParams(name, np);
return 0;
}
@@ -1338,11 +1335,9 @@ int ModApiMapgen::l_register_ore(lua_State *L)
lua_getfield(L, index, "noise_params");
if (read_noiseparams(L, -1, &ore->np)) {
ore->flags |= OREFLAG_USE_NOISE;
- } else if (ore->NEEDS_NOISE) {
- errorstream << "register_ore: specified ore type requires valid "
- "'noise_params' parameter" << std::endl;
- delete ore;
- return 0;
+ } else if (ore->needs_noise) {
+ log_deprecated(L,
+ "register_ore: ore type requires 'noise_params' but it is not specified, falling back to defaults");
}
lua_pop(L, 1);
diff --git a/src/script/lua_api/l_metadata.cpp b/src/script/lua_api/l_metadata.cpp
index 61a25a761..21002e6a7 100644
--- a/src/script/lua_api/l_metadata.cpp
+++ b/src/script/lua_api/l_metadata.cpp
@@ -153,9 +153,7 @@ int MetaDataRef::l_set_int(lua_State *L)
MetaDataRef *ref = checkobject(L, 1);
std::string name = luaL_checkstring(L, 2);
int a = luaL_checkint(L, 3);
- std::string str;
- if (a != 0)
- str = itos(a);
+ std::string str = itos(a);
Metadata *meta = ref->getmeta(true);
if (meta == NULL || str == meta->getString(name))
@@ -193,9 +191,7 @@ int MetaDataRef::l_set_float(lua_State *L)
MetaDataRef *ref = checkobject(L, 1);
std::string name = luaL_checkstring(L, 2);
float a = readParam<float>(L, 3);
- std::string str;
- if (a != 0)
- str = ftos(a);
+ std::string str = ftos(a);
Metadata *meta = ref->getmeta(true);
if (meta == NULL || str == meta->getString(name))
diff --git a/src/script/lua_api/l_minimap.cpp b/src/script/lua_api/l_minimap.cpp
index 5fba76eb8..3bbb6e5e3 100644
--- a/src/script/lua_api/l_minimap.cpp
+++ b/src/script/lua_api/l_minimap.cpp
@@ -89,7 +89,7 @@ int LuaMinimap::l_get_mode(lua_State *L)
LuaMinimap *ref = checkobject(L, 1);
Minimap *m = getobject(ref);
- lua_pushinteger(L, m->getMinimapMode());
+ lua_pushinteger(L, m->getModeIndex());
return 1;
}
@@ -98,13 +98,11 @@ 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) {
+ u32 mode = lua_tointeger(L, 2);
+ if (mode >= m->getMaxModeIndex())
return 0;
- }
- m->setMinimapMode((MinimapMode) mode);
+ m->setModeIndex(mode);
return 1;
}
@@ -140,8 +138,11 @@ int LuaMinimap::l_show(lua_State *L)
LuaMinimap *ref = checkobject(L, 1);
Minimap *m = getobject(ref);
- if (m->getMinimapMode() == MINIMAP_MODE_OFF)
- m->setMinimapMode(MINIMAP_MODE_SURFACEx1);
+ // This is not very adapted to new minimap mode management. Btw, tried
+ // to do something compatible.
+
+ if (m->getModeIndex() == 0 && m->getMaxModeIndex() > 0)
+ m->setModeIndex(1);
client->showMinimap(true);
return 1;
@@ -155,8 +156,11 @@ int LuaMinimap::l_hide(lua_State *L)
LuaMinimap *ref = checkobject(L, 1);
Minimap *m = getobject(ref);
- if (m->getMinimapMode() != MINIMAP_MODE_OFF)
- m->setMinimapMode(MINIMAP_MODE_OFF);
+ // This is not very adapted to new minimap mode management. Btw, tried
+ // to do something compatible.
+
+ if (m->getModeIndex() != 0)
+ m->setModeIndex(0);
client->showMinimap(false);
return 1;
diff --git a/src/script/lua_api/l_noise.cpp b/src/script/lua_api/l_noise.cpp
index 9aeb15709..e0861126a 100644
--- a/src/script/lua_api/l_noise.cpp
+++ b/src/script/lua_api/l_noise.cpp
@@ -122,7 +122,6 @@ void LuaPerlinNoise::Register(lua_State *L)
lua_pop(L, 1);
- markAliasDeprecated(methods);
luaL_openlib(L, 0, methods, 0);
lua_pop(L, 1);
@@ -381,7 +380,6 @@ void LuaPerlinNoiseMap::Register(lua_State *L)
lua_pop(L, 1);
- markAliasDeprecated(methods);
luaL_openlib(L, 0, methods, 0);
lua_pop(L, 1);
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index e7394133a..8ae99b929 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -44,43 +44,44 @@ ObjectRef* ObjectRef::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);
+ if (ud == nullptr)
+ luaL_typerror(L, narg, className);
return *(ObjectRef**)ud; // unbox pointer
}
ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
{
- ServerActiveObject *co = ref->m_object;
- if (co && co->isGone())
- return NULL;
- return co;
+ ServerActiveObject *sao = ref->m_object;
+ if (sao && sao->isGone())
+ return nullptr;
+ return sao;
}
LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
{
- ServerActiveObject *obj = getobject(ref);
- if (obj == NULL)
- return NULL;
- if (obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
- return NULL;
- return (LuaEntitySAO*)obj;
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return nullptr;
+ if (sao->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
+ return nullptr;
+ return (LuaEntitySAO*)sao;
}
PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
{
- ServerActiveObject *obj = getobject(ref);
- if (obj == NULL)
- return NULL;
- if (obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
- return NULL;
- return (PlayerSAO*)obj;
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return nullptr;
+ if (sao->getType() != ACTIVEOBJECT_TYPE_PLAYER)
+ return nullptr;
+ return (PlayerSAO*)sao;
}
RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
{
PlayerSAO *playersao = getplayersao(ref);
- if (playersao == NULL)
- return NULL;
+ if (playersao == nullptr)
+ return nullptr;
return playersao->getPlayer();
}
@@ -88,9 +89,8 @@ RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
// garbage collector
int ObjectRef::gc_object(lua_State *L) {
- ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
- //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
- delete o;
+ ObjectRef *obj = *(ObjectRef **)(lua_touserdata(L, 1));
+ delete obj;
return 0;
}
@@ -100,29 +100,30 @@ int ObjectRef::l_remove(lua_State *L)
GET_ENV_PTR;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
+ if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER)
return 0;
- co->clearChildAttachments();
- co->clearParentAttachment();
+ sao->clearChildAttachments();
+ sao->clearParentAttachment();
- verbosestream << "ObjectRef::l_remove(): id=" << co->getId() << std::endl;
- co->m_pending_removal = true;
+ verbosestream << "ObjectRef::l_remove(): id=" << sao->getId() << std::endl;
+ sao->markForRemoval();
return 0;
}
// get_pos(self)
-// returns: {x=num, y=num, z=num}
int ObjectRef::l_get_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- push_v3f(L, co->getBasePosition() / BS);
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ push_v3f(L, sao->getBasePosition() / BS);
return 1;
}
@@ -131,28 +132,29 @@ int ObjectRef::l_set_pos(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // pos
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
v3f pos = checkFloatPos(L, 2);
- // Do it
- co->setPos(pos);
+
+ sao->setPos(pos);
return 0;
}
-// move_to(self, pos, continuous=false)
+// move_to(self, pos, continuous)
int ObjectRef::l_move_to(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // pos
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
v3f pos = checkFloatPos(L, 2);
- // continuous
bool continuous = readParam<bool>(L, 3);
- // Do it
- co->moveTo(pos, continuous);
+
+ sao->moveTo(pos, continuous);
return 0;
}
@@ -162,32 +164,26 @@ int ObjectRef::l_punch(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ObjectRef *puncher_ref = checkobject(L, 2);
- ServerActiveObject *co = getobject(ref);
+ ServerActiveObject *sao = getobject(ref);
ServerActiveObject *puncher = getobject(puncher_ref);
- if (!co || !puncher)
+ if (sao == nullptr || puncher == nullptr)
return 0;
- v3f dir;
- if (lua_type(L, 5) != LUA_TTABLE)
- dir = co->getBasePosition() - puncher->getBasePosition();
- else
- dir = read_v3f(L, 5);
- float time_from_last_punch = 1000000;
- if (lua_isnumber(L, 3))
- time_from_last_punch = lua_tonumber(L, 3);
+
+ float time_from_last_punch = readParam<float>(L, 3, 1000000.0f);
ToolCapabilities toolcap = read_tool_capabilities(L, 4);
- dir.normalize();
+ v3f dir = readParam<v3f>(L, 5, sao->getBasePosition() - puncher->getBasePosition());
- u16 src_original_hp = co->getHP();
+ dir.normalize();
+ u16 src_original_hp = sao->getHP();
u16 dst_origin_hp = puncher->getHP();
- // Do it
- u16 wear = co->punch(dir, &toolcap, puncher, time_from_last_punch);
+ u16 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch);
lua_pushnumber(L, wear);
// If the punched is a player, and its HP changed
- if (src_original_hp != co->getHP() &&
- co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
- getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co,
+ if (src_original_hp != sao->getHP() &&
+ sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)sao,
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
}
@@ -195,45 +191,38 @@ int ObjectRef::l_punch(lua_State *L)
if (dst_origin_hp != puncher->getHP() &&
puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher,
- PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, co));
+ PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, sao));
}
return 1;
}
-// right_click(self, clicker); clicker = an another ObjectRef
+// right_click(self, clicker)
int ObjectRef::l_right_click(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
ObjectRef *ref2 = checkobject(L, 2);
- ServerActiveObject *co = getobject(ref);
- ServerActiveObject *co2 = getobject(ref2);
- if (co == NULL) return 0;
- if (co2 == NULL) return 0;
- // Do it
- co->rightClick(co2);
+ ServerActiveObject *sao = getobject(ref);
+ ServerActiveObject *sao2 = getobject(ref2);
+ if (sao == nullptr || sao2 == nullptr)
+ return 0;
+
+ sao->rightClick(sao2);
return 0;
}
-// set_hp(self, hp)
-// hp = number of hitpoints (2 * number of hearts)
-// returns: nil
+// set_hp(self, hp, reason)
int ObjectRef::l_set_hp(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
-
- // Get Object
ObjectRef *ref = checkobject(L, 1);
- luaL_checknumber(L, 2);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- // Get HP
- int hp = lua_tonumber(L, 2);
-
- // Get Reason
+ int hp = readParam<float>(L, 2);
PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
+
reason.from_mod = true;
if (lua_istable(L, 3)) {
lua_pushvalue(L, 3);
@@ -248,35 +237,28 @@ int ObjectRef::l_set_hp(lua_State *L)
reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX);
}
- // Do it
- co->setHP(hp, reason);
- if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
- getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason);
-
+ sao->setHP(hp, reason);
+ if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER)
+ getServer(L)->SendPlayerHPOrDie((PlayerSAO *)sao, reason);
if (reason.hasLuaReference())
luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference);
-
- // Return
return 0;
}
// get_hp(self)
-// returns: number of hitpoints (2 * number of hearts)
-// 0 if not applicable to this type of object
int ObjectRef::l_get_hp(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) {
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr) {
// Default hp is 1
lua_pushnumber(L, 1);
return 1;
}
- int hp = co->getHP();
- /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
- <<" hp="<<hp<<std::endl;*/
- // Return
+
+ int hp = sao->getHP();
+
lua_pushnumber(L, hp);
return 1;
}
@@ -286,11 +268,12 @@ int ObjectRef::l_get_inventory(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // Do it
- InventoryLocation loc = co->getInventoryLocation();
- if (getServerInventoryMgr(L)->getInventory(loc) != NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ InventoryLocation loc = sao->getInventoryLocation();
+ if (getServerInventoryMgr(L)->getInventory(loc) != nullptr)
InvRef::create(L, loc);
else
lua_pushnil(L); // An object may have no inventory (nil)
@@ -302,11 +285,11 @@ int ObjectRef::l_get_wield_list(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (!co)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- lua_pushstring(L, co->getWieldList().c_str());
+ lua_pushstring(L, sao->getWieldList().c_str());
return 1;
}
@@ -315,11 +298,11 @@ int ObjectRef::l_get_wield_index(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (!co)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- lua_pushinteger(L, co->getWieldIndex() + 1);
+ lua_pushinteger(L, sao->getWieldIndex() + 1);
return 1;
}
@@ -328,31 +311,33 @@ int ObjectRef::l_get_wielded_item(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (!co) {
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr) {
// Empty ItemStack
LuaItemStack::create(L, ItemStack());
return 1;
}
ItemStack selected_item;
- co->getWieldedItem(&selected_item, nullptr);
+ sao->getWieldedItem(&selected_item, nullptr);
LuaItemStack::create(L, selected_item);
return 1;
}
-// set_wielded_item(self, itemstack or itemstring or table or nil)
+// set_wielded_item(self, item)
int ObjectRef::l_set_wielded_item(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // Do it
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
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, true);
+
+ bool success = sao->setWieldedItem(item);
+ if (success && sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+ getServer(L)->SendInventory((PlayerSAO *)sao, true);
}
lua_pushboolean(L, success);
return 1;
@@ -363,12 +348,23 @@ int ObjectRef::l_set_armor_groups(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // Do it
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
ItemGroupList groups;
+
read_groups(L, 2, groups);
- co->setArmorGroups(groups);
+ if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+ if (!g_settings->getBool("enable_damage") && !itemgroup_get(groups, "immortal")) {
+ warningstream << "Mod tried to enable damage for a player, but it's "
+ "disabled globally. Ignoring." << std::endl;
+ infostream << script_get_backtrace(L) << std::endl;
+ groups["immortal"] = 1;
+ }
+ }
+
+ sao->setArmorGroups(groups);
return 0;
}
@@ -377,77 +373,11 @@ int ObjectRef::l_get_armor_groups(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- // Do it
- push_groups(L, co->getArmorGroups());
- return 1;
-}
-
-// set_physics_override(self, physics_override_speed, physics_override_jump,
-// physics_override_gravity, sneak, sneak_glitch, new_move)
-int ObjectRef::l_set_physics_override(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- ObjectRef *ref = checkobject(L, 1);
- PlayerSAO *co = (PlayerSAO *) getobject(ref);
- 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_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
- if (!lua_isnil(L, 2)) {
- co->m_physics_override_speed = lua_tonumber(L, 2);
- co->m_physics_override_sent = false;
- }
- if (!lua_isnil(L, 3)) {
- co->m_physics_override_jump = lua_tonumber(L, 3);
- co->m_physics_override_sent = false;
- }
- if (!lua_isnil(L, 4)) {
- co->m_physics_override_gravity = lua_tonumber(L, 4);
- co->m_physics_override_sent = false;
- }
- }
- return 0;
-}
-// get_physics_override(self)
-int ObjectRef::l_get_physics_override(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- ObjectRef *ref = checkobject(L, 1);
- PlayerSAO *co = (PlayerSAO *)getobject(ref);
- if (co == NULL)
- return 0;
- // Do it
- lua_newtable(L);
- lua_pushnumber(L, co->m_physics_override_speed);
- lua_setfield(L, -2, "speed");
- lua_pushnumber(L, co->m_physics_override_jump);
- lua_setfield(L, -2, "jump");
- lua_pushnumber(L, co->m_physics_override_gravity);
- lua_setfield(L, -2, "gravity");
- lua_pushboolean(L, co->m_physics_override_sneak);
- 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");
+ push_groups(L, sao->getArmorGroups());
return 1;
}
@@ -456,22 +386,16 @@ int ObjectRef::l_set_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // Do it
- v2f frames = v2f(1, 1);
- if (!lua_isnil(L, 2))
- frames = readParam<v2f>(L, 2);
- float frame_speed = 15;
- if (!lua_isnil(L, 3))
- frame_speed = lua_tonumber(L, 3);
- float frame_blend = 0;
- if (!lua_isnil(L, 4))
- frame_blend = lua_tonumber(L, 4);
- bool frame_loop = true;
- if (lua_isboolean(L, 5))
- frame_loop = readParam<bool>(L, 5);
- co->setAnimation(frames, frame_speed, frame_blend, frame_loop);
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ v2f frame_range = readParam<v2f>(L, 2, v2f(1, 1));
+ float frame_speed = readParam<float>(L, 3, 15.0f);
+ float frame_blend = readParam<float>(L, 4, 0.0f);
+ bool frame_loop = readParam<bool>(L, 5, true);
+
+ sao->setAnimation(frame_range, frame_speed, frame_blend, frame_loop);
return 0;
}
@@ -480,16 +404,16 @@ int ObjectRef::l_get_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- // Do it
- v2f frames = v2f(1,1);
+
+ v2f frames = v2f(1, 1);
float frame_speed = 15;
float frame_blend = 0;
bool frame_loop = true;
- co->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
+ sao->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
push_v2f(L, frames);
lua_pushnumber(L, frame_speed);
lua_pushnumber(L, frame_blend);
@@ -497,23 +421,21 @@ int ObjectRef::l_get_animation(lua_State *L)
return 4;
}
-// set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed)
+// set_local_animation(self, idle, walk, dig, walk_while_dig, frame_speed)
int ObjectRef::l_set_local_animation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- // Do it
+
v2s32 frames[4];
for (int i=0;i<4;i++) {
if (!lua_isnil(L, 2+1))
frames[i] = read_v2s32(L, 2+i);
}
- float frame_speed = 30;
- if (!lua_isnil(L, 6))
- frame_speed = lua_tonumber(L, 6);
+ float frame_speed = readParam<float>(L, 6, 30.0f);
getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed);
lua_pushboolean(L, true);
@@ -526,7 +448,7 @@ int ObjectRef::l_get_local_animation(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
v2s32 frames[4];
@@ -541,27 +463,22 @@ int ObjectRef::l_get_local_animation(lua_State *L)
return 5;
}
-// set_eye_offset(self, v3f first pv, v3f third pv)
+// set_eye_offset(self, firstperson, thirdperson)
int ObjectRef::l_set_eye_offset(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- // Do it
- v3f offset_first = v3f(0, 0, 0);
- v3f offset_third = v3f(0, 0, 0);
- if (!lua_isnil(L, 2))
- offset_first = read_v3f(L, 2);
- if (!lua_isnil(L, 3))
- offset_third = read_v3f(L, 3);
+ v3f offset_first = readParam<v3f>(L, 2, v3f(0, 0, 0));
+ v3f offset_third = readParam<v3f>(L, 3, v3f(0, 0, 0));
// Prevent abuse of offset values (keep player always visible)
offset_third.X = rangelim(offset_third.X,-10,10);
offset_third.Z = rangelim(offset_third.Z,-5,5);
- /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */
+ /* TODO: if possible: improve the camera collision detection to allow Y <= -1.5) */
offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third);
@@ -575,9 +492,9 @@ int ObjectRef::l_get_eye_offset(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- // Do it
+
push_v3f(L, player->eye_offset_first);
push_v3f(L, player->eye_offset_third);
return 2;
@@ -588,14 +505,14 @@ int ObjectRef::l_send_mapblock(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
-
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
- v3s16 p = read_v3s16(L, 2);
+
+ v3s16 pos = read_v3s16(L, 2);
session_t peer_id = player->getPeerId();
- bool r = getServer(L)->SendBlock(peer_id, p);
+ bool r = getServer(L)->SendBlock(peer_id, pos);
lua_pushboolean(L, r);
return 1;
@@ -606,14 +523,13 @@ int ObjectRef::l_set_animation_frame_speed(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- // Do it
if (!lua_isnil(L, 2)) {
- float frame_speed = lua_tonumber(L, 2);
- co->setAnimationSpeed(frame_speed);
+ float frame_speed = readParam<float>(L, 2);
+ sao->setAnimationSpeed(frame_speed);
lua_pushboolean(L, true);
} else {
lua_pushboolean(L, false);
@@ -621,24 +537,20 @@ int ObjectRef::l_set_animation_frame_speed(lua_State *L)
return 1;
}
-// set_bone_position(self, std::string bone, v3f position, v3f rotation)
+// set_bone_position(self, bone, position, rotation)
int ObjectRef::l_set_bone_position(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL) return 0;
- // Do it
- std::string bone;
- if (!lua_isnil(L, 2))
- bone = readParam<std::string>(L, 2);
- v3f position = v3f(0, 0, 0);
- if (!lua_isnil(L, 3))
- position = check_v3f(L, 3);
- v3f rotation = v3f(0, 0, 0);
- if (!lua_isnil(L, 4))
- rotation = check_v3f(L, 4);
- co->setBonePosition(bone, position, rotation);
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ std::string bone = readParam<std::string>(L, 2, "");
+ v3f position = readParam<v3f>(L, 3, v3f(0, 0, 0));
+ v3f rotation = readParam<v3f>(L, 4, v3f(0, 0, 0));
+
+ sao->setBonePosition(bone, position, rotation);
return 0;
}
@@ -647,63 +559,53 @@ int ObjectRef::l_get_bone_position(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- // Do it
- std::string bone;
- if (!lua_isnil(L, 2))
- bone = readParam<std::string>(L, 2);
+
+ std::string bone = readParam<std::string>(L, 2, "");
v3f position = v3f(0, 0, 0);
v3f rotation = v3f(0, 0, 0);
- co->getBonePosition(bone, &position, &rotation);
+ sao->getBonePosition(bone, &position, &rotation);
push_v3f(L, position);
push_v3f(L, rotation);
return 2;
}
-// set_attach(self, parent, bone, position, rotation)
+// set_attach(self, parent, bone, position, rotation, force_visible)
int ObjectRef::l_set_attach(lua_State *L)
{
GET_ENV_PTR;
-
ObjectRef *ref = checkobject(L, 1);
ObjectRef *parent_ref = checkobject(L, 2);
- ServerActiveObject *co = getobject(ref);
+ ServerActiveObject *sao = getobject(ref);
ServerActiveObject *parent = getobject(parent_ref);
- if (co == NULL)
- return 0;
-
- if (parent == NULL)
+ if (sao == nullptr || parent == nullptr)
return 0;
-
- if (co == parent)
+ if (sao == parent)
throw LuaError("ObjectRef::set_attach: attaching object to itself is not allowed.");
- // Do it
- int parent_id = 0;
+ int parent_id;
std::string bone;
- v3f position = v3f(0, 0, 0);
- v3f rotation = v3f(0, 0, 0);
- co->getAttachment(&parent_id, &bone, &position, &rotation);
+ v3f position;
+ v3f rotation;
+ bool force_visible;
+
+ sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible);
if (parent_id) {
ServerActiveObject *old_parent = env->getActiveObject(parent_id);
- old_parent->removeAttachmentChild(co->getId());
+ old_parent->removeAttachmentChild(sao->getId());
}
- bone = "";
- if (!lua_isnil(L, 3))
- bone = readParam<std::string>(L, 3);
- position = v3f(0, 0, 0);
- if (!lua_isnil(L, 4))
- position = read_v3f(L, 4);
- rotation = v3f(0, 0, 0);
- if (!lua_isnil(L, 5))
- rotation = read_v3f(L, 5);
- co->setAttachment(parent->getId(), bone, position, rotation);
- parent->addAttachmentChild(co->getId());
+ bone = readParam<std::string>(L, 3, "");
+ position = readParam<v3f>(L, 4, v3f(0, 0, 0));
+ rotation = readParam<v3f>(L, 5, v3f(0, 0, 0));
+ force_visible = readParam<bool>(L, 6, false);
+
+ sao->setAttachment(parent->getId(), bone, position, rotation, force_visible);
+ parent->addAttachmentChild(sao->getId());
return 0;
}
@@ -711,40 +613,61 @@ int ObjectRef::l_set_attach(lua_State *L)
int ObjectRef::l_get_attach(lua_State *L)
{
GET_ENV_PTR;
-
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- // Do it
- int parent_id = 0;
+ int parent_id;
std::string bone;
- v3f position = v3f(0, 0, 0);
- v3f rotation = v3f(0, 0, 0);
- co->getAttachment(&parent_id, &bone, &position, &rotation);
- if (!parent_id)
+ v3f position;
+ v3f rotation;
+ bool force_visible;
+
+ sao->getAttachment(&parent_id, &bone, &position, &rotation, &force_visible);
+ if (parent_id == 0)
return 0;
- ServerActiveObject *parent = env->getActiveObject(parent_id);
+ ServerActiveObject *parent = env->getActiveObject(parent_id);
getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
lua_pushlstring(L, bone.c_str(), bone.size());
push_v3f(L, position);
push_v3f(L, rotation);
- return 4;
+ lua_pushboolean(L, force_visible);
+ return 5;
+}
+
+// get_children(self)
+int ObjectRef::l_get_children(lua_State *L)
+{
+ GET_ENV_PTR;
+ ObjectRef *ref = checkobject(L, 1);
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ const std::unordered_set<int> child_ids = sao->getAttachmentChildIds();
+ int i = 0;
+
+ lua_createtable(L, child_ids.size(), 0);
+ for (const int id : child_ids) {
+ ServerActiveObject *child = env->getActiveObject(id);
+ getScriptApiBase(L)->objectrefGetOrCreate(L, child);
+ lua_rawseti(L, -2, ++i);
+ }
+ return 1;
}
// set_detach(self)
int ObjectRef::l_set_detach(lua_State *L)
{
GET_ENV_PTR;
-
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- co->clearParentAttachment();
+ sao->clearParentAttachment();
return 0;
}
@@ -753,16 +676,16 @@ int ObjectRef::l_set_properties(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (!co)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- ObjectProperties *prop = co->accessObjectProperties();
- if (!prop)
+ ObjectProperties *prop = sao->accessObjectProperties();
+ if (prop == nullptr)
return 0;
- read_object_properties(L, 2, co, prop, getServer(L)->idef());
- co->notifyObjectPropertiesModified();
+ read_object_properties(L, 2, sao, prop, getServer(L)->idef());
+ sao->notifyObjectPropertiesModified();
return 0;
}
@@ -771,12 +694,14 @@ int ObjectRef::l_get_properties(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- ObjectProperties *prop = co->accessObjectProperties();
- if (!prop)
+
+ ObjectProperties *prop = sao->accessObjectProperties();
+ if (prop == nullptr)
return 0;
+
push_object_properties(L, prop);
return 1;
}
@@ -787,7 +712,7 @@ int ObjectRef::l_is_player(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- lua_pushboolean(L, (player != NULL));
+ lua_pushboolean(L, (player != nullptr));
return 1;
}
@@ -796,12 +721,12 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
-
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- ObjectProperties *prop = co->accessObjectProperties();
- if (!prop)
+
+ ObjectProperties *prop = sao->accessObjectProperties();
+ if (prop == nullptr)
return 0;
lua_getfield(L, 2, "color");
@@ -812,10 +737,22 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
}
lua_pop(L, 1);
+ lua_getfield(L, -1, "bgcolor");
+ if (!lua_isnil(L, -1)) {
+ if (lua_toboolean(L, -1)) {
+ video::SColor color;
+ if (read_color(L, -1, &color))
+ prop->nametag_bgcolor = color;
+ } else {
+ prop->nametag_bgcolor = nullopt;
+ }
+ }
+ lua_pop(L, 1);
+
std::string nametag = getstringfield_default(L, 2, "text", "");
prop->nametag = nametag;
- co->notifyObjectPropertiesModified();
+ sao->notifyObjectPropertiesModified();
lua_pushboolean(L, true);
return 1;
}
@@ -825,50 +762,72 @@ int ObjectRef::l_get_nametag_attributes(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- ServerActiveObject *co = getobject(ref);
-
- if (co == NULL)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- ObjectProperties *prop = co->accessObjectProperties();
+
+ ObjectProperties *prop = sao->accessObjectProperties();
if (!prop)
return 0;
- video::SColor color = prop->nametag_color;
-
lua_newtable(L);
- push_ARGB8(L, color);
+
+ push_ARGB8(L, prop->nametag_color);
lua_setfield(L, -2, "color");
+
+ if (prop->nametag_bgcolor) {
+ push_ARGB8(L, prop->nametag_bgcolor.value());
+ lua_setfield(L, -2, "bgcolor");
+ } else {
+ lua_pushboolean(L, false);
+ lua_setfield(L, -2, "bgcolor");
+ }
+
lua_pushstring(L, prop->nametag.c_str());
lua_setfield(L, -2, "text");
+
+
+
return 1;
}
/* LuaEntitySAO-only */
-// set_velocity(self, {x=num, y=num, z=num})
+// set_velocity(self, velocity)
int ObjectRef::l_set_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (co == NULL) return 0;
- v3f pos = checkFloatPos(L, 2);
- // Do it
- co->setVelocity(pos);
+ LuaEntitySAO *sao = getluaobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ v3f vel = checkFloatPos(L, 2);
+
+ sao->setVelocity(vel);
return 0;
}
-// add_velocity(self, {x=num, y=num, z=num})
+// add_velocity(self, velocity)
int ObjectRef::l_add_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (!co)
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
return 0;
- v3f pos = checkFloatPos(L, 2);
- // Do it
- co->addVelocity(pos);
+
+ v3f vel = checkFloatPos(L, 2);
+
+ if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) {
+ LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao);
+ entitysao->addVelocity(vel);
+ } else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+ PlayerSAO *playersao = dynamic_cast<PlayerSAO*>(sao);
+ playersao->setMaxSpeedOverride(vel);
+ getServer(L)->SendPlayerSpeed(playersao->getPeerID(), vel);
+ }
+
return 0;
}
@@ -877,25 +836,37 @@ int ObjectRef::l_get_velocity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (co == NULL) return 0;
- // Do it
- v3f v = co->getVelocity();
- pushFloatPos(L, v);
+ ServerActiveObject *sao = getobject(ref);
+ if (sao == nullptr)
+ return 0;
+
+ if (sao->getType() == ACTIVEOBJECT_TYPE_LUAENTITY) {
+ LuaEntitySAO *entitysao = dynamic_cast<LuaEntitySAO*>(sao);
+ v3f vel = entitysao->getVelocity();
+ pushFloatPos(L, vel);
+ return 1;
+ } else if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
+ RemotePlayer *player = dynamic_cast<PlayerSAO*>(sao)->getPlayer();
+ push_v3f(L, player->getSpeed() / BS);
+ return 1;
+ }
+
+ lua_pushnil(L);
return 1;
}
-// set_acceleration(self, {x=num, y=num, z=num})
+// set_acceleration(self, acceleration)
int ObjectRef::l_set_acceleration(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (co == NULL) return 0;
- // pos
- v3f pos = checkFloatPos(L, 2);
- // Do it
- co->setAcceleration(pos);
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
+
+ v3f acceleration = checkFloatPos(L, 2);
+
+ entitysao->setAcceleration(acceleration);
return 0;
}
@@ -904,59 +875,58 @@ int ObjectRef::l_get_acceleration(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (co == NULL) return 0;
- // Do it
- v3f v = co->getAcceleration();
- pushFloatPos(L, v);
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
+
+ v3f acceleration = entitysao->getAcceleration();
+ pushFloatPos(L, acceleration);
return 1;
}
-// set_rotation(self, {x=num, y=num, z=num})
-// Each 'num' is in radians
+// set_rotation(self, rotation)
int ObjectRef::l_set_rotation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (!co)
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
return 0;
v3f rotation = check_v3f(L, 2) * core::RADTODEG;
- co->setRotation(rotation);
+
+ entitysao->setRotation(rotation);
return 0;
}
// get_rotation(self)
-// returns: {x=num, y=num, z=num}
-// Each 'num' is in radians
int ObjectRef::l_get_rotation(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (!co)
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
return 0;
+ v3f rotation = entitysao->getRotation() * core::DEGTORAD;
+
lua_newtable(L);
- v3f rotation = co->getRotation() * core::DEGTORAD;
push_v3f(L, rotation);
return 1;
}
-// set_yaw(self, radians)
+// set_yaw(self, yaw)
int ObjectRef::l_set_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
-
- if (co == NULL) return 0;
- if (isNaN(L, 2))
- throw LuaError("ObjectRef::set_yaw: NaN value is not allowed.");
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
float yaw = readParam<float>(L, 2) * core::RADTODEG;
- co->setRotation(v3f(0, yaw, 0));
+
+ entitysao->setRotation(v3f(0, yaw, 0));
return 0;
}
@@ -965,11 +935,12 @@ int ObjectRef::l_get_yaw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (!co)
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
return 0;
- float yaw = co->getRotation().Y * core::DEGTORAD;
+ float yaw = entitysao->getRotation().Y * core::DEGTORAD;
+
lua_pushnumber(L, yaw);
return 1;
}
@@ -979,11 +950,13 @@ int ObjectRef::l_set_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 = luaL_checkstring(L, 2);
- co->setTextureMod(mod);
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
+
+ std::string mod = readParam<std::string>(L, 2);
+
+ entitysao->setTextureMod(mod);
return 0;
}
@@ -992,36 +965,31 @@ 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();
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
+
+ std::string mod = entitysao->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)
+// set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera)
int ObjectRef::l_set_sprite(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (co == NULL) return 0;
- // Do it
- v2s16 p(0,0);
- if (!lua_isnil(L, 2))
- p = readParam<v2s16>(L, 2);
- int num_frames = 1;
- if (!lua_isnil(L, 3))
- num_frames = lua_tonumber(L, 3);
- float framelength = 0.2;
- if (!lua_isnil(L, 4))
- framelength = lua_tonumber(L, 4);
- bool select_horiz_by_yawpitch = false;
- if (!lua_isnil(L, 5))
- select_horiz_by_yawpitch = readParam<bool>(L, 5);
- co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
+
+ v2s16 start_frame = readParam<v2s16>(L, 2, v2s16(0,0));
+ int num_frames = readParam<int>(L, 3, 1);
+ float framelength = readParam<float>(L, 4, 0.2f);
+ bool select_x_by_camera = readParam<bool>(L, 5, false);
+
+ entitysao->setSprite(start_frame, num_frames, framelength, select_x_by_camera);
return 0;
}
@@ -1031,11 +999,13 @@ int ObjectRef::l_get_entity_name(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
+ LuaEntitySAO *entitysao = getluaobject(ref);
log_deprecated(L,"Deprecated call to \"get_entity_name");
- if (co == NULL) return 0;
- // Do it
- std::string name = co->getName();
+ if (entitysao == nullptr)
+ return 0;
+
+ std::string name = entitysao->getName();
+
lua_pushstring(L, name.c_str());
return 1;
}
@@ -1045,87 +1015,45 @@ int ObjectRef::l_get_luaentity(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- LuaEntitySAO *co = getluaobject(ref);
- if (co == NULL) return 0;
- // Do it
- luaentity_get(L, co->getId());
+ LuaEntitySAO *entitysao = getluaobject(ref);
+ if (entitysao == nullptr)
+ return 0;
+
+ luaentity_get(L, entitysao->getId());
return 1;
}
/* Player-only */
-// is_player_connected(self)
-int ObjectRef::l_is_player_connected(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- // This method was once added for a bugfix, but never documented
- log_deprecated(L, "is_player_connected is undocumented and "
- "will be removed in a future release");
- ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- lua_pushboolean(L, (player != NULL && player->getPeerId() != PEER_ID_INEXISTENT));
- return 1;
-}
-
// get_player_name(self)
int ObjectRef::l_get_player_name(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL) {
+ if (player == nullptr) {
lua_pushlstring(L, "", 0);
return 1;
}
- // Do it
- lua_pushstring(L, player->getName());
- return 1;
-}
-// get_player_velocity(self)
-int ObjectRef::l_get_player_velocity(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- ObjectRef *ref = checkobject(L, 1);
- RemotePlayer *player = getplayer(ref);
- if (player == NULL) {
- lua_pushnil(L);
- return 1;
- }
- // Do it
- push_v3f(L, player->getSpeed() / BS);
+ lua_pushstring(L, player->getName());
return 1;
}
-// add_player_velocity(self, {x=num, y=num, z=num})
-int ObjectRef::l_add_player_velocity(lua_State *L)
-{
- NO_MAP_LOCK_REQUIRED;
- ObjectRef *ref = checkobject(L, 1);
- v3f vel = checkFloatPos(L, 2);
-
- PlayerSAO *co = getplayersao(ref);
- if (!co)
- return 0;
-
- // Do it
- co->setMaxSpeedOverride(vel);
- getServer(L)->SendPlayerSpeed(co->getPeerID(), vel);
- return 0;
-}
-
// get_look_dir(self)
int ObjectRef::l_get_look_dir(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
- // Do it
- float pitch = co->getRadLookPitchDep();
- float yaw = co->getRadYawDep();
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ float pitch = playersao->getRadLookPitchDep();
+ float yaw = playersao->getRadYawDep();
v3f v(std::cos(pitch) * std::cos(yaw), std::sin(pitch), std::cos(pitch) *
std::sin(yaw));
+
push_v3f(L, v);
return 1;
}
@@ -1140,10 +1068,11 @@ int ObjectRef::l_get_look_pitch(lua_State *L)
"Deprecated call to get_look_pitch, use get_look_vertical instead");
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
- // Do it
- lua_pushnumber(L, co->getRadLookPitchDep());
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ lua_pushnumber(L, playersao->getRadLookPitchDep());
return 1;
}
@@ -1157,34 +1086,37 @@ int ObjectRef::l_get_look_yaw(lua_State *L)
"Deprecated call to get_look_yaw, use get_look_horizontal instead");
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
- // Do it
- lua_pushnumber(L, co->getRadYawDep());
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ lua_pushnumber(L, playersao->getRadYawDep());
return 1;
}
-// get_look_pitch2(self)
+// get_look_vertical(self)
int ObjectRef::l_get_look_vertical(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
- // Do it
- lua_pushnumber(L, co->getRadLookPitch());
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ lua_pushnumber(L, playersao->getRadLookPitch());
return 1;
}
-// get_look_yaw2(self)
+// get_look_horizontal(self)
int ObjectRef::l_get_look_horizontal(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
- // Do it
- lua_pushnumber(L, co->getRadRotation().Y);
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ lua_pushnumber(L, playersao->getRadRotation().Y);
return 1;
}
@@ -1193,11 +1125,13 @@ int ObjectRef::l_set_look_vertical(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
float pitch = readParam<float>(L, 2) * core::RADTODEG;
- // Do it
- co->setLookPitchAndSend(pitch);
+
+ playersao->setLookPitchAndSend(pitch);
return 1;
}
@@ -1206,11 +1140,13 @@ int ObjectRef::l_set_look_horizontal(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
float yaw = readParam<float>(L, 2) * core::RADTODEG;
- // Do it
- co->setPlayerYawAndSend(yaw);
+
+ playersao->setPlayerYawAndSend(yaw);
return 1;
}
@@ -1224,11 +1160,13 @@ int ObjectRef::l_set_look_pitch(lua_State *L)
"Deprecated call to set_look_pitch, use set_look_vertical instead.");
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
float pitch = readParam<float>(L, 2) * core::RADTODEG;
- // Do it
- co->setLookPitchAndSend(pitch);
+
+ playersao->setLookPitchAndSend(pitch);
return 1;
}
@@ -1242,30 +1180,32 @@ int ObjectRef::l_set_look_yaw(lua_State *L)
"Deprecated call to set_look_yaw, use set_look_horizontal instead.");
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
float yaw = readParam<float>(L, 2) * core::RADTODEG;
- // Do it
- co->setPlayerYawAndSend(yaw);
+
+ playersao->setPlayerYawAndSend(yaw);
return 1;
}
-// set_fov(self, degrees[, is_multiplier, transition_time])
+// set_fov(self, degrees, is_multiplier, transition_time)
int ObjectRef::l_set_fov(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
- player->setFov({
- static_cast<f32>(luaL_checknumber(L, 2)),
- readParam<bool>(L, 3, false),
- lua_isnumber(L, 4) ? static_cast<f32>(luaL_checknumber(L, 4)) : 0.0f
- });
- getServer(L)->SendPlayerFov(player->getPeerId());
+ float degrees = static_cast<f32>(luaL_checknumber(L, 2));
+ bool is_multiplier = readParam<bool>(L, 3, false);
+ float transition_time = lua_isnumber(L, 4) ?
+ static_cast<f32>(luaL_checknumber(L, 4)) : 0.0f;
+ player->setFov({degrees, is_multiplier, transition_time});
+ getServer(L)->SendPlayerFov(player->getPeerId());
return 0;
}
@@ -1275,14 +1215,14 @@ int ObjectRef::l_get_fov(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
PlayerFovSpec fov_spec = player->getFov();
+
lua_pushnumber(L, fov_spec.fov);
lua_pushboolean(L, fov_spec.is_multiplier);
lua_pushnumber(L, fov_spec.transition_time);
-
return 3;
}
@@ -1291,11 +1231,13 @@ int ObjectRef::l_set_breath(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
u16 breath = luaL_checknumber(L, 2);
- co->setBreath(breath);
+ playersao->setBreath(breath);
return 0;
}
@@ -1304,11 +1246,13 @@ int ObjectRef::l_get_breath(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL) return 0;
- // Do it
- u16 breath = co->getBreath();
- lua_pushinteger (L, breath);
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ u16 breath = playersao->getBreath();
+
+ lua_pushinteger(L, breath);
return 1;
}
@@ -1319,16 +1263,16 @@ int ObjectRef::l_set_attribute(lua_State *L)
"Deprecated call to set_attribute, use MetaDataRef methods instead.");
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL)
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
return 0;
std::string attr = luaL_checkstring(L, 2);
if (lua_isnil(L, 3)) {
- co->getMeta().removeString(attr);
+ playersao->getMeta().removeString(attr);
} else {
std::string value = luaL_checkstring(L, 3);
- co->getMeta().setString(attr, value);
+ playersao->getMeta().setString(attr, value);
}
return 1;
}
@@ -1340,14 +1284,14 @@ int ObjectRef::l_get_attribute(lua_State *L)
"Deprecated call to get_attribute, use MetaDataRef methods instead.");
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO* co = getplayersao(ref);
- if (co == NULL)
+ PlayerSAO* playersao = getplayersao(ref);
+ if (playersao == nullptr)
return 0;
std::string attr = luaL_checkstring(L, 2);
std::string value;
- if (co->getMeta().getStringToRef(attr, value)) {
+ if (playersao->getMeta().getStringToRef(attr, value)) {
lua_pushstring(L, value.c_str());
return 1;
}
@@ -1360,11 +1304,11 @@ int ObjectRef::l_get_attribute(lua_State *L)
int ObjectRef::l_get_meta(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
- PlayerSAO *co = getplayersao(ref);
- if (co == NULL)
+ PlayerSAO *playersao = getplayersao(ref);
+ if (playersao == nullptr)
return 0;
- PlayerMetaRef::create(L, &co->getMeta());
+ PlayerMetaRef::create(L, &playersao->getMeta());
return 1;
}
@@ -1375,7 +1319,9 @@ int ObjectRef::l_set_inventory_formspec(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ if (player == nullptr)
+ return 0;
+
std::string formspec = luaL_checkstring(L, 2);
player->inventory_formspec = formspec;
@@ -1390,9 +1336,11 @@ int ObjectRef::l_get_inventory_formspec(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL) return 0;
+ if (player == nullptr)
+ return 0;
std::string formspec = player->inventory_formspec;
+
lua_pushlstring(L, formspec.c_str(), formspec.size());
return 1;
}
@@ -1403,7 +1351,7 @@ int ObjectRef::l_set_formspec_prepend(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
std::string formspec = luaL_checkstring(L, 2);
@@ -1414,16 +1362,17 @@ int ObjectRef::l_set_formspec_prepend(lua_State *L)
return 1;
}
-// get_formspec_prepend(self) -> formspec
+// get_formspec_prepend(self)
int ObjectRef::l_get_formspec_prepend(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
std::string formspec = player->formspec_prepend;
+
lua_pushlstring(L, formspec.c_str(), formspec.size());
return 1;
}
@@ -1434,7 +1383,7 @@ int ObjectRef::l_get_player_control(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL) {
+ if (player == nullptr) {
lua_pushlstring(L, "", 0);
return 1;
}
@@ -1455,9 +1404,14 @@ int ObjectRef::l_get_player_control(lua_State *L)
lua_setfield(L, -2, "aux1");
lua_pushboolean(L, control.sneak);
lua_setfield(L, -2, "sneak");
- lua_pushboolean(L, control.LMB);
+ lua_pushboolean(L, control.dig);
+ lua_setfield(L, -2, "dig");
+ lua_pushboolean(L, control.place);
+ lua_setfield(L, -2, "place");
+ // Legacy fields to ensure mod compatibility
+ lua_pushboolean(L, control.dig);
lua_setfield(L, -2, "LMB");
- lua_pushboolean(L, control.RMB);
+ lua_pushboolean(L, control.place);
lua_setfield(L, -2, "RMB");
lua_pushboolean(L, control.zoom);
lua_setfield(L, -2, "zoom");
@@ -1470,22 +1424,87 @@ int ObjectRef::l_get_player_control_bits(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL) {
+ if (player == nullptr) {
lua_pushlstring(L, "", 0);
return 1;
}
- // Do it
+
lua_pushnumber(L, player->keyPressed);
return 1;
}
-// hud_add(self, form)
+// set_physics_override(self, override_table)
+int ObjectRef::l_set_physics_override(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ PlayerSAO *playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ if (lua_istable(L, 2)) {
+ bool modified = false;
+ modified |= getfloatfield(L, 2, "speed", playersao->m_physics_override_speed);
+ modified |= getfloatfield(L, 2, "jump", playersao->m_physics_override_jump);
+ modified |= getfloatfield(L, 2, "gravity", playersao->m_physics_override_gravity);
+ modified |= getboolfield(L, 2, "sneak", playersao->m_physics_override_sneak);
+ modified |= getboolfield(L, 2, "sneak_glitch", playersao->m_physics_override_sneak_glitch);
+ modified |= getboolfield(L, 2, "new_move", playersao->m_physics_override_new_move);
+ if (modified)
+ playersao->m_physics_override_sent = false;
+ } else {
+ // old, non-table format
+ // TODO: Remove this code after version 5.4.0
+ log_deprecated(L, "Deprecated use of set_physics_override(num, num, num)");
+
+ if (!lua_isnil(L, 2)) {
+ playersao->m_physics_override_speed = lua_tonumber(L, 2);
+ playersao->m_physics_override_sent = false;
+ }
+ if (!lua_isnil(L, 3)) {
+ playersao->m_physics_override_jump = lua_tonumber(L, 3);
+ playersao->m_physics_override_sent = false;
+ }
+ if (!lua_isnil(L, 4)) {
+ playersao->m_physics_override_gravity = lua_tonumber(L, 4);
+ playersao->m_physics_override_sent = false;
+ }
+ }
+ return 0;
+}
+
+// get_physics_override(self)
+int ObjectRef::l_get_physics_override(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ PlayerSAO *playersao = getplayersao(ref);
+ if (playersao == nullptr)
+ return 0;
+
+ lua_newtable(L);
+ lua_pushnumber(L, playersao->m_physics_override_speed);
+ lua_setfield(L, -2, "speed");
+ lua_pushnumber(L, playersao->m_physics_override_jump);
+ lua_setfield(L, -2, "jump");
+ lua_pushnumber(L, playersao->m_physics_override_gravity);
+ lua_setfield(L, -2, "gravity");
+ lua_pushboolean(L, playersao->m_physics_override_sneak);
+ lua_setfield(L, -2, "sneak");
+ lua_pushboolean(L, playersao->m_physics_override_sneak_glitch);
+ lua_setfield(L, -2, "sneak_glitch");
+ lua_pushboolean(L, playersao->m_physics_override_new_move);
+ lua_setfield(L, -2, "new_move");
+ return 1;
+}
+
+// hud_add(self, hud)
int ObjectRef::l_hud_add(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
HudElement *elem = new HudElement;
@@ -1507,12 +1526,10 @@ int ObjectRef::l_hud_remove(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- u32 id = -1;
- if (!lua_isnil(L, 2))
- id = lua_tonumber(L, 2);
+ u32 id = luaL_checkint(L, 2);
if (!getServer(L)->hudRemove(player, id))
return 0;
@@ -1527,17 +1544,17 @@ int ObjectRef::l_hud_change(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- u32 id = lua_isnumber(L, 2) ? lua_tonumber(L, 2) : -1;
+ u32 id = luaL_checkint(L, 2);
- HudElement *e = player->getHud(id);
- if (!e)
+ HudElement *elem = player->getHud(id);
+ if (elem == nullptr)
return 0;
- void *value = NULL;
- HudElementStat stat = read_hud_change(L, e, &value);
+ void *value = nullptr;
+ HudElementStat stat = read_hud_change(L, elem, &value);
getServer(L)->hudChange(player, id, stat, value);
@@ -1551,15 +1568,16 @@ int ObjectRef::l_hud_get(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- u32 id = lua_tonumber(L, -1);
+ u32 id = luaL_checkint(L, 2);
- HudElement *e = player->getHud(id);
- if (!e)
+ HudElement *elem = player->getHud(id);
+ if (elem == nullptr)
return 0;
- push_hud_element(L, e);
+
+ push_hud_element(L, elem);
return 1;
}
@@ -1569,7 +1587,7 @@ int ObjectRef::l_hud_set_flags(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
u32 flags = 0;
@@ -1590,12 +1608,13 @@ int ObjectRef::l_hud_set_flags(lua_State *L)
return 1;
}
+// hud_get_flags(self)
int ObjectRef::l_hud_get_flags(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
lua_newtable(L);
@@ -1613,7 +1632,6 @@ int ObjectRef::l_hud_get_flags(lua_State *L)
lua_setfield(L, -2, "minimap");
lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE);
lua_setfield(L, -2, "minimap_radar");
-
return 1;
}
@@ -1623,10 +1641,10 @@ int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
- s32 hotbar_itemcount = lua_tonumber(L, 2);
+ s32 hotbar_itemcount = luaL_checkint(L, 2);
if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
return 0;
@@ -1641,7 +1659,7 @@ int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
lua_pushnumber(L, player->getHotbarItemcount());
@@ -1654,7 +1672,7 @@ int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
std::string name = readParam<std::string>(L, 2);
@@ -1669,10 +1687,11 @@ int ObjectRef::l_hud_get_hotbar_image(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
const std::string &name = player->getHotbarImage();
+
lua_pushlstring(L, name.c_str(), name.size());
return 1;
}
@@ -1683,7 +1702,7 @@ int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
std::string name = readParam<std::string>(L, 2);
@@ -1698,44 +1717,45 @@ int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
const std::string &name = player->getHotbarSelectedImage();
+
lua_pushlstring(L, name.c_str(), name.size());
return 1;
}
-// set_sky(self, {base_color=, type=, textures=, clouds=, sky_colors={}})
+// set_sky(self, sky_parameters)
int ObjectRef::l_set_sky(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
+ SkyboxParams sky_params = player->getSkyParams();
bool is_colorspec = is_color_table(L, 2);
- SkyboxParams skybox_params = player->getSkyParams();
if (lua_istable(L, 2) && !is_colorspec) {
lua_getfield(L, 2, "base_color");
if (!lua_isnil(L, -1))
- read_color(L, -1, &skybox_params.bgcolor);
+ read_color(L, -1, &sky_params.bgcolor);
lua_pop(L, 1);
lua_getfield(L, 2, "type");
if (!lua_isnil(L, -1))
- skybox_params.type = luaL_checkstring(L, -1);
+ sky_params.type = luaL_checkstring(L, -1);
lua_pop(L, 1);
lua_getfield(L, 2, "textures");
- skybox_params.textures.clear();
- if (lua_istable(L, -1) && skybox_params.type == "skybox") {
+ sky_params.textures.clear();
+ if (lua_istable(L, -1) && sky_params.type == "skybox") {
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
// Key is at index -2 and value at index -1
- skybox_params.textures.emplace_back(readParam<std::string>(L, -1));
+ sky_params.textures.emplace_back(readParam<std::string>(L, -1));
// Removes the value, but keeps the key for iteration
lua_pop(L, 1);
}
@@ -1748,56 +1768,56 @@ int ObjectRef::l_set_sky(lua_State *L)
using "regular" or "plain" skybox modes as textures aren't needed.
*/
- if (skybox_params.textures.size() != 6 && skybox_params.textures.size() > 0)
+ if (sky_params.textures.size() != 6 && sky_params.textures.size() > 0)
throw LuaError("Skybox expects 6 textures!");
- skybox_params.clouds = getboolfield_default(L, 2,
- "clouds", skybox_params.clouds);
+ sky_params.clouds = getboolfield_default(L, 2,
+ "clouds", sky_params.clouds);
lua_getfield(L, 2, "sky_color");
if (lua_istable(L, -1)) {
lua_getfield(L, -1, "day_sky");
- read_color(L, -1, &skybox_params.sky_color.day_sky);
+ read_color(L, -1, &sky_params.sky_color.day_sky);
lua_pop(L, 1);
lua_getfield(L, -1, "day_horizon");
- read_color(L, -1, &skybox_params.sky_color.day_horizon);
+ read_color(L, -1, &sky_params.sky_color.day_horizon);
lua_pop(L, 1);
lua_getfield(L, -1, "dawn_sky");
- read_color(L, -1, &skybox_params.sky_color.dawn_sky);
+ read_color(L, -1, &sky_params.sky_color.dawn_sky);
lua_pop(L, 1);
lua_getfield(L, -1, "dawn_horizon");
- read_color(L, -1, &skybox_params.sky_color.dawn_horizon);
+ read_color(L, -1, &sky_params.sky_color.dawn_horizon);
lua_pop(L, 1);
lua_getfield(L, -1, "night_sky");
- read_color(L, -1, &skybox_params.sky_color.night_sky);
+ read_color(L, -1, &sky_params.sky_color.night_sky);
lua_pop(L, 1);
lua_getfield(L, -1, "night_horizon");
- read_color(L, -1, &skybox_params.sky_color.night_horizon);
+ read_color(L, -1, &sky_params.sky_color.night_horizon);
lua_pop(L, 1);
lua_getfield(L, -1, "indoors");
- read_color(L, -1, &skybox_params.sky_color.indoors);
+ read_color(L, -1, &sky_params.sky_color.indoors);
lua_pop(L, 1);
// Prevent flickering clouds at dawn/dusk:
- skybox_params.fog_sun_tint = video::SColor(255, 255, 255, 255);
+ sky_params.fog_sun_tint = video::SColor(255, 255, 255, 255);
lua_getfield(L, -1, "fog_sun_tint");
- read_color(L, -1, &skybox_params.fog_sun_tint);
+ read_color(L, -1, &sky_params.fog_sun_tint);
lua_pop(L, 1);
- skybox_params.fog_moon_tint = video::SColor(255, 255, 255, 255);
+ sky_params.fog_moon_tint = video::SColor(255, 255, 255, 255);
lua_getfield(L, -1, "fog_moon_tint");
- read_color(L, -1, &skybox_params.fog_moon_tint);
+ read_color(L, -1, &sky_params.fog_moon_tint);
lua_pop(L, 1);
lua_getfield(L, -1, "fog_tint_type");
if (!lua_isnil(L, -1))
- skybox_params.fog_tint_type = luaL_checkstring(L, -1);
+ sky_params.fog_tint_type = luaL_checkstring(L, -1);
lua_pop(L, 1);
// Because we need to leave the "sky_color" table.
@@ -1813,14 +1833,14 @@ int ObjectRef::l_set_sky(lua_State *L)
StarParams star_params = player->getStarParams();
// Prevent erroneous background colors
- skybox_params.bgcolor = video::SColor(255, 255, 255, 255);
- read_color(L, 2, &skybox_params.bgcolor);
+ sky_params.bgcolor = video::SColor(255, 255, 255, 255);
+ read_color(L, 2, &sky_params.bgcolor);
- skybox_params.type = luaL_checkstring(L, 3);
+ sky_params.type = luaL_checkstring(L, 3);
// Preserve old behaviour of the sun, moon and stars
// when using the old set_sky call.
- if (skybox_params.type == "regular") {
+ if (sky_params.type == "regular") {
sun_params.visible = true;
sun_params.sunrise_visible = true;
moon_params.visible = true;
@@ -1832,31 +1852,31 @@ int ObjectRef::l_set_sky(lua_State *L)
star_params.visible = false;
}
- skybox_params.textures.clear();
+ sky_params.textures.clear();
if (lua_istable(L, 4)) {
lua_pushnil(L);
while (lua_next(L, 4) != 0) {
// Key at index -2, and value at index -1
if (lua_isstring(L, -1))
- skybox_params.textures.emplace_back(readParam<std::string>(L, -1));
+ sky_params.textures.emplace_back(readParam<std::string>(L, -1));
else
- skybox_params.textures.emplace_back("");
+ sky_params.textures.emplace_back("");
// Remove the value, keep the key for the next iteration
lua_pop(L, 1);
}
}
- if (skybox_params.type == "skybox" && skybox_params.textures.size() != 6)
+ if (sky_params.type == "skybox" && sky_params.textures.size() != 6)
throw LuaError("Skybox expects 6 textures.");
- skybox_params.clouds = true;
+ sky_params.clouds = true;
if (lua_isboolean(L, 5))
- skybox_params.clouds = readParam<bool>(L, 5);
+ sky_params.clouds = readParam<bool>(L, 5);
getServer(L)->setSun(player, sun_params);
getServer(L)->setMoon(player, moon_params);
getServer(L)->setStars(player, star_params);
}
- getServer(L)->setSky(player, skybox_params);
+ getServer(L)->setSky(player, sky_params);
lua_pushboolean(L, true);
return 1;
}
@@ -1867,18 +1887,17 @@ int ObjectRef::l_get_sky(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
-
- if (!player)
+ if (player == nullptr)
return 0;
- SkyboxParams skybox_params;
- skybox_params = player->getSkyParams();
+
+ SkyboxParams skybox_params = player->getSkyParams();
push_ARGB8(L, skybox_params.bgcolor);
lua_pushlstring(L, skybox_params.type.c_str(), skybox_params.type.size());
lua_newtable(L);
s16 i = 1;
- for (const std::string& texture : skybox_params.textures) {
+ for (const std::string &texture : skybox_params.textures) {
lua_pushlstring(L, texture.c_str(), texture.size());
lua_rawseti(L, -2, i++);
}
@@ -1892,11 +1911,10 @@ int ObjectRef::l_get_sky_color(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
-
- if (!player)
+ if (player == nullptr)
return 0;
- const SkyboxParams& skybox_params = player->getSkyParams();
+ const SkyboxParams &skybox_params = player->getSkyParams();
lua_newtable(L);
if (skybox_params.type == "regular") {
@@ -1924,18 +1942,16 @@ int ObjectRef::l_get_sky_color(lua_State *L)
return 1;
}
-// set_sun(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=})
+// set_sun(self, sun_parameters)
int ObjectRef::l_set_sun(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))
+ if (player == nullptr)
return 0;
+ luaL_checktype(L, 2, LUA_TTABLE);
SunParams sun_params = player->getSunParams();
sun_params.visible = getboolfield_default(L, 2,
@@ -1962,8 +1978,9 @@ int ObjectRef::l_get_sun(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
+
const SunParams &sun_params = player->getSunParams();
lua_newtable(L);
@@ -1979,21 +1996,19 @@ int ObjectRef::l_get_sun(lua_State *L)
lua_setfield(L, -2, "sunrise_visible");
lua_pushnumber(L, sun_params.scale);
lua_setfield(L, -2, "scale");
-
return 1;
}
-// set_moon(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=})
+// set_moon(self, moon_parameters)
int ObjectRef::l_set_moon(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))
+ if (player == nullptr)
return 0;
+ luaL_checktype(L, 2, LUA_TTABLE);
MoonParams moon_params = player->getMoonParams();
moon_params.visible = getboolfield_default(L, 2,
@@ -2016,8 +2031,9 @@ int ObjectRef::l_get_moon(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
+
const MoonParams &moon_params = player->getMoonParams();
lua_newtable(L);
@@ -2029,21 +2045,19 @@ int ObjectRef::l_get_moon(lua_State *L)
lua_setfield(L, -2, "tonemap");
lua_pushnumber(L, moon_params.scale);
lua_setfield(L, -2, "scale");
-
return 1;
}
-// set_stars(self, {visible, count=, starcolor=, rotation=, scale=})
+// set_stars(self, star_parameters)
int ObjectRef::l_set_stars(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))
+ if (player == nullptr)
return 0;
+ luaL_checktype(L, 2, LUA_TTABLE);
StarParams star_params = player->getStarParams();
star_params.visible = getboolfield_default(L, 2,
@@ -2070,8 +2084,9 @@ int ObjectRef::l_get_stars(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
+
const StarParams &star_params = player->getStarParams();
lua_newtable(L);
@@ -2083,21 +2098,19 @@ int ObjectRef::l_get_stars(lua_State *L)
lua_setfield(L, -2, "star_color");
lua_pushnumber(L, star_params.scale);
lua_setfield(L, -2, "scale");
-
return 1;
}
-// set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
+// set_clouds(self, cloud_parameters)
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))
+ if (player == nullptr)
return 0;
+ luaL_checktype(L, 2, LUA_TTABLE);
CloudParams cloud_params = player->getCloudParams();
cloud_params.density = getfloatfield_default(L, 2, "density", cloud_params.density);
@@ -2133,8 +2146,9 @@ int ObjectRef::l_get_clouds(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (!player)
+ if (player == nullptr)
return 0;
+
const CloudParams &cloud_params = player->getCloudParams();
lua_newtable(L);
@@ -2154,25 +2168,27 @@ int ObjectRef::l_get_clouds(lua_State *L)
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)
+// override_day_night_ratio(self, ratio)
int ObjectRef::l_override_day_night_ratio(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
bool do_override = false;
float ratio = 0.0f;
+
if (!lua_isnil(L, 2)) {
do_override = true;
ratio = readParam<float>(L, 2);
+ luaL_argcheck(L, ratio >= 0.0f && ratio <= 1.0f, 1,
+ "value must be between 0 and 1");
}
getServer(L)->overrideDayNightRatio(player, do_override, ratio);
@@ -2186,7 +2202,7 @@ int ObjectRef::l_get_day_night_ratio(lua_State *L)
NO_MAP_LOCK_REQUIRED;
ObjectRef *ref = checkobject(L, 1);
RemotePlayer *player = getplayer(ref);
- if (player == NULL)
+ if (player == nullptr)
return 0;
bool do_override;
@@ -2201,27 +2217,77 @@ int ObjectRef::l_get_day_night_ratio(lua_State *L)
return 1;
}
-ObjectRef::ObjectRef(ServerActiveObject *object):
- m_object(object)
+// set_minimap_modes(self, modes, selected_mode)
+int ObjectRef::l_set_minimap_modes(lua_State *L)
{
- //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
+ NO_MAP_LOCK_REQUIRED;
+ ObjectRef *ref = checkobject(L, 1);
+ RemotePlayer *player = getplayer(ref);
+ if (player == nullptr)
+ return 0;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+ std::vector<MinimapMode> modes;
+ s16 selected_mode = readParam<s16>(L, 3);
+
+ lua_pushnil(L);
+ while (lua_next(L, 2) != 0) {
+ /* key is at index -2, value is at index -1 */
+ if (lua_istable(L, -1)) {
+ bool ok = true;
+ MinimapMode mode;
+ std::string type = getstringfield_default(L, -1, "type", "");
+ if (type == "off")
+ mode.type = MINIMAP_TYPE_OFF;
+ else if (type == "surface")
+ mode.type = MINIMAP_TYPE_SURFACE;
+ else if (type == "radar")
+ mode.type = MINIMAP_TYPE_RADAR;
+ else if (type == "texture") {
+ mode.type = MINIMAP_TYPE_TEXTURE;
+ mode.texture = getstringfield_default(L, -1, "texture", "");
+ mode.scale = getintfield_default(L, -1, "scale", 1);
+ } else {
+ warningstream << "Minimap mode of unknown type \"" << type.c_str()
+ << "\" ignored.\n" << std::endl;
+ ok = false;
+ }
+
+ if (ok) {
+ mode.label = getstringfield_default(L, -1, "label", "");
+ // Size is limited to 512. Performance gets poor if size too large, and
+ // segfaults have been experienced.
+ mode.size = rangelim(getintfield_default(L, -1, "size", 0), 1, 512);
+ modes.push_back(mode);
+ }
+ }
+ /* removes 'value'; keeps 'key' for next iteration */
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1); // Remove key
+
+ getServer(L)->SendMinimapModes(player->getPeerId(), modes, selected_mode);
+ return 0;
}
+ObjectRef::ObjectRef(ServerActiveObject *object):
+ m_object(object)
+{}
+
// Creates an ObjectRef and leaves it on top of stack
// Not callable from Lua; all references are created on the C side.
void ObjectRef::create(lua_State *L, ServerActiveObject *object)
{
- ObjectRef *o = new ObjectRef(object);
- //infostream<<"ObjectRef::create: o="<<o<<std::endl;
- *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ ObjectRef *obj = new ObjectRef(object);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = obj;
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
}
void ObjectRef::set_null(lua_State *L)
{
- ObjectRef *o = checkobject(L, -1);
- o->m_object = NULL;
+ ObjectRef *obj = checkobject(L, -1);
+ obj->m_object = nullptr;
}
void ObjectRef::Register(lua_State *L)
@@ -2245,12 +2311,8 @@ void ObjectRef::Register(lua_State *L)
lua_pop(L, 1); // drop metatable
- markAliasDeprecated(methods);
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 ObjectRef::className[] = "ObjectRef";
@@ -2278,15 +2340,19 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, get_bone_position),
luamethod(ObjectRef, set_attach),
luamethod(ObjectRef, get_attach),
+ luamethod(ObjectRef, get_children),
luamethod(ObjectRef, set_detach),
luamethod(ObjectRef, set_properties),
luamethod(ObjectRef, get_properties),
luamethod(ObjectRef, set_nametag_attributes),
luamethod(ObjectRef, get_nametag_attributes),
- // LuaEntitySAO-only
+
luamethod_aliased(ObjectRef, set_velocity, setvelocity),
- luamethod(ObjectRef, add_velocity),
+ luamethod_aliased(ObjectRef, add_velocity, add_player_velocity),
luamethod_aliased(ObjectRef, get_velocity, getvelocity),
+ luamethod_dep(ObjectRef, get_velocity, get_player_velocity),
+
+ // LuaEntitySAO-only
luamethod_aliased(ObjectRef, set_acceleration, setacceleration),
luamethod_aliased(ObjectRef, get_acceleration, getacceleration),
luamethod_aliased(ObjectRef, set_yaw, setyaw),
@@ -2294,15 +2360,14 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, set_rotation),
luamethod(ObjectRef, get_rotation),
luamethod_aliased(ObjectRef, set_texture_mod, settexturemod),
+ luamethod(ObjectRef, get_texture_mod),
luamethod_aliased(ObjectRef, set_sprite, setsprite),
luamethod(ObjectRef, get_entity_name),
luamethod(ObjectRef, get_luaentity),
+
// Player-only
luamethod(ObjectRef, is_player),
- luamethod(ObjectRef, is_player_connected),
luamethod(ObjectRef, get_player_name),
- luamethod(ObjectRef, get_player_velocity),
- luamethod(ObjectRef, add_player_velocity),
luamethod(ObjectRef, get_look_dir),
luamethod(ObjectRef, get_look_pitch),
luamethod(ObjectRef, get_look_yaw),
@@ -2357,5 +2422,6 @@ luaL_Reg ObjectRef::methods[] = {
luamethod(ObjectRef, set_eye_offset),
luamethod(ObjectRef, get_eye_offset),
luamethod(ObjectRef, send_mapblock),
+ luamethod(ObjectRef, set_minimap_modes),
{0,0}
};
diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h
index a75c59fd9..db3a3a7cf 100644
--- a/src/script/lua_api/l_object.h
+++ b/src/script/lua_api/l_object.h
@@ -69,29 +69,24 @@ private:
static int l_remove(lua_State *L);
// get_pos(self)
- // returns: {x=num, y=num, z=num}
static int l_get_pos(lua_State *L);
// set_pos(self, pos)
static int l_set_pos(lua_State *L);
- // move_to(self, pos, continuous=false)
+ // move_to(self, pos, continuous)
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);
- // right_click(self, clicker); clicker = an another ObjectRef
+ // right_click(self, clicker)
static int l_right_click(lua_State *L);
- // set_hp(self, hp)
- // hp = number of hitpoints (2 * number of hearts)
- // returns: nil
+ // set_hp(self, hp, reason)
static int l_set_hp(lua_State *L);
// get_hp(self)
- // returns: number of hitpoints (2 * number of hearts)
- // 0 if not applicable to this type of object
static int l_get_hp(lua_State *L);
// get_inventory(self)
@@ -106,7 +101,7 @@ private:
// get_wielded_item(self)
static int l_get_wielded_item(lua_State *L);
- // set_wielded_item(self, itemstack or itemstring or table or nil)
+ // set_wielded_item(self, item)
static int l_set_wielded_item(lua_State *L);
// set_armor_groups(self, groups)
@@ -115,8 +110,7 @@ private:
// get_armor_groups(self)
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, new_move)
+ // set_physics_override(self, override_table)
static int l_set_physics_override(lua_State *L);
// get_physics_override(self)
@@ -131,7 +125,7 @@ private:
// get_animation(self)
static int l_get_animation(lua_State *L);
- // set_bone_position(self, std::string bone, v3f position, v3f rotation)
+ // set_bone_position(self, bone, position, rotation)
static int l_set_bone_position(lua_State *L);
// get_bone_position(self, bone)
@@ -143,6 +137,9 @@ private:
// get_attach(self)
static int l_get_attach(lua_State *L);
+ // get_children(self)
+ static int l_get_children(lua_State *L);
+
// set_detach(self)
static int l_set_detach(lua_State *L);
@@ -157,28 +154,28 @@ private:
/* LuaEntitySAO-only */
- // set_velocity(self, {x=num, y=num, z=num})
+ // set_velocity(self, velocity)
static int l_set_velocity(lua_State *L);
- // add_velocity(self, {x=num, y=num, z=num})
+ // add_velocity(self, velocity)
static int l_add_velocity(lua_State *L);
// get_velocity(self)
static int l_get_velocity(lua_State *L);
- // set_acceleration(self, {x=num, y=num, z=num})
+ // set_acceleration(self, acceleration)
static int l_set_acceleration(lua_State *L);
// get_acceleration(self)
static int l_get_acceleration(lua_State *L);
- // set_rotation(self, {x=num, y=num, z=num})
+ // set_rotation(self, rotation)
static int l_set_rotation(lua_State *L);
// get_rotation(self)
static int l_get_rotation(lua_State *L);
- // set_yaw(self, radians)
+ // set_yaw(self, yaw)
static int l_set_yaw(lua_State *L);
// get_yaw(self)
@@ -190,8 +187,7 @@ private:
// 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)
+ // set_sprite(self, start_frame, num_frames, framelength, select_x_by_camera)
static int l_set_sprite(lua_State *L);
// DEPRECATED
@@ -203,18 +199,9 @@ private:
/* Player-only */
- // is_player_connected(self)
- static int l_is_player_connected(lua_State *L);
-
// get_player_name(self)
static int l_get_player_name(lua_State *L);
- // get_player_velocity(self)
- static int l_get_player_velocity(lua_State *L);
-
- // add_player_velocity(self, {x=num, y=num, z=num})
- static int l_add_player_velocity(lua_State *L);
-
// get_fov(self)
static int l_get_fov(lua_State *L);
@@ -235,7 +222,7 @@ private:
// get_look_yaw2(self)
static int l_get_look_horizontal(lua_State *L);
- // set_fov(self, degrees, is_multiplier)
+ // set_fov(self, degrees, is_multiplier, transition_time)
static int l_set_fov(lua_State *L);
// set_look_vertical(self, radians)
@@ -258,9 +245,11 @@ private:
// get_breath(self, breath)
static int l_get_breath(lua_State *L);
+ // DEPRECATED
// set_attribute(self, attribute, value)
static int l_set_attribute(lua_State *L);
+ // DEPRECATED
// get_attribute(self, attribute)
static int l_get_attribute(lua_State *L);
@@ -270,13 +259,13 @@ private:
// set_inventory_formspec(self, formspec)
static int l_set_inventory_formspec(lua_State *L);
- // get_inventory_formspec(self) -> formspec
+ // get_inventory_formspec(self)
static int l_get_inventory_formspec(lua_State *L);
// set_formspec_prepend(self, formspec)
static int l_set_formspec_prepend(lua_State *L);
- // get_formspec_prepend(self) -> formspec
+ // get_formspec_prepend(self)
static int l_get_formspec_prepend(lua_State *L);
// get_player_control(self)
@@ -324,7 +313,7 @@ private:
// hud_get_hotbar_selected_image(self)
static int l_hud_get_hotbar_selected_image(lua_State *L);
- // set_sky({base_color=, type=, textures=, clouds=, sky_colors={}})
+ // set_sky(self, sky_parameters)
static int l_set_sky(lua_State *L);
// get_sky(self)
@@ -333,25 +322,25 @@ private:
// get_sky_color(self)
static int l_get_sky_color(lua_State* L);
- // set_sun(self, {visible, texture=, tonemap=, sunrise=, rotation=, scale=})
+ // set_sun(self, sun_parameters)
static int l_set_sun(lua_State *L);
// get_sun(self)
static int l_get_sun(lua_State *L);
- // set_moon(self, {visible, texture=, tonemap=, rotation, scale=})
+ // set_moon(self, moon_parameters)
static int l_set_moon(lua_State *L);
// get_moon(self)
static int l_get_moon(lua_State *L);
- // set_stars(self, {visible, count=, starcolor=, rotation, scale=})
+ // set_stars(self, star_parameters)
static int l_set_stars(lua_State *L);
// get_stars(self)
static int l_get_stars(lua_State *L);
- // set_clouds(self, {density=, color=, ambient=, height=, thickness=, speed=})
+ // set_clouds(self, cloud_parameters)
static int l_set_clouds(lua_State *L);
// get_clouds(self)
@@ -363,13 +352,13 @@ private:
// get_day_night_ratio(self)
static int l_get_day_night_ratio(lua_State *L);
- // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed)
+ // set_local_animation(self, idle, walk, dig, walk_while_dig, frame_speed)
static int l_set_local_animation(lua_State *L);
// get_local_animation(self)
static int l_get_local_animation(lua_State *L);
- // set_eye_offset(self, v3f first pv, v3f third pv)
+ // set_eye_offset(self, firstperson, thirdperson)
static int l_set_eye_offset(lua_State *L);
// get_eye_offset(self)
@@ -383,4 +372,7 @@ private:
// send_mapblock(pos)
static int l_send_mapblock(lua_State *L);
+
+ // set_minimap_modes(self, modes, wanted_mode)
+ static int l_set_minimap_modes(lua_State *L);
};
diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp
index 6f934bb9d..bf5292521 100644
--- a/src/script/lua_api/l_server.cpp
+++ b/src/script/lua_api/l_server.cpp
@@ -44,7 +44,7 @@ int ModApiServer::l_request_shutdown(lua_State *L)
int ModApiServer::l_get_server_status(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- lua_pushstring(L, wide_to_narrow(getServer(L)->getStatusString()).c_str());
+ lua_pushstring(L, getServer(L)->getStatusString().c_str());
return 1;
}
@@ -116,24 +116,18 @@ int ModApiServer::l_get_player_privs(lua_State *L)
int ModApiServer::l_get_player_ip(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- const char * name = luaL_checkstring(L, 1);
- RemotePlayer *player = dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name);
- if(player == NULL)
- {
+
+ Server *server = getServer(L);
+
+ const char *name = luaL_checkstring(L, 1);
+ RemotePlayer *player = server->getEnv().getPlayer(name);
+ if (!player) {
lua_pushnil(L); // no such player
return 1;
}
- try
- {
- Address addr = getServer(L)->getPeerAddress(player->getPeerId());
- std::string ip_str = addr.serializeString();
- lua_pushstring(L, ip_str.c_str());
- return 1;
- } catch (const con::PeerNotFoundException &) {
- dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
- lua_pushnil(L); // error
- return 1;
- }
+
+ lua_pushstring(L, server->getPeerAddress(player->getPeerId()).serializeString().c_str());
+ return 1;
}
// get_player_information(name)
@@ -150,26 +144,18 @@ int ModApiServer::l_get_player_information(lua_State *L)
return 1;
}
- Address addr;
- try {
- addr = server->getPeerAddress(player->getPeerId());
- } catch (const con::PeerNotFoundException &) {
- dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
- lua_pushnil(L); // error
- return 1;
- }
-
- float min_rtt, max_rtt, avg_rtt, min_jitter, max_jitter, avg_jitter;
- ClientState state;
- u32 uptime;
- u16 prot_vers;
- u8 ser_vers, major, minor, patch;
- std::string vers_string, lang_code;
+ /*
+ Be careful not to introduce a depdendency on the connection to
+ the peer here. This function is >>REQUIRED<< to still be able to return
+ values even when the peer unexpectedly disappears.
+ Hence all the ConInfo values here are optional.
+ */
auto getConInfo = [&] (con::rtt_stat_type type, float *value) -> bool {
return server->getClientConInfo(player->getPeerId(), type, value);
};
+ float min_rtt, max_rtt, avg_rtt, min_jitter, max_jitter, avg_jitter;
bool have_con_info =
getConInfo(con::MIN_RTT, &min_rtt) &&
getConInfo(con::MAX_RTT, &max_rtt) &&
@@ -178,11 +164,9 @@ int ModApiServer::l_get_player_information(lua_State *L)
getConInfo(con::MAX_JITTER, &max_jitter) &&
getConInfo(con::AVG_JITTER, &avg_jitter);
- bool r = server->getClientInfo(player->getPeerId(), &state, &uptime,
- &ser_vers, &prot_vers, &major, &minor, &patch, &vers_string,
- &lang_code);
- if (!r) {
- dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
+ ClientInfo info;
+ if (!server->getClientInfo(player->getPeerId(), info)) {
+ warningstream << FUNCTION_NAME << ": no client info?!" << std::endl;
lua_pushnil(L); // error
return 1;
}
@@ -191,13 +175,13 @@ int ModApiServer::l_get_player_information(lua_State *L)
int table = lua_gettop(L);
lua_pushstring(L,"address");
- lua_pushstring(L, addr.serializeString().c_str());
+ lua_pushstring(L, info.addr.serializeString().c_str());
lua_settable(L, table);
lua_pushstring(L,"ip_version");
- if (addr.getFamily() == AF_INET) {
+ if (info.addr.getFamily() == AF_INET) {
lua_pushnumber(L, 4);
- } else if (addr.getFamily() == AF_INET6) {
+ } else if (info.addr.getFamily() == AF_INET6) {
lua_pushnumber(L, 6);
} else {
lua_pushnumber(L, 0);
@@ -231,11 +215,11 @@ int ModApiServer::l_get_player_information(lua_State *L)
}
lua_pushstring(L,"connection_uptime");
- lua_pushnumber(L, uptime);
+ lua_pushnumber(L, info.uptime);
lua_settable(L, table);
lua_pushstring(L,"protocol_version");
- lua_pushnumber(L, prot_vers);
+ lua_pushnumber(L, info.prot_vers);
lua_settable(L, table);
lua_pushstring(L, "formspec_version");
@@ -243,32 +227,32 @@ int ModApiServer::l_get_player_information(lua_State *L)
lua_settable(L, table);
lua_pushstring(L, "lang_code");
- lua_pushstring(L, lang_code.c_str());
+ lua_pushstring(L, info.lang_code.c_str());
lua_settable(L, table);
#ifndef NDEBUG
lua_pushstring(L,"serialization_version");
- lua_pushnumber(L, ser_vers);
+ lua_pushnumber(L, info.ser_vers);
lua_settable(L, table);
lua_pushstring(L,"major");
- lua_pushnumber(L, major);
+ lua_pushnumber(L, info.major);
lua_settable(L, table);
lua_pushstring(L,"minor");
- lua_pushnumber(L, minor);
+ lua_pushnumber(L, info.minor);
lua_settable(L, table);
lua_pushstring(L,"patch");
- lua_pushnumber(L, patch);
+ lua_pushnumber(L, info.patch);
lua_settable(L, table);
lua_pushstring(L,"version_string");
- lua_pushstring(L, vers_string.c_str());
+ lua_pushstring(L, info.vers_string.c_str());
lua_settable(L, table);
lua_pushstring(L,"state");
- lua_pushstring(L,ClientInterface::state2Name(state).c_str());
+ lua_pushstring(L, ClientInterface::state2Name(info.state).c_str());
lua_settable(L, table);
#endif
@@ -296,23 +280,18 @@ int ModApiServer::l_get_ban_description(lua_State *L)
int ModApiServer::l_ban_player(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- const char * name = luaL_checkstring(L, 1);
- RemotePlayer *player = dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name);
- if (player == NULL) {
+
+ Server *server = getServer(L);
+
+ const char *name = luaL_checkstring(L, 1);
+ RemotePlayer *player = server->getEnv().getPlayer(name);
+ if (!player) {
lua_pushboolean(L, false); // no such player
return 1;
}
- try
- {
- Address addr = getServer(L)->getPeerAddress(
- dynamic_cast<ServerEnvironment *>(getEnv(L))->getPlayer(name)->getPeerId());
- std::string ip_str = addr.serializeString();
- getServer(L)->setIpBanned(ip_str, name);
- } catch(const con::PeerNotFoundException &) {
- dstream << FUNCTION_NAME << ": peer was not found" << std::endl;
- lua_pushboolean(L, false); // error
- return 1;
- }
+
+ std::string ip_str = server->getPeerAddress(player->getPeerId()).serializeString();
+ server->setIpBanned(ip_str, name);
lua_pushboolean(L, true);
return 1;
}
@@ -473,19 +452,30 @@ int ModApiServer::l_sound_fade(lua_State *L)
}
// dynamic_add_media(filepath)
-int ModApiServer::l_dynamic_add_media(lua_State *L)
+int ModApiServer::l_dynamic_add_media_raw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- // Reject adding media before the server has started up
if (!getEnv(L))
throw LuaError("Dynamic media cannot be added before server has started up");
std::string filepath = readParam<std::string>(L, 1);
CHECK_SECURE_PATH(L, filepath.c_str(), false);
- bool ok = getServer(L)->dynamicAddMedia(filepath);
- lua_pushboolean(L, ok);
+ std::vector<RemotePlayer*> sent_to;
+ bool ok = getServer(L)->dynamicAddMedia(filepath, sent_to);
+ if (ok) {
+ // (see wrapper code in builtin)
+ lua_createtable(L, sent_to.size(), 0);
+ int i = 0;
+ for (RemotePlayer *player : sent_to) {
+ lua_pushstring(L, player->getName());
+ lua_rawseti(L, -2, ++i);
+ }
+ } else {
+ lua_pushboolean(L, false);
+ }
+
return 1;
}
@@ -553,7 +543,7 @@ void ModApiServer::Initialize(lua_State *L, int top)
API_FCT(sound_play);
API_FCT(sound_stop);
API_FCT(sound_fade);
- API_FCT(dynamic_add_media);
+ API_FCT(dynamic_add_media_raw);
API_FCT(get_player_information);
API_FCT(get_player_privs);
diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h
index 938bfa8ef..2df180b17 100644
--- a/src/script/lua_api/l_server.h
+++ b/src/script/lua_api/l_server.h
@@ -71,7 +71,7 @@ private:
static int l_sound_fade(lua_State *L);
// dynamic_add_media(filepath)
- static int l_dynamic_add_media(lua_State *L);
+ static int l_dynamic_add_media_raw(lua_State *L);
// get_player_privs(name, text)
static int l_get_player_privs(lua_State *L);
diff --git a/src/script/lua_api/l_settings.cpp b/src/script/lua_api/l_settings.cpp
index 33eb02392..bcbaf15fa 100644
--- a/src/script/lua_api/l_settings.cpp
+++ b/src/script/lua_api/l_settings.cpp
@@ -197,7 +197,7 @@ int LuaSettings::l_set_np_group(lua_State *L)
SET_SECURITY_CHECK(L, key);
- o->m_settings->setNoiseParams(key, value, false);
+ o->m_settings->setNoiseParams(key, value);
return 0;
}
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index cd63e20c2..203a0dd28 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -239,21 +239,23 @@ int ModApiUtil::l_is_yes(lua_State *L)
return 1;
}
-// is_nan(arg)
-int ModApiUtil::l_is_nan(lua_State *L)
+// get_builtin_path()
+int ModApiUtil::l_get_builtin_path(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- lua_pushboolean(L, isNaN(L, 1));
+ std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM;
+ lua_pushstring(L, path.c_str());
+
return 1;
}
-// get_builtin_path()
-int ModApiUtil::l_get_builtin_path(lua_State *L)
+// get_user_path()
+int ModApiUtil::l_get_user_path(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
- std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM;
+ std::string path = porting::path_user;
lua_pushstring(L, path.c_str());
return 1;
@@ -493,9 +495,9 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(get_password_hash);
API_FCT(is_yes);
- API_FCT(is_nan);
API_FCT(get_builtin_path);
+ API_FCT(get_user_path);
API_FCT(compress);
API_FCT(decompress);
@@ -526,7 +528,6 @@ void ModApiUtil::InitializeClient(lua_State *L, int top)
API_FCT(write_json);
API_FCT(is_yes);
- API_FCT(is_nan);
API_FCT(compress);
API_FCT(decompress);
@@ -550,6 +551,7 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
API_FCT(is_yes);
API_FCT(get_builtin_path);
+ API_FCT(get_user_path);
API_FCT(compress);
API_FCT(decompress);
diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h
index 9ff91bb53..dbdd62b99 100644
--- a/src/script/lua_api/l_util.h
+++ b/src/script/lua_api/l_util.h
@@ -65,12 +65,12 @@ private:
// is_yes(arg)
static int l_is_yes(lua_State *L);
- // is_nan(arg)
- static int l_is_nan(lua_State *L);
-
// get_builtin_path()
static int l_get_builtin_path(lua_State *L);
+ // get_user_path()
+ static int l_get_user_path(lua_State *L);
+
// compress(data, method, ...)
static int l_compress(lua_State *L);
diff --git a/src/script/scripting_mainmenu.cpp b/src/script/scripting_mainmenu.cpp
index 0f672f917..b102a66a1 100644
--- a/src/script/scripting_mainmenu.cpp
+++ b/src/script/scripting_mainmenu.cpp
@@ -31,7 +31,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
extern "C" {
#include "lualib.h"
}
-
#define MAINMENU_NUM_ASYNC_THREADS 4