]> git.lizzy.rs Git - minetest.git/blobdiff - src/script/lua_api/l_localplayer.cpp
Remove setlocal and setupvalue from `debug` table whitelist
[minetest.git] / src / script / lua_api / l_localplayer.cpp
index 87190cb393e3f79ef479722284ac9e4334413902..bdbe98cb0422fa7705cb6279d95781a5ba1a5617 100644 (file)
@@ -19,26 +19,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "l_localplayer.h"
 #include "l_internal.h"
+#include "lua_api/l_item.h"
 #include "script/common/c_converter.h"
+#include "client/localplayer.h"
+#include "hud.h"
+#include "common/c_content.h"
+#include "client/content_cao.h"
 
-LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m) { m_localplayer = m; }
+LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m) : m_localplayer(m)
+{
+}
 
 void LuaLocalPlayer::create(lua_State *L, LocalPlayer *m)
 {
+       lua_getglobal(L, "core");
+       luaL_checktype(L, -1, LUA_TTABLE);
+       int objectstable = lua_gettop(L);
+       lua_getfield(L, -1, "localplayer");
+
+       // Duplication check
+       if (lua_type(L, -1) == LUA_TUSERDATA) {
+               lua_pop(L, 1);
+               return;
+       }
+
        LuaLocalPlayer *o = new LuaLocalPlayer(m);
        *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
        luaL_getmetatable(L, className);
        lua_setmetatable(L, -2);
 
-       // Keep localplayer object stack id
-       int localplayer_object = lua_gettop(L);
-
-       lua_getglobal(L, "core");
-       luaL_checktype(L, -1, LUA_TTABLE);
-       int coretable = lua_gettop(L);
-
-       lua_pushvalue(L, localplayer_object);
-       lua_setfield(L, coretable, "localplayer");
+       lua_pushvalue(L, lua_gettop(L));
+       lua_setfield(L, objectstable, "localplayer");
 }
 
 int LuaLocalPlayer::l_get_velocity(lua_State *L)
