Beispiel #1
0
void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
{
	lua_State* L = getStack();

	lua_newtable(L);
	if(pointed.type == POINTEDTHING_NODE)
	{
		lua_pushstring(L, "node");
		lua_setfield(L, -2, "type");
		push_v3s16(L, pointed.node_undersurface);
		lua_setfield(L, -2, "under");
		push_v3s16(L, pointed.node_abovesurface);
		lua_setfield(L, -2, "above");
	}
	else if(pointed.type == POINTEDTHING_OBJECT)
	{
		lua_pushstring(L, "object");
		lua_setfield(L, -2, "type");
		objectrefGet(L, pointed.object_id);
		lua_setfield(L, -2, "ref");
	}
	else
	{
		lua_pushstring(L, "nothing");
		lua_setfield(L, -2, "type");
	}
}
Beispiel #2
0
int LuaVoxelManip::l_get_emerged_area(lua_State *L)
{
	LuaVoxelManip *o = checkobject(L, 1);

	push_v3s16(L, o->vm->m_area.MinEdge);
	push_v3s16(L, o->vm->m_area.MaxEdge);

	return 2;
}
Beispiel #3
0
void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
	u32 blockseed)
{
	SCRIPTAPI_PRECHECKHEADER

	// Get core.registered_on_generateds
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_generateds");
	// Call callbacks
	push_v3s16(L, minp);
	push_v3s16(L, maxp);
	lua_pushnumber(L, blockseed);
	runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
}
Beispiel #4
0
// Return number of accepted items to be put
int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
		const std::string &listname, int index, ItemStack &stack,
		ServerActiveObject *player)
{
	SCRIPTAPI_PRECHECKHEADER

	INodeDefManager *ndef = getServer()->ndef();

	// If node doesn't exist, we don't know what callback to call
	MapNode node = getEnv()->getMap().getNodeNoEx(p);
	if (node.getContent() == CONTENT_IGNORE)
		return 0;

	// Push callback function on stack
	std::string nodename = ndef->get(node).name;
	if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put"))
		return stack.count;

	// Call function(pos, listname, index, stack, player)
	push_v3s16(L, p);                    // pos
	lua_pushstring(L, listname.c_str()); // listname
	lua_pushinteger(L, index + 1);       // index
	LuaItemStack::create(L, stack);      // stack
	objectrefGetOrCreate(L, player);     // player
	if (lua_pcall(L, 5, 1, m_errorhandler))
		scriptError();
	if(!lua_isnumber(L, -1))
		throw LuaError("allow_metadata_inventory_put should"
				" return a number, guilty node: " + nodename);
	int num = luaL_checkinteger(L, -1);
	lua_pop(L, 1); // Pop integer
	return num;
}
Beispiel #5
0
// 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_STAR;
	if (!lua_isnil(L, 6)) {
		std::string algorithm = luaL_checkstring(L,6);
	}

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

	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;
}
Beispiel #6
0
void ScriptApiNode::node_on_receive_fields(v3s16 p,
		const std::string &formname,
		const std::map<std::string, std::string> &fields,
		ServerActiveObject *sender)
{
	SCRIPTAPI_PRECHECKHEADER

	INodeDefManager *ndef = getServer()->ndef();

	// If node doesn't exist, we don't know what callback to call
	MapNode node = getEnv()->getMap().getNodeNoEx(p);
	if (node.getContent() == CONTENT_IGNORE)
		return;

	// Push callback function on stack
	if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields"))
		return;

	// Call function
	push_v3s16(L, p);                    // pos
	lua_pushstring(L, formname.c_str()); // formname
	lua_newtable(L);                     // fields
	std::map<std::string, std::string>::const_iterator it;
	for (it = fields.begin(); it != fields.end(); it++){
		const std::string &name = it->first;
		const std::string &value = it->second;
		lua_pushstring(L, name.c_str());
		lua_pushlstring(L, value.c_str(), value.size());
		lua_settable(L, -3);
	}
	objectrefGetOrCreate(sender);        // player
	if (lua_pcall(L, 4, 0, m_errorhandler))
		scriptError();
}
Beispiel #7
0
// Report moved items
void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
		const std::string &from_list, int from_index,
		const std::string &to_list, int to_index,
		int count, ServerActiveObject *player)
{
	SCRIPTAPI_PRECHECKHEADER

	lua_pushcfunction(L, script_error_handler);
	int errorhandler = lua_gettop(L);

	INodeDefManager *ndef = getServer()->ndef();

	// If node doesn't exist, we don't know what callback to call
	MapNode node = getEnv()->getMap().getNodeNoEx(p);
	if(node.getContent() == CONTENT_IGNORE)
		return;

	// Push callback function on stack
	if(!getItemCallback(ndef->get(node).name.c_str(),
			"on_metadata_inventory_move"))
		return;

	// function(pos, from_list, from_index, to_list, to_index, count, player)
	push_v3s16(L, p);                     // pos
	lua_pushstring(L, from_list.c_str()); // from_list
	lua_pushinteger(L, from_index + 1);   // from_index
	lua_pushstring(L, to_list.c_str());   // to_list
	lua_pushinteger(L, to_index + 1);     // to_index
	lua_pushinteger(L, count);            // count
	objectrefGetOrCreate(player);         // player
	if(lua_pcall(L, 7, 0, errorhandler))
		scriptError();
	lua_pop(L, 1); // Pop error handler
}
Beispiel #8
0
// Report taken items
void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
		const std::string &listname, int index, ItemStack &stack,
		ServerActiveObject *player)
{
	SCRIPTAPI_PRECHECKHEADER

	lua_pushcfunction(L, script_error_handler);
	int errorhandler = lua_gettop(L);

	INodeDefManager *ndef = getServer()->ndef();

	// If node doesn't exist, we don't know what callback to call
	MapNode node = getEnv()->getMap().getNodeNoEx(p);
	if(node.getContent() == CONTENT_IGNORE)
		return;

	// Push callback function on stack
	if(!getItemCallback(ndef->get(node).name.c_str(),
			"on_metadata_inventory_take"))
		return;

	// Call function(pos, listname, index, stack, player)
	push_v3s16(L, p);                    // pos
	lua_pushstring(L, listname.c_str()); // listname
	lua_pushinteger(L, index + 1);       // index
	LuaItemStack::create(L, stack);      // stack
	objectrefGetOrCreate(player);        // player
	if(lua_pcall(L, 5, 0, errorhandler))
		scriptError();
	lua_pop(L, 1); // Pop error handler
}
Beispiel #9
0
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
		u32 active_object_count, u32 active_object_count_wider)
{
	GameScripting *scriptIface = env->getScriptIface();
	scriptIface->realityCheck();

	lua_State *L = scriptIface->getStack();
	assert(lua_checkstack(L, 20));
	StackUnroller stack_unroller(L);

	// Get minetest.registered_abms
	lua_getglobal(L, "minetest");
	lua_getfield(L, -1, "registered_abms");
	luaL_checktype(L, -1, LUA_TTABLE);
	int registered_abms = lua_gettop(L);

	// Get minetest.registered_abms[m_id]
	lua_pushnumber(L, m_id);
	lua_gettable(L, registered_abms);
	if(lua_isnil(L, -1))
		assert(0);

	// Call action
	luaL_checktype(L, -1, LUA_TTABLE);
	lua_getfield(L, -1, "action");
	luaL_checktype(L, -1, LUA_TFUNCTION);
	push_v3s16(L, p);
	pushnode(L, n, env->getGameDef()->ndef());
	lua_pushnumber(L, active_object_count);
	lua_pushnumber(L, active_object_count_wider);
	if(lua_pcall(L, 4, 0, 0))
		script_error(L, "error: %s", lua_tostring(L, -1));
}
Beispiel #10
0
int LuaVoxelManip::l_read_from_map(lua_State *L)
{
	LuaVoxelManip *o = checkobject(L, 1);
	ManualMapVoxelManipulator *vm = o->vm;
	
	v3s16 bp1 = getNodeBlockPos(read_v3s16(L, 2));
	v3s16 bp2 = getNodeBlockPos(read_v3s16(L, 3));
	sortBoxVerticies(bp1, bp2);
	
	vm->initialEmerge(bp1, bp2);
	
	push_v3s16(L, vm->m_area.MinEdge);
	push_v3s16(L, vm->m_area.MaxEdge);
	
	return 2;
}
Beispiel #11
0
int LuaMinimap::l_get_pos(lua_State *L)
{
	LuaMinimap *ref = checkobject(L, 1);
	Minimap *m = getobject(ref);

	push_v3s16(L, m->getPos());
	return 1;
}
Beispiel #12
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);
	sortBoxVerticies(minp, maxp);

	v3s16 cube = maxp - minp + 1;

	/* Limit for too large areas, assume default values
	 * and give tolerances of 1 node on each side
	 * (chunksize * MAP_BLOCKSIZE + 2)^3 = 551368
	*/
	if ((u64)cube.X * (u64)cube.Y * (u64)cube.Z > 551368) {
		luaL_error(L, "find_nodes_in_area(): area volume"
				" exceeds allowed value of 551368");
		return 0;
	}

	std::set<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);
	}

	std::unordered_map<content_t, u32> 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>::const_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;
}
Beispiel #13
0
int LuaVoxelManip::l_read_from_map(lua_State *L)
{
	MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2));
	v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3));
	sortBoxVerticies(bp1, bp2);

	vm->initialEmerge(bp1, bp2);

	push_v3s16(L, vm->m_area.MinEdge);
	push_v3s16(L, vm->m_area.MaxEdge);

	return 2;
}
Beispiel #14
0
void ScriptApiNode::node_falling_update_single(v3s16 p)
{
	SCRIPTAPI_PRECHECKHEADER

	lua_getglobal(L, "nodeupdate_single");
	push_v3s16(L, p);
	if (lua_pcall(L, 1, 0, m_errorhandler))
		scriptError();
}
Beispiel #15
0
static void push_area(lua_State *L, const Area *a,
		bool include_borders, bool include_data)
{
	if (!include_borders && !include_data) {
		lua_pushboolean(L, true);
		return;
	}
	lua_newtable(L);
	if (include_borders) {
		push_v3s16(L, a->minedge);
		lua_setfield(L, -2, "min");
		push_v3s16(L, a->maxedge);
		lua_setfield(L, -2, "max");
	}
	if (include_data) {
		lua_pushlstring(L, a->data.c_str(), a->data.size());
		lua_setfield(L, -2, "data");
	}
}
Beispiel #16
0
void ScriptApiNode::node_falling_update_single(v3s16 p)
{
	SCRIPTAPI_PRECHECKHEADER

	int error_handler = PUSH_ERROR_HANDLER(L);

	lua_getglobal(L, "nodeupdate_single");
	push_v3s16(L, p);
	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
	lua_pop(L, 1);  // Pop error handler
}
Beispiel #17
0
void ScriptApiNode::node_drop(v3s16 p, int fast = 0)
{
	SCRIPTAPI_PRECHECKHEADER

	lua_pushcfunction(L, script_error_handler);
	int errorhandler = lua_gettop(L);

	lua_getglobal(L, "node_drop");
	push_v3s16(L, p);
	lua_pushinteger(L, fast);
	PCALL_RES(lua_pcall(L, 2, 0, errorhandler));
	lua_pop(L, 1); // Pop error handler
}
Beispiel #18
0
void ScriptApiNode::node_falling_update_single(v3s16 p)
{
	SCRIPTAPI_PRECHECKHEADER

	lua_pushcfunction(L, script_error_handler);
	int errorhandler = lua_gettop(L);

	lua_getglobal(L, "nodeupdate_single");
	push_v3s16(L, p);
	if(lua_pcall(L, 1, 0, errorhandler))
		scriptError();
	lua_pop(L, 1); // Pop error handler
}
Beispiel #19
0
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
		u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate)
{
	GameScripting *scriptIface = env->getScriptIface();
	auto _script_lock = RecursiveMutexAutoLock(scriptIface->m_luastackmutex, std::try_to_lock);
	if (!_script_lock.owns_lock()) {
		return;
	}
	scriptIface->realityCheck();

	lua_State *L = scriptIface->getStack();
	sanity_check(lua_checkstack(L, 20));
	StackUnroller stack_unroller(L);

	int error_handler = PUSH_ERROR_HANDLER(L);

	// Get registered_abms
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_abms");
	luaL_checktype(L, -1, LUA_TTABLE);
	lua_remove(L, -2); // Remove core

	// Get registered_abms[m_id]
	lua_pushnumber(L, m_id);
	lua_gettable(L, -2);
	if(lua_isnil(L, -1))
		//FATAL_ERROR("");
		return;
	lua_remove(L, -2); // Remove registered_abms

	scriptIface->setOriginFromTable(-1);

	// Call action
	luaL_checktype(L, -1, LUA_TTABLE);
	lua_getfield(L, -1, "action");
	luaL_checktype(L, -1, LUA_TFUNCTION);
	lua_remove(L, -2); // Remove registered_abms[m_id]
	push_v3s16(L, p);
	pushnode(L, n, env->getGameDef()->ndef());
	lua_pushnumber(L, active_object_count);
	lua_pushnumber(L, active_object_count_wider);
	pushnode(L, neighbor, env->getGameDef()->ndef());
	lua_pushboolean(L, activate);

	int result = lua_pcall(L, 6, 0, error_handler);
	if (result)
		scriptIface->scriptError(result, "LuaABM::trigger");

	lua_pop(L, 1); // Pop error handler
}
Beispiel #20
0
// find_nodes_in_area_under_air(minp, maxp, nodenames) -> list of positions
// nodenames: e.g. {"ignore", "group:tree"} or "default:dirt"
int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
{
	/* Note: A similar but generalized (and therefore slower) version of this
	 * function could be created -- e.g. find_nodes_in_area_under -- which
	 * would accept a node name (or ID?) or list of names that the "above node"
	 * should be.
	 * TODO
	 */

	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 z = minp.Z; z <= maxp.Z; z++) {
		s16 y = minp.Y;
		v3s16 p(x, y, z);
		content_t c = env->getMap().getNodeNoEx(p).getContent();
		for (; y <= maxp.Y; y++) {
			v3s16 psurf(x, y + 1, z);
			content_t csurf = env->getMap().getNodeNoEx(psurf).getContent();
			if(c != CONTENT_AIR && csurf == CONTENT_AIR &&
					filter.count(c) != 0) {
				push_v3s16(L, v3s16(x, y, z));
				lua_rawseti(L, -2, ++i);
			}
			c = csurf;
		}
	}
	return 1;
}
Beispiel #21
0
// find_nodes_with_meta(pos1, pos2)
int ModApiEnvMod::l_find_nodes_with_meta(lua_State *L)
{
	GET_ENV_PTR;

	std::vector<v3s16> positions = env->getMap().findNodesWithMetadata(
		check_v3s16(L, 1), check_v3s16(L, 2));

	lua_newtable(L);
	for (size_t i = 0; i != positions.size(); i++) {
		push_v3s16(L, positions[i]);
		lua_rawseti(L, -2, i + 1);
	}

	return 1;
}
Beispiel #22
0
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
{
	SCRIPTAPI_PRECHECKHEADER

	INodeDefManager *ndef = getServer()->ndef();

	// Push callback function on stack
	if(!getItemCallback(ndef->get(node).name.c_str(), "on_destruct"))
		return;

	// Call function
	push_v3s16(L, p);
	if(lua_pcall(L, 1, 0, 0))
		scriptError("error: %s", lua_tostring(L, -1));
}
Beispiel #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;
}
Beispiel #24
0
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
{
	SCRIPTAPI_PRECHECKHEADER

	INodeDefManager *ndef = getServer()->ndef();

	// Push callback function on stack
	if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct"))
		return;

	// Call function
	push_v3s16(L, p);
	pushnode(L, node, ndef);
	if (lua_pcall(L, 2, 0, m_errorhandler))
		scriptError();
}
Beispiel #25
0
void LuaLBM::trigger(ServerEnvironment *env, v3s16 p, MapNode n)
{
	GameScripting *scriptIface = env->getScriptIface();
	auto _script_lock = RecursiveMutexAutoLock(scriptIface->m_luastackmutex, std::try_to_lock);
	if (!_script_lock.owns_lock()) {
		return;
	}
	scriptIface->realityCheck();

	lua_State *L = scriptIface->getStack();
	sanity_check(lua_checkstack(L, 20));
	StackUnroller stack_unroller(L);

	int error_handler = PUSH_ERROR_HANDLER(L);

	// Get registered_lbms
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_lbms");
	luaL_checktype(L, -1, LUA_TTABLE);
	lua_remove(L, -2); // Remove core

	// Get registered_lbms[m_id]
	lua_pushnumber(L, m_id);
	lua_gettable(L, -2);
	//FATAL_ERROR_IF(lua_isnil(L, -1), "Entry with given id not found in registered_lbms table");
	if (lua_isnil(L, -1)) {
		errorstream << "Entry with given id " << m_id << " not found in registered_lbms table" << std::endl;
		return;
	}
	lua_remove(L, -2); // Remove registered_lbms

	scriptIface->setOriginFromTable(-1);

	// Call action
	luaL_checktype(L, -1, LUA_TTABLE);
	lua_getfield(L, -1, "action");
	luaL_checktype(L, -1, LUA_TFUNCTION);
	lua_remove(L, -2); // Remove registered_lbms[m_id]
	push_v3s16(L, p);
	pushnode(L, n, env->getGameDef()->ndef());

	int result = lua_pcall(L, 2, 0, error_handler);
	if (result)
		scriptIface->scriptError(result, "LuaLBM::trigger");

	lua_pop(L, 1); // Pop error handler
}
Beispiel #26
0
// 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;
}
Beispiel #27
0
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
{
	SCRIPTAPI_PRECHECKHEADER

	INodeDefManager *ndef = getServer()->ndef();

	// Push callback function on stack
	if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer"))
		return false;

	// Call function
	push_v3s16(L, p);
	lua_pushnumber(L,dtime);
	if (lua_pcall(L, 2, 1, m_errorhandler))
		scriptError();
	return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
}
Beispiel #28
0
void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node)
{
	realitycheck(L);
	assert(lua_checkstack(L, 20));
	StackUnroller stack_unroller(L);

	INodeDefManager *ndef = get_server(L)->ndef();

	// Push callback function on stack
	if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_destruct"))
		return;

	// Call function
	push_v3s16(L, p);
	if(lua_pcall(L, 1, 0, 0))
		script_error(L, "error: %s", lua_tostring(L, -1));
}
Beispiel #29
0
void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
{
	SCRIPTAPI_PRECHECKHEADER

	int error_handler = PUSH_ERROR_HANDLER(L);

	INodeDefManager *ndef = getServer()->ndef();

	// Push callback function on stack
	if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct"))
		return;

	// Call function
	push_v3s16(L, p);
	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
	lua_pop(L, 1);  // Pop error handler
}
Beispiel #30
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;
}