Ejemplo n.º 1
0
int ServerMap::getSurface(v3s16 basepos, int searchup, bool walkable_only) {

	s16 max = MYMIN(searchup + basepos.Y, 0x7FFF);

	MapNode last_node = getNodeNoEx(basepos);
	MapNode node = last_node;
	v3s16 runpos = basepos;
	INodeDefManager *nodemgr = m_gamedef->ndef();

	bool last_was_walkable = nodemgr->get(node).walkable;

	while ((runpos.Y < max) && (node.param0 != CONTENT_AIR)) {
		runpos.Y += 1;
		last_node = node;
		node = getNodeNoEx(runpos);

		if (!walkable_only) {
			if ((last_node.param0 != CONTENT_AIR) &&
			        (last_node.param0 != CONTENT_IGNORE) &&
			        (node.param0 == CONTENT_AIR)) {
				return runpos.Y;
			}
		} else {
			bool is_walkable = nodemgr->get(node).walkable;

			if (last_was_walkable && (!is_walkable)) {
				return runpos.Y;
			}
			last_was_walkable = is_walkable;
		}
	}

	return basepos.Y - 1;
}
Ejemplo n.º 2
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		int cold = ((ItemGroupList) ndef->get(neighbor).groups)["cold"];
		int freeze = ((ItemGroupList) ndef->get(n).groups)["freeze"];
		if (cold < freeze) {
			n.freeze_melt(ndef, -1);
			map->setNode(p, n);
		}
	}
Ejemplo n.º 3
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		int hot = ((ItemGroupList) ndef->get(neighbor).groups)["hot"];
		int melt = ((ItemGroupList) ndef->get(n).groups)["melt"];
		if (hot > melt) {
			n.freeze_melt(ndef, +1);
			map->setNode(p, n);
			env->nodeUpdate(p, 2);
		}
	}
Ejemplo n.º 4
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n)
	{
		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		MapNode n_top = map->getNodeNoEx(p+v3s16(0,1,0));
		if(!ndef->get(n_top).light_propagates ||
				ndef->get(n_top).isLiquid())
		{
			n.setContent(ndef->getId("dirt"));
			map->addNodeWithEvent(p, n);
		}
	}
Ejemplo n.º 5
0
	virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n)
	{
		INodeDefManager *ndef = env->getGameDef()->ndef();
		ServerMap *map = &env->getServerMap();
		
		MapNode n_top = map->getNodeNoEx(p+v3s16(0,1,0));
		if(ndef->get(n_top).light_propagates &&
				!ndef->get(n_top).isLiquid() &&
				n_top.getLightBlend(env->getDayNightRatio(), ndef) >= 13)
		{
			n.setContent(ndef->getId("dirt_with_grass"));
			map->addNodeWithEvent(p, n);
		}
	}
