]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/scriptapi.cpp
Add EnvRef:get_objects_inside_radius(pos, radius)
[dragonfireclient.git] / src / scriptapi.cpp
index a88d6be5ab66f59694910626d90836ac71070ad6..1a50e1e34e1571854c11323e229a2f5066d1a07b 100644 (file)
@@ -164,7 +164,44 @@ void check_modname_prefix(lua_State *L, std::string &name)
                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
                throw LuaError(L, std::string("Name \"")+name
                                +"\" does not follow naming conventions: "
-                               +"\"contains unallowed characters)");
+                               +"\"contains unallowed characters");
+}
+
+static void push_v3f(lua_State *L, v3f p)
+{
+       lua_newtable(L);
+       lua_pushnumber(L, p.X);
+       lua_setfield(L, -2, "x");
+       lua_pushnumber(L, p.Y);
+       lua_setfield(L, -2, "y");
+       lua_pushnumber(L, p.Z);
+       lua_setfield(L, -2, "z");
+}
+
+static v2s16 read_v2s16(lua_State *L, int index)
+{
+       v2s16 p;
+       luaL_checktype(L, index, LUA_TTABLE);
+       lua_getfield(L, index, "x");
+       p.X = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       lua_getfield(L, index, "y");
+       p.Y = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       return p;
+}
+
+static v2f read_v2f(lua_State *L, int index)
+{
+       v2f p;
+       luaL_checktype(L, index, LUA_TTABLE);
+       lua_getfield(L, index, "x");
+       p.X = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       lua_getfield(L, index, "y");
+       p.Y = lua_tonumber(L, -1);
+       lua_pop(L, 1);
+       return p;
 }
 
 static v3f readFloatPos(lua_State *L, int index)
@@ -187,13 +224,7 @@ static v3f readFloatPos(lua_State *L, int index)
 static void pushFloatPos(lua_State *L, v3f p)
 {
        p /= BS;
-       lua_newtable(L);
-       lua_pushnumber(L, p.X);
-       lua_setfield(L, -2, "x");
-       lua_pushnumber(L, p.Y);
-       lua_setfield(L, -2, "y");
-       lua_pushnumber(L, p.Z);
-       lua_setfield(L, -2, "z");
+       push_v3f(L, p);
 }
 
 static void pushpos(lua_State *L, v3s16 p)
@@ -228,7 +259,7 @@ static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
 static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
 {
        lua_getfield(L, index, "name");
-       const char *name = lua_tostring(L, -1);
+       const char *name = luaL_checkstring(L, -1);
        lua_pop(L, 1);
        u8 param1;
        lua_getfield(L, index, "param1");
@@ -293,32 +324,6 @@ static core::aabbox3d<f32> read_aabbox3df32(lua_State *L, int index, f32 scale)
        return box;
 }
 
