예제 #1
0
// find_nodes_in_area(minp, maxp, nodenames) -> list of positions
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
{
	GET_ENV_PTR;

	INodeDefManager *ndef = getServer(L)->ndef();
	v3s16 minp = read_v3s16(L, 1);
	v3s16 maxp = read_v3s16(L, 2);
	std::set<content_t> filter;
	if(lua_istable(L, 3)) {
		int table = 3;
		lua_pushnil(L);
		while(lua_next(L, table) != 0) {
			// key at index -2 and value at index -1
			luaL_checktype(L, -1, LUA_TSTRING);
			ndef->getIds(lua_tostring(L, -1), filter);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
		}
	} else if(lua_isstring(L, 3)) {
		ndef->getIds(lua_tostring(L, 3), filter);
	}

	std::map<content_t, u16> individual_count;

	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().getNodeNoEx(p).getContent();
				if (filter.count(c) != 0) {
					push_v3s16(L, p);
					lua_rawseti(L, -2, ++i);
					individual_count[c]++;
				}
	}
	lua_newtable(L);
	for (std::set<content_t>::iterator it = filter.begin();
			it != filter.end(); ++it) {
		lua_pushnumber(L, individual_count[*it]);
		lua_setfield(L, -2, ndef->get(*it).name.c_str());
	}
	return 2;
}
예제 #2
0
// minetest.find_nodes_in_area(minp, maxp, nodenames) -> list of positions
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
{
	GET_ENV_PTR;

	INodeDefManager *ndef = getServer(L)->ndef();
	v3s16 minp = read_v3s16(L, 1);
	v3s16 maxp = read_v3s16(L, 2);
	std::set<content_t> filter;
	if(lua_istable(L, 3)){
		int table = 3;
		lua_pushnil(L);
		while(lua_next(L, table) != 0){
			// key at index -2 and value at index -1
			luaL_checktype(L, -1, LUA_TSTRING);
			ndef->getIds(lua_tostring(L, -1), filter);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
		}
	} else if(lua_isstring(L, 3)){
		ndef->getIds(lua_tostring(L, 3), filter);
	}

	// Get the table insert function
	lua_getglobal(L, "table");
	lua_getfield(L, -1, "insert");
	int table_insert = lua_gettop(L);

	lua_newtable(L);
	int table = lua_gettop(L);
	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().getNodeNoEx(p).getContent();
		if(filter.count(c) != 0){
			lua_pushvalue(L, table_insert);
			lua_pushvalue(L, table);
			push_v3s16(L, p);
			if(lua_pcall(L, 2, 0, 0))
				script_error(L, "error: %s", lua_tostring(L, -1));
		}
	}
	return 1;
}
예제 #3
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// get_node_level(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_node_level(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos = read_v3s16(L, 1);
	MapNode n = env->getMap().getNodeNoEx(pos);
	lua_pushnumber(L, n.getLevel(env->getGameDef()->ndef()));
	return 1;
}
예제 #4
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// get_meta(pos)
int ModApiEnvMod::l_get_meta(lua_State *L)
{
	GET_ENV_PTR;

	// Do it
	v3s16 p = read_v3s16(L, 1);
	NodeMetaRef::create(L, p, env);
	return 1;
}
예제 #5
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// get_node_timer(pos)
int ModApiEnvMod::l_get_node_timer(lua_State *L)
{
	GET_ENV_PTR;

	// Do it
	v3s16 p = read_v3s16(L, 1);
	NodeTimerRef::create(L, p, env);
	return 1;
}
예제 #6
0
// LuaVoxelManip()
// Creates an LuaVoxelManip and leaves it on top of stack
int LuaVoxelManip::create_object(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	Environment *env = getEnv(L);
	if (!env)
		return 0;

	Map *map = &(env->getMap());
	LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ?
		new LuaVoxelManip(map, read_v3s16(L, 1), read_v3s16(L, 2)) :
		new LuaVoxelManip(map);

	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}