Ejemplo n.º 6
0
void GridNodeContainer::initNode(v3s16 ipos, PathGridnode *p_node)
{
    INodeDefManager *ndef = m_pathf->m_env->getGameDef()->ndef();
    PathGridnode &elem = *p_node;

    v3s16 realpos = m_pathf->getRealPos(ipos);

    MapNode current = m_pathf->m_env->getMap().getNodeNoEx(realpos);
    MapNode below   = m_pathf->m_env->getMap().getNodeNoEx(realpos + v3s16(0, -1, 0));


    if ((current.param0 == CONTENT_IGNORE) ||
            (below.param0 == CONTENT_IGNORE)) {
        DEBUG_OUT("Pathfinder: " << PP(realpos) <<
                  " current or below is invalid element" << std::endl);
        if (current.param0 == CONTENT_IGNORE) {
            elem.type = 'i';
            DEBUG_OUT(PP(ipos) << ": " << 'i' << std::endl);
        }
        return;
    }

    //don't add anything if it isn't an air node
    if (ndef->get(current).walkable || !ndef->get(below).walkable) {
        DEBUG_OUT("Pathfinder: " << PP(realpos)
                  << " not on surface" << std::endl);
        if (ndef->get(current).walkable) {
            elem.type = 's';
            DEBUG_OUT(PP(ipos) << ": " << 's' << std::endl);
        } else {
            elem.type = '-';
            DEBUG_OUT(PP(ipos) << ": " << '-' << std::endl);
        }
        return;
    }

    elem.valid = true;
    elem.pos   = realpos;
    elem.type  = 'g';
    DEBUG_OUT(PP(ipos) << ": " << 'a' << std::endl);

    if (m_pathf->m_prefetch) {
        elem.directions[DIR_XP] = m_pathf->calcCost(realpos, v3s16( 1, 0, 0));
        elem.directions[DIR_XM] = m_pathf->calcCost(realpos, v3s16(-1, 0, 0));
        elem.directions[DIR_ZP] = m_pathf->calcCost(realpos, v3s16( 0, 0, 1));
        elem.directions[DIR_ZM] = m_pathf->calcCost(realpos, v3s16( 0, 0,-1));
    }
}
Ejemplo n.º 7
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();

		float heat = map->updateBlockHeat(env, p);
		//heater = rare
		content_t c = map->getNodeTry(p - v3POS(0,  -1, 0 )).getContent(); // top
		//more chance to freeze if air at top
		static int water_level = g_settings->getS16("water_level");
		bool top_liquid = ndef->get(n).liquid_type > LIQUID_NONE && p.Y > water_level;
		int freeze = ((ItemGroupList) ndef->get(n).groups)["freeze"];
		if (heat <= freeze - 1 && ((!top_liquid && (activate || (heat <= freeze - 50))) || heat <= freeze - 50 ||
		                           (myrand_range(freeze - 50, heat) <= (freeze + (top_liquid ? -42 : c == CONTENT_AIR ? -10 : -40))))) {
			content_t c_self = n.getContent();
			// making freeze not annoying, do not freeze random blocks in center of ocean
			// todo: any block not water (dont freeze _source near _flowing)
			bool allow = activate || heat < freeze - 40;
			// todo: make for(...)
			if (!allow) {
				c = map->getNodeTry(p - v3POS(0,  1, 0 )).getContent(); // below
				if (c == CONTENT_AIR || c == CONTENT_IGNORE)
					if (ndef->get(n.getContent()).liquid_type == LIQUID_FLOWING || ndef->get(n.getContent()).liquid_type == LIQUID_SOURCE)
						return; // do not freeze when falling
				if (c != c_self && c != CONTENT_IGNORE) allow = 1;
				if (!allow) {
					c = map->getNodeTry(p - v3POS(1,  0, 0 )).getContent(); // right
					if (c != c_self && c != CONTENT_IGNORE) allow = 1;
					if (!allow) {
						c = map->getNodeTry(p - v3POS(-1, 0, 0 )).getContent(); // left
						if (c != c_self && c != CONTENT_IGNORE) allow = 1;
						if (!allow) {
							c = map->getNodeTry(p - v3POS(0,  0, 1 )).getContent(); // back
							if (c != c_self && c != CONTENT_IGNORE) allow = 1;
							if (!allow) {
								c = map->getNodeTry(p - v3POS(0,  0, -1)).getContent(); // front
								if (c != c_self && c != CONTENT_IGNORE) allow = 1;
							}
						}
					}
				}
			}
			if (allow) {
				n.freeze_melt(ndef, -1);
				map->setNode(p, n);
			}
		}
	}