-static v2s16 read_v2s16(lua_State *L, int index)
-{
-       v2s16 p;
-       luaL_checktype(L, index, LUA_TTABLE);
-       lua_getfield(L, index, "x");
-       p.X = lua_tonumber(L, -1);
-       lua_pop(L, 1);
-       lua_getfield(L, index, "y");
-       p.Y = lua_tonumber(L, -1);
-       lua_pop(L, 1);
-       return p;
-}
-
-static v2f read_v2f(lua_State *L, int index)
-{
-       v2f p;
-       luaL_checktype(L, index, LUA_TTABLE);
-       lua_getfield(L, index, "x");
-       p.X = lua_tonumber(L, -1);
-       lua_pop(L, 1);
-       lua_getfield(L, index, "y");
-       p.Y = lua_tonumber(L, -1);
-       lua_pop(L, 1);
-       return p;
-}
-
 static bool getstringfield(lua_State *L, int table,
                const char *fieldname, std::string &result)
 {
@@ -489,7 +494,7 @@ static void inventory_set_list_from_lua(Inventory *inv, const char *name,
        while(lua_next(L, table) != 0){
                // key at index -2 and value at index -1
                luaL_checktype(L, -1, LUA_TSTRING);
-               std::string itemstring = lua_tostring(L, -1);
+               std::string itemstring = luaL_checkstring(L, -1);
                items.push_back(itemstring);
                // removes value, keeps key for next iteration
                lua_pop(L, 1);
@@ -1334,6 +1339,23 @@ static int l_get_player_privs(lua_State *L)
        return 1;
 }
 
+// get_modpath(modname)
+static int l_get_modpath(lua_State *L)
+{
+       const char *modname = luaL_checkstring(L, 1);
+       // Get server from registry
+       lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
+       Server *server = (Server*)lua_touserdata(L, -1);
+       // Do it
+       const ModSpec *mod = server->getModSpec(modname);
+       if(!mod){
+               lua_pushnil(L);
+               return 1;
+       }
+       lua_pushstring(L, mod->path.c_str());
+       return 1;
+}
+
 static const struct luaL_Reg minetest_f [] = {
        {"register_nodedef_defaults", l_register_nodedef_defaults},
        {"register_entity", l_register_entity},
@@ -1350,6 +1372,7 @@ static const struct luaL_Reg minetest_f [] = {
        {"chat_send_all", l_chat_send_all},
        {"chat_send_player", l_chat_send_player},
        {"get_player_privs", l_get_player_privs},
+       {"get_modpath", l_get_modpath},
        {NULL, NULL}
 };
 
@@ -1488,7 +1511,7 @@ class NodeMetaRef
                NodeMetadata *meta = getmeta(ref);
                if(meta == NULL) return 0;
                // Do it
-               std::string text = lua_tostring(L, 2);
+               std::string text = luaL_checkstring(L, 2);
                meta->setText(text);
                reportMetadataChange(ref);
                return 0;
@@ -1528,7 +1551,7 @@ class NodeMetaRef
                NodeMetadata *meta = getmeta(ref);
                if(meta == NULL) return 0;
                // Do it
-               std::string text = lua_tostring(L, 2);
+               std::string text = luaL_checkstring(L, 2);
                meta->setInfoText(text);
                reportMetadataChange(ref);
                return 0;
@@ -1542,7 +1565,7 @@ class NodeMetaRef
                if(meta == NULL) return 0;
                // Do it
                Inventory *inv = meta->getInventory();
-               const char *name = lua_tostring(L, 2);
+               const char *name = luaL_checkstring(L, 2);
                inventory_set_list_from_lua(inv, name, L, 3,
                                ref->m_env->getGameDef());
                reportMetadataChange(ref);
@@ -1557,7 +1580,7 @@ class NodeMetaRef
                if(meta == NULL) return 0;
                // Do it
                Inventory *inv = meta->getInventory();
-               const char *name = lua_tostring(L, 2);
+               const char *name = luaL_checkstring(L, 2);
                inventory_get_list_to_lua(inv, name, L);
                return 1;
        }
@@ -1569,7 +1592,7 @@ class NodeMetaRef
                NodeMetadata *meta = getmeta(ref);
                if(meta == NULL) return 0;
                // Do it
-               std::string text = lua_tostring(L, 2);
+               std::string text = luaL_checkstring(L, 2);
                meta->setInventoryDrawSpec(text);
                reportMetadataChange(ref);
                return 0;
@@ -1667,7 +1690,7 @@ class NodeMetaRef
                NodeMetadata *meta = getmeta(ref);
                if(meta == NULL) return 0;
                // Do it
-               std::string name = lua_tostring(L, 2);
+               std::string name = luaL_checkstring(L, 2);
                size_t len = 0;
                const char *s = lua_tolstring(L, 3, &len);
                std::string str(s, len);
@@ -1683,7 +1706,7 @@ class NodeMetaRef
                NodeMetadata *meta = getmeta(ref);
                if(meta == NULL) return 0;
                // Do it
-               std::string name = lua_tostring(L, 2);
+               std::string name = luaL_checkstring(L, 2);
                std::string str = meta->getString(name);
                lua_pushlstring(L, str.c_str(), str.size());
                return 1;
@@ -1939,7 +1962,7 @@ class ObjectRef
                ServerActiveObject *co = getobject(ref);
                if(co == NULL) return 0;
                // itemstring
-               const char *itemstring = lua_tostring(L, 2);
+               const char *itemstring = luaL_checkstring(L, 2);
                infostream<<"ObjectRef::l_add_to_inventory(): id="<<co->getId()
                                <<" itemstring=\""<<itemstring<<"\""<<std::endl;
                // Do it
@@ -1975,7 +1998,7 @@ class ObjectRef
                ServerActiveObject *co = getobject(ref);
                if(co == NULL) return 0;
                // itemstring
-               const char *itemstring = lua_tostring(L, 2);
+               const char *itemstring = luaL_checkstring(L, 2);
                infostream<<"ObjectRef::l_add_to_inventory_later(): id="<<co->getId()
                                <<" itemstring=\""<<itemstring<<"\""<<std::endl;
                // Do it
@@ -2071,7 +2094,7 @@ class ObjectRef
                LuaEntitySAO *co = getluaobject(ref);
                if(co == NULL) return 0;
                // Do it
-               std::string mod = lua_tostring(L, 2);
+               std::string mod = luaL_checkstring(L, 2);
                co->setTextureMod(mod);
                return 0;
        }
@@ -2122,7 +2145,7 @@ class ObjectRef
                ObjectRef *ref = checkobject(L, 1);
                ServerRemotePlayer *player = getplayer(ref);
                if(player == NULL) return 0;
-               const char *name = lua_tostring(L, 2);
+               const char *name = luaL_checkstring(L, 2);
                // Do it
                inventory_set_list_from_lua(&player->inventory, name, L, 3,
                                player->getEnv()->getGameDef(), PLAYER_INVENTORY_SIZE);
@@ -2136,7 +2159,7 @@ class ObjectRef
                ObjectRef *ref = checkobject(L, 1);
                ServerRemotePlayer *player = getplayer(ref);
                if(player == NULL) return 0;
-               const char *name = lua_tostring(L, 2);
+               const char *name = luaL_checkstring(L, 2);
                // Do it
                inventory_get_list_to_lua(&player->inventory, name, L);
                return 1;
@@ -2204,6 +2227,42 @@ class ObjectRef
                return 1;
        }
 