예제 #7
0
// spawn_tree(pos, treedef)
int ModApiEnvMod::l_spawn_tree(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 p0 = read_v3s16(L, 1);

	treegen::TreeDef tree_def;
	std::string trunk,leaves,fruit;
	INodeDefManager *ndef = env->getGameDef()->ndef();

	if(lua_istable(L, 2))
	{
		getstringfield(L, 2, "axiom", tree_def.initial_axiom);
		getstringfield(L, 2, "rules_a", tree_def.rules_a);
		getstringfield(L, 2, "rules_b", tree_def.rules_b);
		getstringfield(L, 2, "rules_c", tree_def.rules_c);
		getstringfield(L, 2, "rules_d", tree_def.rules_d);
		getstringfield(L, 2, "trunk", trunk);
		tree_def.trunknode=ndef->getId(trunk);
		getstringfield(L, 2, "leaves", leaves);
		tree_def.leavesnode=ndef->getId(leaves);
		tree_def.leaves2_chance=0;
		getstringfield(L, 2, "leaves2", leaves);
		if (leaves !="")
		{
			tree_def.leaves2node=ndef->getId(leaves);
			getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance);
		}
		getintfield(L, 2, "angle", tree_def.angle);
		getintfield(L, 2, "iterations", tree_def.iterations);
		if (!getintfield(L, 2, "random_level", tree_def.iterations_random_level))
			tree_def.iterations_random_level = 0;
		getstringfield(L, 2, "trunk_type", tree_def.trunk_type);
		getboolfield(L, 2, "thin_branches", tree_def.thin_branches);
		tree_def.fruit_chance=0;
		getstringfield(L, 2, "fruit", fruit);
		if (fruit != "")
		{
			tree_def.fruitnode=ndef->getId(fruit);
			getintfield(L, 2, "fruit_chance",tree_def.fruit_chance);
		}
		tree_def.explicit_seed = getintfield(L, 2, "seed", tree_def.seed);
	}
	else
		return 0;

	treegen::error e;
	if ((e = treegen::spawn_ltree (env, p0, ndef, tree_def)) != treegen::SUCCESS) {
		if (e == treegen::UNBALANCED_BRACKETS) {
			luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket");
		} else {
			luaL_error(L, "spawn_tree(): unknown error");
		}
	}

	return 1;
}
예제 #8
0
// 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)
{
	GET_ENV_PTR;

	EmergeCompletionCallback callback = NULL;
	ScriptCallbackState *state = NULL;

	EmergeManager *emerge = getServer(L)->getEmergeManager();

	v3s16 bpmin = getNodeBlockPos(read_v3s16(L, 1));
	v3s16 bpmax = getNodeBlockPos(read_v3s16(L, 2));
	sortBoxVerticies(bpmin, bpmax);

	size_t num_blocks = VoxelArea(bpmin, bpmax).getVolume();
	assert(num_blocks != 0);

	if (lua_isfunction(L, 3)) {
		callback = LuaEmergeAreaCallback;

		lua_pushvalue(L, 3);
		int callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);

		lua_pushvalue(L, 4);
		int args_ref = luaL_ref(L, LUA_REGISTRYINDEX);

		state = new ScriptCallbackState;
		state->script       = getServer(L)->getScriptIface();
		state->callback_ref = callback_ref;
		state->args_ref     = args_ref;
		state->refcount     = num_blocks;
		state->origin       = getScriptApiBase(L)->getOrigin();
	}

	for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
	for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
	for (s16 x = bpmin.X; x <= bpmax.X; x++) {
		emerge->enqueueBlockEmergeEx(v3s16(x, y, z), PEER_ID_INEXISTENT,
			BLOCK_EMERGE_ALLOW_GEN | BLOCK_EMERGE_FORCE_QUEUE, callback, state);
	}

	return 0;
}
예제 #9
0
// get_node(pos)
// pos = {x=num, y=num, z=num}
int ModApiClient::l_get_node(lua_State *L)
{
	// pos
	v3s16 pos = read_v3s16(L, 1);
	// Do it
	bool pos_ok;
	MapNode n = getClient(L)->getNode(pos, &pos_ok);
	// Return node
	pushnode(L, n, getClient(L)->ndef());
	return 1;
}
예제 #10
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// remove_node(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_remove_node(lua_State *L)
{
	GET_ENV_PTR;

	// parameters
	v3s16 pos = read_v3s16(L, 1);
	// Do it
	bool succeeded = env->removeNode(pos);
	lua_pushboolean(L, succeeded);
	return 1;
}
예제 #11
0
int LuaVoxelManip::l_get_node_at(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	GET_ENV_PTR;

	LuaVoxelManip *o = checkobject(L, 1);
	v3s16 pos        = read_v3s16(L, 2);

	pushnode(L, o->vm->getNodeNoExNoEmerge(pos), env->getGameDef()->ndef());
	return 1;
}
예제 #12
0
// get_node_level(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_node_level(lua_State *L)
{
	Environment *env = getEnv(L);
	if (!env) {
		return 0;
	}

	v3s16 pos = read_v3s16(L, 1);
	MapNode n = env->getMap().getNodeNoEx(pos);
	lua_pushnumber(L, n.getLevel(env->getGameDef()->ndef()));
	return 1;
}
예제 #13
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// get_node(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_node(lua_State *L)
{
	GET_ENV_PTR;

	// pos
	v3s16 pos = read_v3s16(L, 1);
	// Do it
	MapNode n = env->getMap().getNodeNoEx(pos);
	// Return node
	pushnode(L, n, env->getGameDef()->ndef());
	return 1;
}
예제 #14
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// find_path(pos1, pos2, searchdistance,
//     max_jump, max_drop, algorithm) -> table containing path
int ModApiEnvMod::l_find_path(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos1                  = read_v3s16(L, 1);
	v3s16 pos2                  = read_v3s16(L, 2);
	unsigned int searchdistance = luaL_checkint(L, 3);
	unsigned int max_jump       = luaL_checkint(L, 4);
	unsigned int max_drop       = luaL_checkint(L, 5);
	algorithm algo              = A_PLAIN_NP;
	if (!lua_isnil(L, 6)) {
		std::string algorithm = luaL_checkstring(L,6);

		if (algorithm == "A*")
			algo = A_PLAIN;

		if (algorithm == "Dijkstra")
			algo = DIJKSTRA;
	}

	std::vector<v3s16> path =
			get_Path(env,pos1,pos2,searchdistance,max_jump,max_drop,algo);

	if (path.size() > 0)
	{
		lua_newtable(L);
		int top = lua_gettop(L);
		unsigned int index = 1;
		for (std::vector<v3s16>::iterator i = path.begin(); i != path.end();i++)
		{
			lua_pushnumber(L,index);
			push_v3s16(L, *i);
			lua_settable(L, top);
			index++;
		}
		return 1;
	}

	return 0;
}
예제 #15
0
int LuaVoxelManip::l_set_node_at(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	GET_ENV_PTR;

	LuaVoxelManip *o = checkobject(L, 1);
	v3s16 pos        = read_v3s16(L, 2);
	MapNode n        = readnode(L, 3, env->getGameDef()->ndef());

	o->vm->setNodeNoEmerge(pos, n);

	return 0;
}
예제 #16
0
파일: l_noise.cpp 프로젝트: 0151n/minetest
// LuaPerlinNoiseMap(np, size)
// Creates an LuaPerlinNoiseMap and leaves it on top of stack
int LuaPerlinNoiseMap::create_object(lua_State *L)
{
	NoiseParams *np = read_noiseparams(L, 1);
	if (!np)
		return 0;
	v3s16 size = read_v3s16(L, 2);

	LuaPerlinNoiseMap *o = new LuaPerlinNoiseMap(np, 0, size);
	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}