Ejemplo n.º 8
0
void ClientMap::renderPostFx()
{
	INodeDefManager *nodemgr = m_gamedef->ndef();

	// Sadly ISceneManager has no "post effects" render pass, in that case we
	// could just register for that and handle it in renderMap().

	m_camera_mutex.Lock();
	v3f camera_position = m_camera_position;
	m_camera_mutex.Unlock();

	MapNode n = getNodeNoEx(floatToInt(camera_position, BS));

	// - If the player is in a solid node, make everything black.
	// - If the player is in liquid, draw a semi-transparent overlay.
	const ContentFeatures& features = nodemgr->get(n);
	video::SColor post_effect_color = features.post_effect_color;
	if(features.solidness == 2 && !(g_settings->getBool("noclip") && m_gamedef->checkLocalPrivilege("noclip")))
	{
		post_effect_color = video::SColor(255, 0, 0, 0);
	}
	if (post_effect_color.getAlpha() != 0)
	{
		// Draw a full-screen rectangle
		video::IVideoDriver* driver = SceneManager->getVideoDriver();
		v2u32 ss = driver->getScreenSize();
		core::rect<s32> rect(0,0, ss.X, ss.Y);
		driver->draw2DRectangle(post_effect_color, rect);
	}
}
Ejemplo n.º 9
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

	int error_handler = PUSH_ERROR_HANDLER(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 0;

	// Push callback function on stack
	std::string nodename = ndef->get(node).name;
	if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put", &p))
		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
	PCALL_RES(lua_pcall(L, 5, 1, error_handler));
	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, 2); // Pop integer and error handler
	return num;
}
Ejemplo n.º 10
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
}
Ejemplo n.º 11
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
}
Ejemplo n.º 12
0
// place_node(pos, node)
// pos = {x=num, y=num, z=num}
int ModApiEnvMod::l_place_node(lua_State *L)
{
	GET_ENV_PTR;

	ScriptApiItem *scriptIfaceItem = getScriptApi<ScriptApiItem>(L);
	Server *server = getServer(L);
	INodeDefManager *ndef = server->ndef();
	IItemDefManager *idef = server->idef();

	v3s16 pos = read_v3s16(L, 1);
	MapNode n = readnode(L, 2, ndef);

	// Don't attempt to load non-loaded area as of now
	MapNode n_old = env->getMap().getNodeNoEx(pos);
	if(n_old.getContent() == CONTENT_IGNORE){
		lua_pushboolean(L, false);
		return 1;
	}
	// Create item to place
	ItemStack item(ndef->get(n).name, 1, 0, "", idef);
	// Make pointed position
	PointedThing pointed;
	pointed.type = POINTEDTHING_NODE;
	pointed.node_abovesurface = pos;
	pointed.node_undersurface = pos + v3s16(0,-1,0);
	// Place it with a NULL placer (appears in Lua as a non-functional
	// ObjectRef)
	bool success = scriptIfaceItem->item_OnPlace(item, NULL, pointed);
	lua_pushboolean(L, success);
	return 1;
}
Ejemplo n.º 13
0
void WieldMeshSceneNode::setItem(const ItemStack &item, IGameDef *gamedef)
{
	ITextureSource *tsrc = gamedef->getTextureSource();
	IItemDefManager *idef = gamedef->getItemDefManager();

	const ItemDefinition &def = item.getDefinition(idef);

	// If wield_image is defined, it overrides everything else
	if (def.wield_image != "") {
		setExtruded(def.wield_image, def.wield_scale, tsrc);
		return;
	}

	// Handle nodes
	// See also CItemDefManager::createClientCached()
	if (def.type == ITEM_NODE) {
		INodeDefManager *ndef = gamedef->getNodeDefManager();
		const ContentFeatures &f = ndef->get(def.name);
		if (f.mesh_ptr[0]) {
			// e.g. mesh nodes and nodeboxes
			changeToMesh(f.mesh_ptr[0]);
			// mesh_ptr[0] is pre-scaled by BS * f->visual_scale
			m_meshnode->setScale(
					def.wield_scale * WIELD_SCALE_FACTOR
					/ (BS * f.visual_scale));
			// Customize materials
			for (u32 i = 0; i < m_meshnode->getMaterialCount(); ++i) {
				assert(i < 6);
				video::SMaterial &material = m_meshnode->getMaterial(i);
				material.setTexture(0, f.tiles[i].texture);
				f.tiles[i].applyMaterialOptions(material);
			}
			return;
		} else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) {
			setCube(f.tiles, def.wield_scale, tsrc);
			return;
		} else if (f.drawtype == NDT_AIRLIKE) {
			changeToMesh(NULL);
			return;
		}

		// If none of the above standard cases worked, use the wield mesh from ClientCached
		scene::IMesh *mesh = idef->getWieldMesh(item.name, gamedef);
		if (mesh) {
			changeToMesh(mesh);
			m_meshnode->setScale(def.wield_scale * WIELD_SCALE_FACTOR);
			return;
		}
	}

	// default to inventory_image
	if (def.inventory_image != "") {
		setExtruded(def.inventory_image, def.wield_scale, tsrc);
		return;
	}

	// no wield mesh found
	changeToMesh(NULL);
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
/*
	Gets nth node tile (0 <= n <= 5).
*/
TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data)
{
	INodeDefManager *ndef = data->m_gamedef->ndef();
	TileSpec spec = ndef->get(mn).tiles[tileindex];
	// Apply temporary crack
	if (p == data->m_crack_pos_relative)
		spec.material_flags |= MATERIAL_FLAG_CRACK;
	return spec;
}
Ejemplo n.º 16
0
/*
	Calculate smooth lighting at the XYZ- corner of p.
	Single light bank.
*/
static u8 getSmoothLight(enum LightBank bank, v3s16 p, MeshMakeData *data)
{
	static v3s16 dirs8[8] = {
		v3s16(0,0,0),
		v3s16(0,0,1),
		v3s16(0,1,0),
		v3s16(0,1,1),
		v3s16(1,0,0),
		v3s16(1,1,0),
		v3s16(1,0,1),
		v3s16(1,1,1),
	};

	INodeDefManager *ndef = data->m_gamedef->ndef();

	u16 ambient_occlusion = 0;
	u16 light = 0;
	u16 light_count = 0;
	u8 light_source_max = 0;
	for(u32 i=0; i<8; i++)
	{
		MapNode n = data->m_vmanip.getNodeNoEx(p - dirs8[i]);
		const ContentFeatures &f = ndef->get(n);
		if(f.light_source > light_source_max)
			light_source_max = f.light_source;
		// Check f.solidness because fast-style leaves look
		// better this way
		if(f.param_type == CPT_LIGHT && f.solidness != 2)
		{
			light += decode_light(n.getLight(bank, ndef));
			light_count++;
		}
		else if(n.getContent() != CONTENT_IGNORE)
		{
			ambient_occlusion++;
		}
	}

	if(light_count == 0)
		return 255;
	
	light /= light_count;

	// Boost brightness around light sources
	if(decode_light(light_source_max) >= light)
		//return decode_light(undiminish_light(light_source_max));
		return decode_light(light_source_max);

	if(ambient_occlusion > 4)
	{
		ambient_occlusion -= 4;
		light = (float)light / ((float)ambient_occlusion * 0.5 + 1.0);
	}

	return light;
}
Ejemplo n.º 17
0
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		float heat = map->updateBlockHeat(env, p);
		content_t c = map->getNodeTry(p - v3POS(0,  -1, 0 )).getContent(); // top
		int melt = ((ItemGroupList) ndef->get(n).groups)["melt"];
		if (heat >= melt + 1 && (activate || heat >= melt + 40 ||
		                         ((myrand_range(heat, melt + 40)) >= (c == CONTENT_AIR ? melt + 10 : melt + 20)))) {
			if (ndef->get(n.getContent()).liquid_type == LIQUID_FLOWING || ndef->get(n.getContent()).liquid_type == LIQUID_SOURCE) {
				c = map->getNodeTry(p - v3POS(0,  1, 0 )).getContent(); // below
				if (c == CONTENT_AIR || c == CONTENT_IGNORE)
					return; // do not melt when falling (dirt->dirt_with_grass on air)
			}
			n.freeze_melt(ndef, +1);
			map->setNode(p, n);
			env->nodeUpdate(p, 2); //enable after making FAST nodeupdate
		}
	}