@@ -65,11 +76,23 @@ int LuaLocalPlayer::l_get_name(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_is_teleported(lua_State *L)
+// get_wield_index(self)
+int LuaLocalPlayer::l_get_wield_index(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
 
-       lua_pushboolean(L, player->got_teleported);
+       lua_pushinteger(L, player->getWieldIndex());
+       return 1;
+}
+
+// get_wielded_item(self)
+int LuaLocalPlayer::l_get_wielded_item(lua_State *L)
+{
+       LocalPlayer *player = getobject(L, 1);
+
+       ItemStack selected_item;
+       player->getWieldedItem(&selected_item, nullptr);
+       LuaItemStack::create(L, selected_item);
        return 1;
 }
 
@@ -77,7 +100,7 @@ int LuaLocalPlayer::l_is_attached(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
 
-       lua_pushboolean(L, player->isAttached);
+       lua_pushboolean(L, player->getParent() != nullptr);
        return 1;
 }
 
@@ -105,11 +128,11 @@ int LuaLocalPlayer::l_is_in_liquid_stable(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_get_liquid_viscosity(lua_State *L)
+int LuaLocalPlayer::l_get_move_resistance(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
 
-       lua_pushinteger(L, player->liquid_viscosity);
+       lua_pushinteger(L, player->move_resistance);
        return 1;
 }
 
@@ -129,6 +152,7 @@ int LuaLocalPlayer::l_swimming_vertical(lua_State *L)
        return 1;
 }
 
+// get_physics_override(self)
 int LuaLocalPlayer::l_get_physics_override(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -149,14 +173,9 @@ int LuaLocalPlayer::l_get_physics_override(lua_State *L)
        lua_pushboolean(L, player->physics_override_sneak_glitch);
        lua_setfield(L, -2, "sneak_glitch");
 
-       return 1;
-}
+       lua_pushboolean(L, player->physics_override_new_move);
+       lua_setfield(L, -2, "new_move");
 
-int LuaLocalPlayer::l_get_override_pos(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       push_v3f(L, player->overridePosition);
        return 1;
 }
 
@@ -192,14 +211,37 @@ int LuaLocalPlayer::l_get_last_look_horizontal(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_get_key_pressed(lua_State *L)
+// get_control(self)
+int LuaLocalPlayer::l_get_control(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
+       const PlayerControl &c = player->getPlayerControl();
+
+       auto set = [L] (const char *name, bool value) {
+               lua_pushboolean(L, value);
+               lua_setfield(L, -2, name);
+       };
+
+       lua_createtable(L, 0, 12);
+       set("jump",  c.jump);
+       set("aux1",  c.aux1);
+       set("sneak", c.sneak);
+       set("zoom",  c.zoom);
+       set("dig",   c.dig);
+       set("place", c.place);
+       // Player movement in polar coordinates and non-binary speed
+       set("movement_speed",     c.movement_speed);
+       set("movement_direction", c.movement_direction);
+       // Provide direction keys to ensure compatibility
+       set("up",    player->keyPressed & (1 << 0)); // Up, down, left, and right were removed in favor of
+       set("down",  player->keyPressed & (1 << 1)); // analog  direction indicators and are therefore not
+       set("left",  player->keyPressed & (1 << 2)); // available as booleans anymore. The corresponding values
+       set("right", player->keyPressed & (1 << 3)); // can still be read from the keyPressed bits though.
 
-       lua_pushinteger(L, player->last_keyPressed);
        return 1;
 }
 
+// get_breath(self)
 int LuaLocalPlayer::l_get_breath(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -208,34 +250,7 @@ int LuaLocalPlayer::l_get_breath(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_get_look_dir(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       float pitch = -1.0 * player->getPitch() * core::DEGTORAD;
-       float yaw = (player->getYaw() + 90.) * core::DEGTORAD;
-       v3f v(cos(pitch) * cos(yaw), sin(pitch), cos(pitch) * sin(yaw));
-
-       push_v3f(L, v);
-       return 1;
-}
-
-int LuaLocalPlayer::l_get_look_horizontal(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       lua_pushnumber(L, (player->getYaw() + 90.) * core::DEGTORAD);
-       return 1;
-}
-
-int LuaLocalPlayer::l_get_look_vertical(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       lua_pushnumber(L, -1.0 * player->getPitch() * core::DEGTORAD);
-       return 1;
-}
-
+// get_pos(self)
 int LuaLocalPlayer::l_get_pos(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -244,22 +259,7 @@ int LuaLocalPlayer::l_get_pos(lua_State *L)
        return 1;
 }
 
-int LuaLocalPlayer::l_get_eye_pos(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       push_v3f(L, player->getEyePosition());
-       return 1;
-}
-
-int LuaLocalPlayer::l_get_eye_offset(lua_State *L)
-{
-       LocalPlayer *player = getobject(L, 1);
-
-       push_v3f(L, player->getEyeOffset());
-       return 1;
-}
-
+// get_movement_acceleration(self)
 int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -277,6 +277,7 @@ int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L)
        return 1;
 }
 
+// get_movement_speed(self)
 int LuaLocalPlayer::l_get_movement_speed(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -300,6 +301,7 @@ int LuaLocalPlayer::l_get_movement_speed(lua_State *L)
        return 1;
 }
 
+// get_movement(self)
 int LuaLocalPlayer::l_get_movement(lua_State *L)
 {
        LocalPlayer *player = getobject(L, 1);
@@ -321,6 +323,81 @@ int LuaLocalPlayer::l_get_movement(lua_State *L)
        return 1;
 }
 
+// get_armor_groups(self)
+int LuaLocalPlayer::l_get_armor_groups(lua_State *L)
+{
+       LocalPlayer *player = getobject(L, 1);
+       push_groups(L, player->getCAO()->getGroups());
+       return 1;
+}
+
+// hud_add(self, form)
+int LuaLocalPlayer::l_hud_add(lua_State *L)
+{
+       LocalPlayer *player = getobject(L, 1);
+
+       HudElement *elem = new HudElement;
+       read_hud_element(L, elem);
+
+       u32 id = player->addHud(elem);
+       if (id == U32_MAX) {
+               delete elem;
+               return 0;
+       }
+       lua_pushnumber(L, id);
+       return 1;
+}
+
+// hud_remove(self, id)
+int LuaLocalPlayer::l_hud_remove(lua_State *L)
+{
+       LocalPlayer *player = getobject(L, 1);
+       u32 id = luaL_checkinteger(L, 2);
+       HudElement *element = player->removeHud(id);
+       if (!element)
+               lua_pushboolean(L, false);
+       else
+               lua_pushboolean(L, true);
+       delete element;
+       return 1;
+}
+
+// hud_change(self, id, stat, data)
+int LuaLocalPlayer::l_hud_change(lua_State *L)
+{
+       LocalPlayer *player = getobject(L, 1);
+
+       u32 id = luaL_checkinteger(L, 2);
+
+       HudElement *element = player->getHud(id);
+       if (!element)
+               return 0;
+
+       HudElementStat stat;
+       void *unused;
+       bool ok = read_hud_change(L, stat, element, &unused);
+
+       lua_pushboolean(L, ok);
+       return 1;
+}
+
+// hud_get(self, id)
+int LuaLocalPlayer::l_hud_get(lua_State *L)
+{
+       LocalPlayer *player = getobject(L, 1);
+
+       u32 id = luaL_checkinteger(L, -1);
+
+       HudElement *e = player->getHud(id);
+       if (!e) {
+               lua_pushnil(L);
+               return 1;
+       }
+
+       push_hud_element(L, e);
+       return 1;
+}
+
 LuaLocalPlayer *LuaLocalPlayer::checkobject(lua_State *L, int narg)
 {
        luaL_checktype(L, narg, LUA_TUSERDATA);
@@ -332,7 +409,10 @@ LuaLocalPlayer *LuaLocalPlayer::checkobject(lua_State *L, int narg)
        return *(LuaLocalPlayer **)ud;
 }
 
-LocalPlayer *LuaLocalPlayer::getobject(LuaLocalPlayer *ref) { return ref->m_localplayer; }
+LocalPlayer *LuaLocalPlayer::getobject(LuaLocalPlayer *ref)
+{
+       return ref->m_localplayer;
+}
 
 LocalPlayer *LuaLocalPlayer::getobject(lua_State *L, int narg)
 {
@@ -371,37 +451,43 @@ void LuaLocalPlayer::Register(lua_State *L)
 
        lua_pop(L, 1); // Drop metatable
 
-       luaL_openlib(L, 0, methods, 0); // fill methodtable
+       luaL_register(L, nullptr, methods); // fill methodtable
        lua_pop(L, 1);                  // Drop methodtable
 }
 
 const char LuaLocalPlayer::className[] = "LocalPlayer";
-const luaL_reg LuaLocalPlayer::methods[] = {luamethod(LuaLocalPlayer, get_velocity),
-               luamethod(LuaLocalPlayer, get_hp), luamethod(LuaLocalPlayer, get_name),
-               luamethod(LuaLocalPlayer, is_teleported),
+const luaL_Reg LuaLocalPlayer::methods[] = {
+               luamethod(LuaLocalPlayer, get_velocity),
+               luamethod(LuaLocalPlayer, get_hp),
+               luamethod(LuaLocalPlayer, get_name),
+               luamethod(LuaLocalPlayer, get_wield_index),
+               luamethod(LuaLocalPlayer, get_wielded_item),
                luamethod(LuaLocalPlayer, is_attached),
                luamethod(LuaLocalPlayer, is_touching_ground),
                luamethod(LuaLocalPlayer, is_in_liquid),
                luamethod(LuaLocalPlayer, is_in_liquid_stable),
-               luamethod(LuaLocalPlayer, get_liquid_viscosity),
                luamethod(LuaLocalPlayer, is_climbing),
                luamethod(LuaLocalPlayer, swimming_vertical),
                luamethod(LuaLocalPlayer, get_physics_override),
-               luamethod(LuaLocalPlayer, get_override_pos),
+               // TODO: figure our if these are useful in any way
                luamethod(LuaLocalPlayer, get_last_pos),
                luamethod(LuaLocalPlayer, get_last_velocity),
                luamethod(LuaLocalPlayer, get_last_look_horizontal),
                luamethod(LuaLocalPlayer, get_last_look_vertical),
-               luamethod(LuaLocalPlayer, get_key_pressed),
+               //
+               luamethod(LuaLocalPlayer, get_control),
                luamethod(LuaLocalPlayer, get_breath),
-               luamethod(LuaLocalPlayer, get_look_dir),
-               luamethod(LuaLocalPlayer, get_look_horizontal),
-               luamethod(LuaLocalPlayer, get_look_vertical),
                luamethod(LuaLocalPlayer, get_pos),
-               luamethod(LuaLocalPlayer, get_eye_pos),
-               luamethod(LuaLocalPlayer, get_eye_offset),
                luamethod(LuaLocalPlayer, get_movement_acceleration),
                luamethod(LuaLocalPlayer, get_movement_speed),
                luamethod(LuaLocalPlayer, get_movement),
+               luamethod(LuaLocalPlayer, get_armor_groups),
+               luamethod(LuaLocalPlayer, hud_add),
+               luamethod(LuaLocalPlayer, hud_remove),
+               luamethod(LuaLocalPlayer, hud_change),
+               luamethod(LuaLocalPlayer, hud_get),
+
+               luamethod(LuaLocalPlayer, get_move_resistance),
 
-               {0, 0}};
+               {0, 0}
+};