예제 #17
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// add_node_level(pos, level)
// pos = {x=num, y=num, z=num}
// level: 0..63
int ModApiEnvMod::l_add_node_level(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos = read_v3s16(L, 1);
	u8 level = 1;
	if(lua_isnumber(L, 2))
		level = lua_tonumber(L, 2);
	MapNode n = env->getMap().getNodeNoEx(pos);
	lua_pushnumber(L, n.addLevel(env->getGameDef()->ndef(), level));
	env->setNode(pos, n);
	return 1;
}
예제 #18
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// set_node(pos, node)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_set_node(lua_State *L)
{
	GET_ENV_PTR;

	INodeDefManager *ndef = env->getGameDef()->ndef();
	// parameters
	v3s16 pos = read_v3s16(L, 1);
	MapNode n = readnode(L, 2, ndef);
	// Do it
	bool succeeded = env->setNode(pos, n);
	lua_pushboolean(L, succeeded);
	return 1;
}
예제 #19
0
파일: l_env.cpp 프로젝트: EXio4/minetest
// find_path(pos1, pos2, searchdistance,
//     max_jump, max_drop, algorithm) -> table containing path
int ModApiEnvMod::l_find_path(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos1                  = read_v3s16(L, 1);
	v3s16 pos2                  = read_v3s16(L, 2);
	unsigned int searchdistance = luaL_checkint(L, 3);
	unsigned int max_jump       = luaL_checkint(L, 4);
	unsigned int max_drop       = luaL_checkint(L, 5);
	PathAlgorithm algo          = PA_PLAIN_NP;
	if (!lua_isnil(L, 6)) {
		std::string algorithm = luaL_checkstring(L,6);

		if (algorithm == "A*")
			algo = PA_PLAIN;

		if (algorithm == "Dijkstra")
			algo = PA_DIJKSTRA;
	}

	std::vector<v3s16> path = get_path(env, pos1, pos2,
		searchdistance, max_jump, max_drop, algo);

	if (!path.empty()) {
		lua_newtable(L);
		int top = lua_gettop(L);
		unsigned int index = 1;
		for (const v3s16 &i : path) {
			lua_pushnumber(L,index);
			push_v3s16(L, i);
			lua_settable(L, top);
			index++;
		}
		return 1;
	}

	return 0;
}
예제 #20
0
int LuaPerlinNoiseMap::l_getMapSlice(lua_State *L)
{
    NO_MAP_LOCK_REQUIRED;

    LuaPerlinNoiseMap *o = checkobject(L, 1);
    v3s16 slice_offset   = read_v3s16(L, 2);
    v3s16 slice_size     = read_v3s16(L, 3);
    bool use_buffer      = lua_istable(L, 4);

    Noise *n = o->noise;

    if (use_buffer)
        lua_pushvalue(L, 3);
    else
        lua_newtable(L);

    write_array_slice_float(L, lua_gettop(L), n->result,
                            v3u16(n->sx, n->sy, n->sz),
                            v3u16(slice_offset.X, slice_offset.Y, slice_offset.Z),
                            v3u16(slice_size.X, slice_size.Y, slice_size.Z));

    return 1;
}
예제 #21
0
// place_schematic(p, schematic, rotation, replacement)
int ModApiMapgen::l_place_schematic(lua_State *L)
{
	DecoSchematic dschem;

	Map *map = &(getEnv(L)->getMap());
	INodeDefManager *ndef = getServer(L)->getNodeDefManager();

	v3s16 p = read_v3s16(L, 1);
	if (!read_schematic(L, 2, &dschem, getServer(L)))
		return 0;

	int rot = ROTATE_0;
	if (lua_isstring(L, 3))
		string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3)));

	dschem.rotation = (Rotation)rot;

	if (lua_istable(L, 4)) {
		lua_pushnil(L);
		while (lua_next(L, 4) != 0) {
			// key at index -2 and value at index -1
			lua_rawgeti(L, -1, 1);
			std::string replace_from = lua_tostring(L, -1);
			lua_pop(L, 1);
			lua_rawgeti(L, -1, 2);
			std::string replace_to = lua_tostring(L, -1);
			lua_pop(L, 1);
			dschem.replacements[replace_from] = replace_to;
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
		}
	}

	bool force_placement = true;
	if (lua_isboolean(L, 5))
		force_placement = lua_toboolean(L, 5);

	if (!dschem.filename.empty()) {
		if (!dschem.loadSchematicFile()) {
			errorstream << "place_schematic: failed to load schematic file '"
				<< dschem.filename << "'" << std::endl;
			return 0;
		}
		dschem.resolveNodeNames(ndef);
	}

	dschem.placeStructure(map, p, force_placement);

	return 1;
}
예제 #22
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// find_nodes_in_area(minp, maxp, nodenames) -> list of positions
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
{
	GET_ENV_PTR;

	INodeDefManager *ndef = getServer(L)->ndef();
	v3s16 minp = read_v3s16(L, 1);
	v3s16 maxp = read_v3s16(L, 2);
	std::set<content_t> filter;
	if(lua_istable(L, 3)){
		int table = 3;
		lua_pushnil(L);
		while(lua_next(L, table) != 0){
			// key at index -2 and value at index -1
			luaL_checktype(L, -1, LUA_TSTRING);
			ndef->getIds(lua_tostring(L, -1), filter);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
		}
	} else if(lua_isstring(L, 3)){
		ndef->getIds(lua_tostring(L, 3), filter);
	}

	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().getNodeNoEx(p).getContent();
		if(filter.count(c) != 0) {
			push_v3s16(L, p);
			lua_rawseti(L, -2, ++i);
		}
	}
	return 1;
}
예제 #23
0
// rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
int ModApiBasic::l_rollback_get_last_node_actor(lua_State *L)
{
	v3s16 p = read_v3s16(L, 1);
	int range = luaL_checknumber(L, 2);
	int seconds = luaL_checknumber(L, 3);
	Server *server = getServer(L);
	IRollbackManager *rollback = server->getRollbackManager();
	v3s16 act_p;
	int act_seconds = 0;
	std::string actor = rollback->getLastNodeActor(p, range, seconds, &act_p, &act_seconds);
	lua_pushstring(L, actor.c_str());
	push_v3s16(L, act_p);
	lua_pushnumber(L, act_seconds);
	return 3;
}
예제 #24
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// get_perlin_map(noiseparams, size)
// returns world-specific PerlinNoiseMap
int ModApiEnvMod::l_get_perlin_map(lua_State *L)
{
	GET_ENV_PTR;

	NoiseParams *np = read_noiseparams(L, 1);
	if (!np)
		return 0;
	v3s16 size = read_v3s16(L, 2);

	int seed = (int)(env->getServerMap().getSeed());
	LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(np, seed, size);
	*(void **)(lua_newuserdata(L, sizeof(void *))) = n;
	luaL_getmetatable(L, "PerlinNoiseMap");
	lua_setmetatable(L, -2);
	return 1;
}
예제 #25
0
// get_perlin_map(noiseparams, size)
// returns world-specific PerlinNoiseMap
int ModApiEnvMod::l_get_perlin_map(lua_State *L)
{
	GET_ENV_PTR_NO_MAP_LOCK;

	NoiseParams np;
	if (!read_noiseparams(L, 1, &np))
		return 0;
	v3s16 size = read_v3s16(L, 2);

	s32 seed = (s32)(env->getServerMap().getSeed());
	LuaPerlinNoiseMap *n = new LuaPerlinNoiseMap(&np, seed, size);
	*(void **)(lua_newuserdata(L, sizeof(void *))) = n;
	luaL_getmetatable(L, "PerlinNoiseMap");
	lua_setmetatable(L, -2);
	return 1;
}
예제 #26
0
파일: l_env.cpp 프로젝트: malmrose/minetest
// spawn_tree(pos, treedef)
int ModApiEnvMod::l_spawn_tree(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 p0 = read_v3s16(L, 1);

	treegen::TreeDef tree_def;
	std::string trunk,leaves,fruit;
	INodeDefManager *ndef = env->getGameDef()->ndef();

	if(lua_istable(L, 2))
	{
		getstringfield(L, 2, "axiom", tree_def.initial_axiom);
		getstringfield(L, 2, "rules_a", tree_def.rules_a);
		getstringfield(L, 2, "rules_b", tree_def.rules_b);
		getstringfield(L, 2, "rules_c", tree_def.rules_c);
		getstringfield(L, 2, "rules_d", tree_def.rules_d);
		getstringfield(L, 2, "trunk", trunk);
		tree_def.trunknode=ndef->getId(trunk);
		getstringfield(L, 2, "leaves", leaves);
		tree_def.leavesnode=ndef->getId(leaves);
		tree_def.leaves2_chance=0;
		getstringfield(L, 2, "leaves2", leaves);
		if (leaves !="")
		{
			tree_def.leaves2node=ndef->getId(leaves);
			getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance);
		}
		getintfield(L, 2, "angle", tree_def.angle);
		getintfield(L, 2, "iterations", tree_def.iterations);
		getintfield(L, 2, "random_level", tree_def.iterations_random_level);
		getstringfield(L, 2, "trunk_type", tree_def.trunk_type);
		getboolfield(L, 2, "thin_branches", tree_def.thin_branches);
		tree_def.fruit_chance=0;
		getstringfield(L, 2, "fruit", fruit);
		if (fruit != "")
		{
			tree_def.fruitnode=ndef->getId(fruit);
			getintfield(L, 2, "fruit_chance",tree_def.fruit_chance);
		}
		getintfield(L, 2, "seed", tree_def.seed);
	}
	else
		return 0;
	treegen::spawn_ltree (env, p0, ndef, tree_def);
	return 1;
}
예제 #27
0
파일: l_env.cpp 프로젝트: EXio4/minetest
// 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)
{
	Environment *env = getEnv(L);
	if (!env) {
		return 0;
	}

	INodeDefManager *ndef = getGameDef(L)->ndef();
	v3s16 pos = read_v3s16(L, 1);
	int radius = luaL_checkinteger(L, 2);
	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(lua_tostring(L, -1), filter);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
		}
	} else if (lua_isstring(L, 3)) {
		ndef->getIds(lua_tostring(L, 3), filter);
	}

	int start_radius = (lua_toboolean(L, 4)) ? 0 : 1;