Ejemplo n.º 18
0
// get_name_from_content_id(name)
int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	content_t c = luaL_checkint(L, 1);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	const char *name = ndef->get(c).name.c_str();

	lua_pushstring(L, name);
	return 1; /* number of results */
}
Ejemplo n.º 19
0
/*
	Calculate non-smooth lighting at face of node.
	Single light bank.
*/
static u8 getFaceLight(enum LightBank bank, MapNode n, MapNode n2,
		v3s16 face_dir, MeshMakeData *data)
{
	INodeDefManager *ndef = data->m_gamedef->ndef();

	u8 light;
	u8 l1 = n.getLight(bank, ndef);
	u8 l2 = n2.getLight(bank, ndef);
	if(l1 > l2)
		light = l1;
	else
		light = l2;

	// Boost light level for light sources
	u8 light_source = MYMAX(ndef->get(n).light_source,
			ndef->get(n2).light_source);
	//if(light_source >= light)
		//return decode_light(undiminish_light(light_source));
	if(light_source > light)
		//return decode_light(light_source);
		light = light_source;

	// Make some nice difference to different sides

	// This makes light come from a corner
	/*if(face_dir.X == 1 || face_dir.Z == 1 || face_dir.Y == -1)
		light = diminish_light(diminish_light(light));
	else if(face_dir.X == -1 || face_dir.Z == -1)
		light = diminish_light(light);*/

	// All neighboring faces have different shade (like in minecraft)
	if(face_dir.X == 1 || face_dir.X == -1 || face_dir.Y == -1)
		light = diminish_light(diminish_light(light));
	else if(face_dir.Z == 1 || face_dir.Z == -1)
		light = diminish_light(light);

	return decode_light(light);
}
Ejemplo n.º 20
0
RollbackNode::RollbackNode(Map *map, v3s16 p, IGameDef *gamedef)
{
	INodeDefManager *ndef = gamedef->ndef();
	MapNode n = map->getNodeNoEx(p);
	name = ndef->get(n).name;
	param1 = n.param1;
	param2 = n.param2;
	NodeMetadata *metap = map->getNodeMetadata(p);
	if (metap) {
		std::ostringstream os(std::ios::binary);
		metap->serialize(os);
		meta = os.str();
	}
}
MapgenSinglenode::MapgenSinglenode(int mapgenid,
	MapgenParams *params, EmergeManager *emerge)
	: Mapgen(mapgenid, params, emerge)
{
	flags = params->flags;

	INodeDefManager *ndef = emerge->ndef;

	c_node = ndef->getId("mapgen_singlenode");
	if (c_node == CONTENT_IGNORE)
		c_node = CONTENT_AIR;

	MapNode n_node(c_node);
	set_light = (ndef->get(n_node).sunlight_propagates) ? LIGHT_SUN : 0x00;
}
Ejemplo n.º 22
0
/*
	Gets nth node tile (0 <= n <= 5).
*/
TileSpec getNodeTileN(MapNode mn, v3s16 p, u8 tileindex, MeshMakeData *data)
{
	INodeDefManager *ndef = data->m_gamedef->ndef();
	TileSpec spec = ndef->get(mn).tiles[tileindex];
	// Apply temporary crack
	if(p == data->m_crack_pos_relative)
	{
		spec.material_flags |= MATERIAL_FLAG_CRACK;
		spec.texture = data->m_gamedef->tsrc()->getTextureRawAP(spec.texture);
	}
	// If animated, replace tile texture with one without texture atlas
	if(spec.material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES)
	{
		spec.texture = data->m_gamedef->tsrc()->getTextureRawAP(spec.texture);
	}
	return spec;
}
Ejemplo n.º 23
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));
}
Ejemplo n.º 24
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
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
0
void ScriptApiNode::node_on_deactivate(v3s16 p, MapNode node)
{
	SCRIPTAPI_PRECHECKHEADER

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

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

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

	// Call function
	push_v3s16(L, p);
	PCALL_RES(lua_pcall(L, 1, 0, errorhandler));
	lua_pop(L, 1); // Pop error handler
}
Ejemplo n.º 27
0
bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
{
	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_timer"))
		return false;

	// Call function
	push_v3s16(L, p);
	lua_pushnumber(L,dtime);
	PCALL_RES(lua_pcall(L, 2, 1, error_handler));
	lua_remove(L, error_handler);
	return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
}
Ejemplo n.º 28
0
bool RollbackAction::isImportant(IGameDef *gamedef) const
{
	if (type != TYPE_SET_NODE)
		return true;
	// If names differ, action is always important
	if(n_old.name != n_new.name)
		return true;
	// If metadata differs, action is always important
	if(n_old.meta != n_new.meta)
		return true;
	INodeDefManager *ndef = gamedef->ndef();
	// Both are of the same name, so a single definition is needed
	const ContentFeatures &def = ndef->get(n_old.name);
	// If the type is flowing liquid, action is not important
	if (def.liquid_type == LIQUID_FLOWING)
		return false;
	// Otherwise action is important
	return true;
}
Ejemplo n.º 29
0
// get_node_def(nodename)
int ModApiClient::l_get_node_def(lua_State *L)
{
	IGameDef *gdef = getGameDef(L);
	assert(gdef);

	INodeDefManager *ndef = gdef->ndef();
	assert(ndef);

	if (!lua_isstring(L, 1))
		return 0;

	const std::string &name = lua_tostring(L, 1);
	const ContentFeatures &cf = ndef->get(ndef->getId(name));
	if (cf.name != name) // Unknown node. | name = <whatever>, cf.name = ignore
		return 0;

	push_content_features(L, cf);

	return 1;
}
Ejemplo n.º 30
0
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
{
	SCRIPTAPI_PRECHECKHEADER

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

	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, errorhandler))
		scriptError();
	lua_pop(L, 1); // Pop error handler
}