diff options
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/cpp_api/s_item.h | 1 | ||||
-rw-r--r-- | src/script/lua_api/l_env.cpp | 105 | ||||
-rw-r--r-- | src/script/lua_api/l_env.h | 45 | ||||
-rw-r--r-- | src/script/scripting_server.cpp | 1 |
4 files changed, 152 insertions, 0 deletions
diff --git a/src/script/cpp_api/s_item.h b/src/script/cpp_api/s_item.h index 7350a71c5..6ceb4b559 100644 --- a/src/script/cpp_api/s_item.h +++ b/src/script/cpp_api/s_item.h @@ -52,6 +52,7 @@ public: protected: friend class LuaItemStack; friend class ModApiItemMod; + friend class LuaRaycast; bool getItemCallback(const char *name, const char *callbackname); void pushPointedThing(const PointedThing& pointed); diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index e7284b035..3a4ba89f3 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -131,6 +131,105 @@ void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n) lua_pop(L, 1); // Pop error handler } +int LuaRaycast::l_next(lua_State *L) +{ + MAP_LOCK_REQUIRED; + + ScriptApiItem *script = getScriptApi<ScriptApiItem>(L); + GET_ENV_PTR; + + LuaRaycast *o = checkobject(L, 1); + PointedThing pointed; + env->continueRaycast(&o->state, &pointed); + if (pointed.type == POINTEDTHING_NOTHING) + lua_pushnil(L); + else + script->pushPointedThing(pointed); + + return 1; +} + +int LuaRaycast::create_object(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + bool objects = true; + bool liquids = false; + + v3f pos1 = checkFloatPos(L, 1); + v3f pos2 = checkFloatPos(L, 2); + if (lua_isboolean(L, 3)) { + objects = lua_toboolean(L, 3); + } + if (lua_isboolean(L, 4)) { + liquids = lua_toboolean(L, 4); + } + + LuaRaycast *o = new LuaRaycast(core::line3d<f32>(pos1, pos2), + objects, liquids); + + *(void **) (lua_newuserdata(L, sizeof(void *))) = o; + luaL_getmetatable(L, className); + lua_setmetatable(L, -2); + return 1; +} + +LuaRaycast *LuaRaycast::checkobject(lua_State *L, int narg) +{ + NO_MAP_LOCK_REQUIRED; + + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if (!ud) + luaL_typerror(L, narg, className); + return *(LuaRaycast **) ud; +} + +int LuaRaycast::gc_object(lua_State *L) +{ + LuaRaycast *o = *(LuaRaycast **) (lua_touserdata(L, 1)); + delete o; + return 0; +} + +void LuaRaycast::Register(lua_State *L) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, className); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__gc"); + lua_pushcfunction(L, gc_object); + lua_settable(L, metatable); + + lua_pushliteral(L, "__call"); + lua_pushcfunction(L, l_next); + lua_settable(L, metatable); + + lua_pop(L, 1); + + luaL_openlib(L, 0, methods, 0); + lua_pop(L, 1); + + lua_register(L, className, create_object); +} + +const char LuaRaycast::className[] = "Raycast"; +const luaL_Reg LuaRaycast::methods[] = +{ + luamethod(LuaRaycast, next), + { 0, 0 } +}; + void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param) { ScriptCallbackState *state = (ScriptCallbackState *)param; @@ -904,6 +1003,11 @@ int ModApiEnvMod::l_fix_light(lua_State *L) return 1; } +int ModApiEnvMod::l_raycast(lua_State *L) +{ + return LuaRaycast::create_object(L); +} + // emerge_area(p1, p2, [callback, context]) // emerge mapblocks in area p1..p2, calls callback with context upon completion int ModApiEnvMod::l_emerge_area(lua_State *L) @@ -1155,6 +1259,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top) API_FCT(spawn_tree); API_FCT(find_path); API_FCT(line_of_sight); + API_FCT(raycast); API_FCT(transforming_liquid_add); API_FCT(forceload_block); API_FCT(forceload_free_block); diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h index 7ce19b085..f380d8d6f 100644 --- a/src/script/lua_api/l_env.h +++ b/src/script/lua_api/l_env.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_base.h" #include "serverenvironment.h" +#include "raycast.h" class ModApiEnvMod : public ModApiBase { private: @@ -159,6 +160,9 @@ private: // line_of_sight(pos1, pos2, stepsize) -> true/false static int l_line_of_sight(lua_State *L); + // raycast(pos1, pos2, objects, liquids) -> Raycast + static int l_raycast(lua_State *L); + // find_path(pos1, pos2, searchdistance, // max_jump, max_drop, algorithm) -> table containing path static int l_find_path(lua_State *L); @@ -245,6 +249,47 @@ public: virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n); }; +//! Lua wrapper for RaycastState objects +class LuaRaycast : public ModApiBase +{ +private: + static const char className[]; + static const luaL_Reg methods[]; + //! Inner state + RaycastState state; + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + /*! + * Raycast:next() -> pointed_thing + * Returns the next pointed thing on the ray. + */ + static int l_next(lua_State *L); +public: + //! Constructor with the same arguments as RaycastState. + LuaRaycast( + const core::line3d<f32> &shootline, + bool objects_pointable, + bool liquids_pointable) : + state(shootline, objects_pointable, liquids_pointable) + {} + + //! Creates a LuaRaycast and leaves it on top of the stack. + static int create_object(lua_State *L); + + /*! + * Returns the Raycast from the stack or throws an error. + * @param narg location of the RaycastState in the stack + */ + static LuaRaycast *checkobject(lua_State *L, int narg); + + //! Registers Raycast as a Lua userdata type. + static void Register(lua_State *L); +}; + struct ScriptCallbackState { ServerScripting *script; int callback_ref; diff --git a/src/script/scripting_server.cpp b/src/script/scripting_server.cpp index 51e13f04d..01e8e2fb5 100644 --- a/src/script/scripting_server.cpp +++ b/src/script/scripting_server.cpp @@ -92,6 +92,7 @@ void ServerScripting::InitializeModApi(lua_State *L, int top) LuaPerlinNoiseMap::Register(L); LuaPseudoRandom::Register(L); LuaPcgRandom::Register(L); + LuaRaycast::Register(L); LuaSecureRandom::Register(L); LuaVoxelManip::Register(L); NodeMetaRef::Register(L); |