#ifndef SERVER
	// Client API limitations
	if (getClient(L) &&
			getClient(L)->checkCSMFlavourLimit(CSMFlavourLimit::CSM_FL_LOOKUP_NODES)) {
		radius = std::max<int>(radius, getClient(L)->getCSMNodeRangeLimit());
	}
#endif

	for (int d = start_radius; d <= radius; d++) {
		std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
		for (const v3s16 &i : list) {
			v3s16 p = pos + i;
			content_t c = env->getMap().getNodeNoEx(p).getContent();
			if (CONTAINS(filter, c)) {
				push_v3s16(L, p);
				return 1;
			}
		}
	}
	return 0;
}
예제 #28
0
// get_node_or_nil(pos)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_get_node_or_nil(lua_State *L)
{
	GET_ENV_PTR;

	// pos
	v3s16 pos = read_v3s16(L, 1);
	// Do it
	bool pos_ok;
	MapNode n = env->getMap().getNodeNoEx(pos, &pos_ok);
	if (pos_ok) {
		// Return node
		pushnode(L, n, env->getGameDef()->ndef());
	} else {
		lua_pushnil(L);
	}
	return 1;
}
예제 #29
0
파일: l_env.cpp 프로젝트: nsd2/freeminer
// freeze_melt(pos, direction)
// pos = {x=num, y=num, z=num}
// direction: -1 (freeze), 1 (melt)
int ModApiEnvMod::l_freeze_melt(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos = read_v3s16(L, 1);
	int direction = 1;
	if(lua_isnumber(L, 2))
		direction = lua_tonumber(L, 2);
	MapNode n = env->getMap().getNodeNoEx(pos);
	if(n.getContent() == CONTENT_IGNORE){
		lua_pushnumber(L, 0);
		return 1;
	}
	lua_pushnumber(L, n.freeze_melt(env->getGameDef()->ndef(), direction));
	env->setNode(pos, n);
	return 1;
}
예제 #30
0
파일: l_env.cpp 프로젝트: nsd2/freeminer
// set_node_level(pos, level)
// pos = {x=num, y=num, z=num}
// level: 0..63
int ModApiEnvMod::l_set_node_level(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos = read_v3s16(L, 1);
	u8 level = 1;
	if(lua_isnumber(L, 2))
		level = lua_tonumber(L, 2);
	MapNode n = env->getMap().getNodeNoEx(pos);
	if(n.getContent() == CONTENT_IGNORE){
		lua_pushnumber(L, 0);
		return 1;
	}
	lua_pushnumber(L, n.setLevel(env->getGameDef()->ndef(), level));
	env->setNode(pos, n);
	return 1;
}