From 8ad3dad137df740ce63101bf224e977e66b9df2c Mon Sep 17 00:00:00 2001 From: Vincent Glize Date: Sat, 8 Apr 2017 12:26:45 +0200 Subject: LocalPlayer api lua --- src/client.cpp | 4 +- src/script/clientscripting.cpp | 8 + src/script/clientscripting.h | 2 + src/script/lua_api/CMakeLists.txt | 1 + src/script/lua_api/l_localplayer.cpp | 416 +++++++++++++++++++++++++++++++++++ src/script/lua_api/l_localplayer.h | 95 ++++++++ 6 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 src/script/lua_api/l_localplayer.cpp create mode 100644 src/script/lua_api/l_localplayer.h (limited to 'src') diff --git a/src/client.cpp b/src/client.cpp index 3a3e33cfd..246525f62 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1865,8 +1865,10 @@ void Client::afterContentReceived(IrrlichtDevice *device) m_state = LC_Ready; sendReady(); - if (g_settings->getBool("enable_client_modding")) + if (g_settings->getBool("enable_client_modding")) { + m_script->on_client_ready(m_env.getLocalPlayer()); m_script->on_connect(); + } text = wgettext("Done!"); draw_load_screen(text, device, guienv, 0, 100); diff --git a/src/script/clientscripting.cpp b/src/script/clientscripting.cpp index 6f91b82ec..ba3f910c0 100644 --- a/src/script/clientscripting.cpp +++ b/src/script/clientscripting.cpp @@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_util.h" #include "lua_api/l_item.h" #include "lua_api/l_nodemeta.h" +#include "lua_api/l_localplayer.h" ClientScripting::ClientScripting(Client *client): ScriptApiBase() @@ -69,4 +70,11 @@ void ClientScripting::InitializeModApi(lua_State *L, int top) StorageRef::Register(L); LuaMinimap::Register(L); NodeMetaRef::RegisterClient(L); + LuaLocalPlayer::Register(L); +} + +void ClientScripting::on_client_ready(LocalPlayer *localplayer) +{ + lua_State *L = getStack(); + LuaLocalPlayer::create(L, localplayer); } diff --git a/src/script/clientscripting.h b/src/script/clientscripting.h index e2a91f695..df94e8b71 100644 --- a/src/script/clientscripting.h +++ b/src/script/clientscripting.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "cpp_api/s_security.h" class Client; +class LocalPlayer; class ClientScripting: virtual public ScriptApiBase, public ScriptApiSecurity, @@ -33,6 +34,7 @@ class ClientScripting: { public: ClientScripting(Client *client); + void on_client_ready(LocalPlayer *localplayer); private: virtual void InitializeModApi(lua_State *L, int top); diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt index f7f22870e..b03e94a09 100644 --- a/src/script/lua_api/CMakeLists.txt +++ b/src/script/lua_api/CMakeLists.txt @@ -28,4 +28,5 @@ set(client_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_minimap.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_storage.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_sound.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_localplayer.cpp PARENT_SCOPE) diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp new file mode 100644 index 000000000..dc07d2445 --- /dev/null +++ b/src/script/lua_api/l_localplayer.cpp @@ -0,0 +1,416 @@ +/* +Minetest +Copyright (C) 2017 Dumbeldor, Vincent Glize + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "script/common/c_converter.h" +#include "l_localplayer.h" +#include "l_internal.h" + +LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m) +{ + m_localplayer = m; +} + +void LuaLocalPlayer::create(lua_State *L, LocalPlayer *m) +{ + LuaLocalPlayer *o = new LuaLocalPlayer(m); + *(void **) (lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + + // Keep localplayer object stack id + int localplayer_object = lua_gettop(L); + + lua_getglobal(L, "core"); + luaL_checktype(L, -1, LUA_TTABLE); + int coretable = lua_gettop(L); + + lua_pushvalue(L, localplayer_object); + lua_setfield(L, coretable, "localplayer"); +} + +int LuaLocalPlayer::l_get_velocity(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->getSpeed() / BS); + return 1; +} + +int LuaLocalPlayer::l_get_hp(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->hp); + return 1; +} + +int LuaLocalPlayer::l_get_name(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushstring(L, player->getName()); + return 1; +} + +int LuaLocalPlayer::l_is_teleported(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->got_teleported); + return 1; +} + +int LuaLocalPlayer::l_is_attached(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->isAttached); + return 1; +} + +int LuaLocalPlayer::l_is_touching_ground(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->touching_ground); + return 1; +} + +int LuaLocalPlayer::l_is_in_liquid(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->in_liquid); + return 1; +} + +int LuaLocalPlayer::l_is_in_liquid_stable(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->in_liquid_stable); + return 1; +} + +int LuaLocalPlayer::l_get_liquid_viscosity(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->liquid_viscosity); + return 1; +} + +int LuaLocalPlayer::l_is_climbing(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->is_climbing); + return 1; +} + +int LuaLocalPlayer::l_swimming_vertical(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushboolean(L, player->swimming_vertical); + return 1; +} + +int LuaLocalPlayer::l_get_physics_override(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + lua_pushnumber(L, player->physics_override_speed); + lua_setfield(L, -2, "speed"); + + lua_pushnumber(L, player->physics_override_jump); + lua_setfield(L, -2, "jump"); + + lua_pushnumber(L, player->physics_override_gravity); + lua_setfield(L, -2, "gravity"); + + lua_pushboolean(L, player->physics_override_sneak); + lua_setfield(L, -2, "sneak"); + + lua_pushboolean(L, player->physics_override_sneak_glitch); + lua_setfield(L, -2, "sneak_glitch"); + + return 1; +} + +int LuaLocalPlayer::l_get_override_pos(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->overridePosition); + return 1; +} + +int LuaLocalPlayer::l_get_last_pos(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->last_position / BS); + return 1; +} + +int LuaLocalPlayer::l_get_last_velocity(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->last_speed); + return 1; +} + +int LuaLocalPlayer::l_get_last_look_vertical(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushnumber(L, -1.0 * player->last_pitch * core::DEGTORAD); + return 1; +} + +int LuaLocalPlayer::l_get_last_look_horizontal(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushnumber(L, (player->last_yaw + 90.) * core::DEGTORAD); + return 1; +} + +int LuaLocalPlayer::l_get_key_pressed(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->last_keyPressed); + return 1; +} + +int LuaLocalPlayer::l_get_breath(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_pushinteger(L, player->getBreath()); + return 1; +} + +int LuaLocalPlayer::l_get_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; +} + +int LuaLocalPlayer::l_get_pos(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + push_v3f(L, player->getPosition() / BS); + return 1; +} + +int LuaLocalPlayer::l_get_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; +} + +int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + lua_pushnumber(L, player->movement_acceleration_default); + lua_setfield(L, -2, "default"); + + lua_pushnumber(L, player->movement_acceleration_air); + lua_setfield(L, -2, "air"); + + lua_pushnumber(L, player->movement_acceleration_fast); + lua_setfield(L, -2, "fast"); + + return 1; +} + +int LuaLocalPlayer::l_get_movement_speed(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + lua_pushnumber(L, player->movement_speed_walk); + lua_setfield(L, -2, "walk"); + + lua_pushnumber(L, player->movement_speed_crouch); + lua_setfield(L, -2, "crouch"); + + lua_pushnumber(L, player->movement_speed_fast); + lua_setfield(L, -2, "fast"); + + lua_pushnumber(L, player->movement_speed_climb); + lua_setfield(L, -2, "climb"); + + lua_pushnumber(L, player->movement_speed_jump); + lua_setfield(L, -2, "jump"); + + return 1; +} + +int LuaLocalPlayer::l_get_movement(lua_State *L) +{ + LocalPlayer *player = getobject(L, 1); + + lua_newtable(L); + + lua_pushnumber(L, player->movement_liquid_fluidity); + lua_setfield(L, -2, "liquid_fluidity"); + + lua_pushnumber(L, player->movement_liquid_fluidity_smooth); + lua_setfield(L, -2, "liquid_fluidity_smooth"); + + lua_pushnumber(L, player->movement_liquid_sink); + lua_setfield(L, -2, "liquid_sink"); + + lua_pushnumber(L, player->movement_gravity); + lua_setfield(L, -2, "gravity"); + + return 1; +} + +LuaLocalPlayer *LuaLocalPlayer::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + + return *(LuaLocalPlayer **) ud; +} + +LocalPlayer *LuaLocalPlayer::getobject(LuaLocalPlayer *ref) +{ + return ref->m_localplayer; +} + +LocalPlayer *LuaLocalPlayer::getobject(lua_State *L, int narg) +{ + LuaLocalPlayer *ref = checkobject(L, narg); + assert(ref); + LocalPlayer *player = getobject(ref); + assert(player); + return player; +} + +int LuaLocalPlayer::gc_object(lua_State *L) +{ + LuaLocalPlayer *o = *(LuaLocalPlayer **) (lua_touserdata(L, 1)); + delete o; + return 0; +} + +void LuaLocalPlayer::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); // hide metatable from lua getmetatable() + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pop(L, 1); // Drop metatable + + luaL_openlib(L, 0, methods, 0); // fill methodtable + lua_pop(L, 1); // Drop methodtable +} + +const char LuaLocalPlayer::className[] = "LocalPlayer"; +const luaL_reg LuaLocalPlayer::methods[] = { + luamethod(LuaLocalPlayer, get_velocity), + luamethod(LuaLocalPlayer, get_hp), + luamethod(LuaLocalPlayer, get_name), + luamethod(LuaLocalPlayer, is_teleported), + luamethod(LuaLocalPlayer, is_attached), + luamethod(LuaLocalPlayer, is_touching_ground), + luamethod(LuaLocalPlayer, is_in_liquid), + luamethod(LuaLocalPlayer, is_in_liquid_stable), + luamethod(LuaLocalPlayer, get_liquid_viscosity), + luamethod(LuaLocalPlayer, is_climbing), + luamethod(LuaLocalPlayer, swimming_vertical), + luamethod(LuaLocalPlayer, get_physics_override), + luamethod(LuaLocalPlayer, get_override_pos), + luamethod(LuaLocalPlayer, get_last_pos), + luamethod(LuaLocalPlayer, get_last_velocity), + luamethod(LuaLocalPlayer, get_last_look_horizontal), + luamethod(LuaLocalPlayer, get_last_look_vertical), + luamethod(LuaLocalPlayer, get_key_pressed), + luamethod(LuaLocalPlayer, get_breath), + luamethod(LuaLocalPlayer, get_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), + + {0, 0} +}; diff --git a/src/script/lua_api/l_localplayer.h b/src/script/lua_api/l_localplayer.h new file mode 100644 index 000000000..19012f01f --- /dev/null +++ b/src/script/lua_api/l_localplayer.h @@ -0,0 +1,95 @@ +/* +Minetest +Copyright (C) 2017 Dumbeldor, Vincent Glize + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef MINETEST_L_LOCALPLAYER_H +#define MINETEST_L_LOCALPLAYER_H + +#include "l_base.h" + + +class LocalPlayer; + +class LuaLocalPlayer : public ModApiBase { +private: + + static const char className[]; + static const luaL_Reg methods[]; + + // garbage collector + static int gc_object(lua_State *L); + + static int l_get_velocity(lua_State *L); + + static int l_get_hp(lua_State *L); + + static int l_get_name(lua_State *L); + + static int l_is_teleported(lua_State *L); + static int l_is_attached(lua_State *L); + static int l_is_touching_ground(lua_State *L); + static int l_is_in_liquid(lua_State *L); + static int l_is_in_liquid_stable(lua_State *L); + static int l_get_liquid_viscosity(lua_State *L); + static int l_is_climbing(lua_State *L); + static int l_swimming_vertical(lua_State *L); + + static int l_get_physics_override(lua_State *L); + + static int l_get_override_pos(lua_State *L); + + static int l_get_last_pos(lua_State *L); + static int l_get_last_velocity(lua_State *L); + static int l_get_last_look_vertical(lua_State *L); + static int l_get_last_look_horizontal(lua_State *L); + static int l_get_key_pressed(lua_State *L); + + static int l_get_breath(lua_State *L); + + static int l_get_look_dir(lua_State *L); + static int l_get_look_horizontal(lua_State *L); + static int l_get_look_vertical(lua_State *L); + + static int l_get_pos(lua_State *L); + + static int l_get_eye_pos(lua_State *L); + static int l_get_eye_offset(lua_State *L); + + static int l_get_movement_acceleration(lua_State *L); + + static int l_get_movement_speed(lua_State *L); + + static int l_get_movement(lua_State *L); + + LocalPlayer *m_localplayer; + +public: + LuaLocalPlayer(LocalPlayer *m); + ~LuaLocalPlayer() {} + + static void create(lua_State *L, LocalPlayer *m); + + static LuaLocalPlayer *checkobject(lua_State *L, int narg); + static LocalPlayer *getobject(LuaLocalPlayer *ref); + static LocalPlayer *getobject(lua_State *L, int narg); + + static void Register(lua_State *L); +}; + + +#endif //MINETEST_L_LOCALPLAYER_H -- cgit v1.2.3