+       // get_look_dir(self)
+       static int l_get_look_dir(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerRemotePlayer *player = getplayer(ref);
+               if(player == NULL) return 0;
+               // Do it
+               float pitch = player->getRadPitch();
+               float yaw = player->getRadYaw();
+               v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
+               push_v3f(L, v);
+               return 1;
+       }
+
+       // get_look_pitch(self)
+       static int l_get_look_pitch(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerRemotePlayer *player = getplayer(ref);
+               if(player == NULL) return 0;
+               // Do it
+               lua_pushnumber(L, player->getRadPitch());
+               return 1;
+       }
+
+       // get_look_yaw(self)
+       static int l_get_look_yaw(lua_State *L)
+       {
+               ObjectRef *ref = checkobject(L, 1);
+               ServerRemotePlayer *player = getplayer(ref);
+               if(player == NULL) return 0;
+               // Do it
+               lua_pushnumber(L, player->getRadYaw());
+               return 1;
+       }
+
 public:
        ObjectRef(ServerActiveObject *object):
                m_object(object)
@@ -2292,6 +2351,9 @@ const luaL_reg ObjectRef::methods[] = {
        method(ObjectRef, inventory_get_list),
        method(ObjectRef, get_wielded_itemstring),
        method(ObjectRef, get_wielded_item),
+       method(ObjectRef, get_look_dir),
+       method(ObjectRef, get_look_pitch),
+       method(ObjectRef, get_look_yaw),
        {0,0}
 };
 
@@ -2441,7 +2503,7 @@ class EnvRef
                // pos
                v3f pos = readFloatPos(L, 2);
                // content
-               const char *name = lua_tostring(L, 3);
+               const char *name = luaL_checkstring(L, 3);
                // Do it
                ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
                env->addActiveObject(obj);
@@ -2459,7 +2521,7 @@ class EnvRef
                // pos
                v3f pos = readFloatPos(L, 2);
                // inventorystring
-               const char *inventorystring = lua_tostring(L, 3);
+               const char *inventorystring = luaL_checkstring(L, 3);
                // Do it
                ServerActiveObject *obj = new ItemSAO(env, pos, inventorystring);
                env->addActiveObject(obj);
@@ -2518,7 +2580,7 @@ class EnvRef
                ServerEnvironment *env = o->m_env;
                if(env == NULL) return 0;
                // Do it
-               const char *name = lua_tostring(L, 2);
+               const char *name = luaL_checkstring(L, 2);
                ServerRemotePlayer *player =
                                static_cast<ServerRemotePlayer*>(env->getPlayer(name));
                if(player == NULL){
@@ -2530,6 +2592,36 @@ class EnvRef
                return 1;
        }
 
+       // EnvRef:get_objects_inside_radius(pos, radius)
+       static int l_get_objects_inside_radius(lua_State *L)
+       {
+               // Get the table insert function
+               lua_getglobal(L, "table");
+               lua_getfield(L, -1, "insert");
+               int table_insert = lua_gettop(L);
+               // Get environemnt
+               EnvRef *o = checkobject(L, 1);
+               ServerEnvironment *env = o->m_env;
+               if(env == NULL) return 0;
+               // Do it
+               v3f pos = readFloatPos(L, 2);
+               float radius = luaL_checknumber(L, 3) * BS;
+               std::set<u16> ids = env->getObjectsInsideRadius(pos, radius);
+               lua_newtable(L);
+               int table = lua_gettop(L);
+               for(std::set<u16>::const_iterator
+                               i = ids.begin(); i != ids.end(); i++){
+                       ServerActiveObject *obj = env->getActiveObject(*i);
+                       // Insert object reference into table
+                       lua_pushvalue(L, table_insert);
+                       lua_pushvalue(L, table);
+                       objectref_get_or_create(L, obj);
+                       if(lua_pcall(L, 2, 0, 0))
+                               script_error(L, "error: %s", lua_tostring(L, -1));
+               }
+               return 1;
+       }
+
        static int gc_object(lua_State *L) {
                EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
                delete o;
@@ -2606,6 +2698,7 @@ const luaL_reg EnvRef::methods[] = {
        method(EnvRef, add_firefly),
        method(EnvRef, get_meta),
        method(EnvRef, get_player_by_name),
+       method(EnvRef, get_objects_inside_radius),
        {0,0}
 };
 
@@ -2672,6 +2765,14 @@ bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
 {
        ModNameStorer modnamestorer(L, modname);
 
+       if(!string_allowed(modname, "abcdefghijklmnopqrstuvwxyz"
+                       "0123456789_")){
+               errorstream<<"Error loading mod \""<<modname
+                               <<"\": modname does not follow naming conventions: "
+                               <<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
+               return false;
+       }
+       
        bool success = false;
 
        try{