コード例 #1
0
ファイル: c_content.cpp プロジェクト: kaeza/minetest
struct TileAnimationParams read_animation_definition(lua_State *L, int index)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	struct TileAnimationParams anim;
	anim.type = TAT_NONE;
	if (!lua_istable(L, index))
		return anim;

	anim.type = (TileAnimationType)
		getenumfield(L, index, "type", es_TileAnimationType,
		TAT_NONE);
	if (anim.type == TAT_VERTICAL_FRAMES) {
		// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
		anim.vertical_frames.aspect_w =
			getintfield_default(L, index, "aspect_w", 16);
		anim.vertical_frames.aspect_h =
			getintfield_default(L, index, "aspect_h", 16);
		anim.vertical_frames.length =
			getfloatfield_default(L, index, "length", 1.0);
	} else if (anim.type == TAT_SHEET_2D) {
		// {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5}
		getintfield(L, index, "frames_w",
			anim.sheet_2d.frames_w);
		getintfield(L, index, "frames_h",
			anim.sheet_2d.frames_h);
		getfloatfield(L, index, "frame_length",
			anim.sheet_2d.frame_length);
	}

	return anim;
}
コード例 #2
0
ファイル: l_mapgen.cpp プロジェクト: DarkDracoon/minetest
Biome *read_biome_def(lua_State *L, int index, INodeDefManager *ndef)
{
	if (!lua_istable(L, index))
		return NULL;

	BiomeType biometype = (BiomeType)getenumfield(L, index, "type",
		ModApiMapgen::es_BiomeTerrainType, BIOMETYPE_NORMAL);
	Biome *b = BiomeManager::create(biometype);

	b->name            = getstringfield_default(L, index, "name", "");
	b->depth_top       = getintfield_default(L,    index, "depth_top",       0);
	b->depth_filler    = getintfield_default(L,    index, "depth_filler",    -31000);
	b->depth_water_top = getintfield_default(L,    index, "depth_water_top", 0);
	b->depth_riverbed  = getintfield_default(L,    index, "depth_riverbed",  0);
	b->y_min           = getintfield_default(L,    index, "y_min",           -31000);
	b->y_max           = getintfield_default(L,    index, "y_max",           31000);
	b->heat_point      = getfloatfield_default(L,  index, "heat_point",      0.f);
	b->humidity_point  = getfloatfield_default(L,  index, "humidity_point",  0.f);
	b->flags           = 0; //reserved

	std::vector<std::string> &nn = b->m_nodenames;
	nn.push_back(getstringfield_default(L, index, "node_top",         ""));
	nn.push_back(getstringfield_default(L, index, "node_filler",      ""));
	nn.push_back(getstringfield_default(L, index, "node_stone",       ""));
	nn.push_back(getstringfield_default(L, index, "node_water_top",   ""));
	nn.push_back(getstringfield_default(L, index, "node_water",       ""));
	nn.push_back(getstringfield_default(L, index, "node_river_water", ""));
	nn.push_back(getstringfield_default(L, index, "node_riverbed",    ""));
	nn.push_back(getstringfield_default(L, index, "node_dust",        ""));
	ndef->pendNodeResolve(b);

	return b;
}
コード例 #3
0
ファイル: l_mapgen.cpp プロジェクト: AnnXGame/Minetest
bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef,
	DecoSchematic *deco)
{
	int index = 1;

	deco->rotation = (Rotation)getenumfield(L, index, "rotation",
		es_Rotation, ROTATE_0);

	std::map<std::string, std::string> replace_names;
	lua_getfield(L, index, "replacements");
	if (lua_istable(L, -1))
		read_schematic_replacements(L, replace_names, lua_gettop(L));
	lua_pop(L, 1);

	// TODO(hmmmm): get a ref from registered schematics
	Schematic *schem = new Schematic;
	lua_getfield(L, index, "schematic");
	if (!get_schematic(L, -1, schem, ndef, replace_names)) {
		lua_pop(L, 1);
		delete schem;
		return false;
	}
	lua_pop(L, 1);

	deco->schematic = schem;

	return true;
}
コード例 #4
0
ファイル: l_object.cpp プロジェクト: Selat/freeminer
// hud_add(self, form)
int ObjectRef::l_hud_add(lua_State *L)
{
	ObjectRef *ref = checkobject(L, 1);
	Player *player = getplayer(ref);
	if (player == NULL)
		return 0;

	HudElement *elem = new HudElement;

	elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
								es_HudElementType, HUD_ELEM_TEXT);

	lua_getfield(L, 2, "position");
	elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "scale");
	elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "size");
	elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32();
	lua_pop(L, 1);

	elem->name   = getstringfield_default(L, 2, "name", "");
	elem->text   = getstringfield_default(L, 2, "text", "");
	elem->number = getintfield_default(L, 2, "number", 0);
	elem->item   = getintfield_default(L, 2, "item", 0);
	elem->dir    = getintfield_default(L, 2, "direction", 0);

	// Deprecated, only for compatibility's sake
	if (elem->dir == 0)
		elem->dir = getintfield_default(L, 2, "dir", 0);

	lua_getfield(L, 2, "alignment");
	elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "offset");
	elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "world_pos");
	elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
	lua_pop(L, 1);

	/* check for known deprecated element usage */
	if ((elem->type  == HUD_ELEM_STATBAR) && (elem->size == v2s32())) {
		log_deprecated(L,"Deprecated usage of statbar without size!");
	}

	u32 id = getServer(L)->hudAdd(player, elem);
	if (id == (u32)-1) {
		delete elem;
		return 0;
	}

	lua_pushnumber(L, id);
	return 1;
}
コード例 #5
0
// register_biome({lots of stuff})
int ModApiBasic::l_register_biome(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
	if (!bmgr) {
		verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
		return 0;
	}

	enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
				"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
	Biome *b = bmgr->createBiome(terrain);

	b->name            = getstringfield_default(L, index, "name", "");
	b->top_nodename    = getstringfield_default(L, index, "top_node", "");
	b->top_depth       = getintfield_default(L, index, "top_depth", 0);
	b->filler_nodename = getstringfield_default(L, index, "filler_node", "");
	b->filler_height   = getintfield_default(L, index, "filler_height", 0);
	b->height_min      = getintfield_default(L, index, "height_min", 0);
	b->height_max      = getintfield_default(L, index, "height_max", 0);
	b->heat_point      = getfloatfield_default(L, index, "heat_point", 0.);
	b->humidity_point  = getfloatfield_default(L, index, "humidity_point", 0.);

	b->flags    = 0; //reserved
	b->c_top    = CONTENT_IGNORE;
	b->c_filler = CONTENT_IGNORE;
	verbosestream << "register_biome: " << b->name << std::endl;
	bmgr->addBiome(b);

	return 0;
}
コード例 #6
0
ファイル: luaapi.cpp プロジェクト: EcoleKeine/minetest
int ModApiBasic::l_register_ore(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

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

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_SCATTER);
	Ore *ore = createOre(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type "
			<< oretype << " not implemented";
		return 0;
	}

	ore->ore_name       = getstringfield_default(L, index, "ore", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->height_min     = getintfield_default(L, index, "height_min", 0);
	ore->height_max     = getintfield_default(L, index, "height_max", 0);
	ore->flags          = getflagsfield(L, index, "flags", flagdesc_ore);
	ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0.);

	lua_getfield(L, index, "wherein");
	if (lua_istable(L, -1)) {
		int  i = lua_gettop(L);
		lua_pushnil(L);
		while(lua_next(L, i) != 0) {
			ore->wherein_names.push_back(lua_tostring(L, -1));
			lua_pop(L, 1);
		}
	} else if (lua_isstring(L, -1)) {
		ore->wherein_names.push_back(lua_tostring(L, -1));
	} else {
		ore->wherein_names.push_back("");
	}
	lua_pop(L, 1);

	lua_getfield(L, index, "noise_params");
	ore->np = read_noiseparams(L, -1);
	lua_pop(L, 1);

	ore->noise = NULL;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	emerge->ores.push_back(ore);

	verbosestream << "register_ore: ore '" << ore->ore_name
		<< "' registered" << std::endl;
	return 0;
}
コード例 #7
0
ItemDefinition read_item_definition(lua_State *L, int index,
		ItemDefinition default_def)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	// Read the item definition
	ItemDefinition def = default_def;

	def.type = (ItemType)getenumfield(L, index, "type",
			es_ItemType, ITEM_NONE);
	getstringfield(L, index, "name", def.name);
	getstringfield(L, index, "description", def.description);
	getstringfield(L, index, "inventory_image", def.inventory_image);
	getstringfield(L, index, "wield_image", def.wield_image);

	lua_getfield(L, index, "wield_scale");
	if(lua_istable(L, -1)){
		def.wield_scale = check_v3f(L, -1);
	}
	lua_pop(L, 1);

	def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
	if(def.stack_max == 0)
		def.stack_max = 1;

	lua_getfield(L, index, "on_use");
	def.usable = lua_isfunction(L, -1);
	lua_pop(L, 1);

	getboolfield(L, index, "liquids_pointable", def.liquids_pointable);

	warn_if_field_exists(L, index, "tool_digging_properties",
			"deprecated: use tool_capabilities");

	lua_getfield(L, index, "tool_capabilities");
	if(lua_istable(L, -1)){
		def.tool_capabilities = new ToolCapabilities(
				read_tool_capabilities(L, -1));
	}

	// If name is "" (hand), ensure there are ToolCapabilities
	// because it will be looked up there whenever any other item has
	// no ToolCapabilities
	if(def.name == "" && def.tool_capabilities == NULL){
		def.tool_capabilities = new ToolCapabilities();
	}

	lua_getfield(L, index, "groups");
	read_groups(L, -1, def.groups);
	lua_pop(L, 1);

	// Client shall immediately place this node when player places the item.
	// Server will update the precise end result a moment later.
	// "" = no prediction
	getstringfield(L, index, "node_placement_prediction",
			def.node_placement_prediction);

	return def;
}
コード例 #8
0
ファイル: c_content.cpp プロジェクト: kaeza/minetest
NodeBox read_nodebox(lua_State *L, int index)
{
	NodeBox nodebox;
	if(lua_istable(L, -1)){
		nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
				ScriptApiNode::es_NodeBoxType, NODEBOX_REGULAR);

#define NODEBOXREAD(n, s) \
	do { \
		lua_getfield(L, index, (s)); \
		if (lua_istable(L, -1)) \
			(n) = read_aabb3f(L, -1, BS); \
		lua_pop(L, 1); \
	} while (0)

#define NODEBOXREADVEC(n, s) \
	do { \
		lua_getfield(L, index, (s)); \
		if (lua_istable(L, -1)) \
			(n) = read_aabb3f_vector(L, -1, BS); \
		lua_pop(L, 1); \
	} while (0)
		NODEBOXREADVEC(nodebox.fixed, "fixed");
		NODEBOXREAD(nodebox.wall_top, "wall_top");
		NODEBOXREAD(nodebox.wall_bottom, "wall_bottom");
		NODEBOXREAD(nodebox.wall_side, "wall_side");
		NODEBOXREADVEC(nodebox.connect_top, "connect_top");
		NODEBOXREADVEC(nodebox.connect_bottom, "connect_bottom");
		NODEBOXREADVEC(nodebox.connect_front, "connect_front");
		NODEBOXREADVEC(nodebox.connect_left, "connect_left");
		NODEBOXREADVEC(nodebox.connect_back, "connect_back");
		NODEBOXREADVEC(nodebox.connect_right, "connect_right");
	}
	return nodebox;
}
コード例 #9
0
NodeBox read_nodebox(lua_State *L, int index)
{
	NodeBox nodebox;
	if(lua_istable(L, -1)){
		nodebox.type = (NodeBoxType)getenumfield(L, index, "type",
				ScriptApiNode::es_NodeBoxType, NODEBOX_REGULAR);

		lua_getfield(L, index, "fixed");
		if(lua_istable(L, -1))
			nodebox.fixed = read_aabb3f_vector(L, -1, BS);
		lua_pop(L, 1);

		lua_getfield(L, index, "wall_top");
		if(lua_istable(L, -1))
			nodebox.wall_top = read_aabb3f(L, -1, BS);
		lua_pop(L, 1);

		lua_getfield(L, index, "wall_bottom");
		if(lua_istable(L, -1))
			nodebox.wall_bottom = read_aabb3f(L, -1, BS);
		lua_pop(L, 1);

		lua_getfield(L, index, "wall_side");
		if(lua_istable(L, -1))
			nodebox.wall_side = read_aabb3f(L, -1, BS);
		lua_pop(L, 1);
	}
	return nodebox;
}
コード例 #10
0
// clear_objects([options])
// clear all objects in the environment
// where options = {mode = "full" or "quick"}
int ModApiEnvMod::l_clear_objects(lua_State *L)
{
	GET_ENV_PTR;

	ClearObjectsMode mode = CLEAR_OBJECTS_MODE_FULL;
	if (lua_istable(L, 1)) {
		mode = (ClearObjectsMode)getenumfield(L, 1, "mode",
			ModApiEnvMod::es_ClearObjectsMode, mode);
	}

	env->clearObjects(mode);
	return 0;
}
コード例 #11
0
ファイル: l_craft.cpp プロジェクト: Mab879/freeminer
// get_craft_result(input)
int ModApiCraft::l_get_craft_result(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	int input_i = 1;
	std::string method_s = getstringfield_default(L, input_i, "method", "normal");
	enum CraftMethod method = (CraftMethod)getenumfield(L, input_i, "method",
				es_CraftMethod, CRAFT_METHOD_NORMAL);
	int width = 1;
	lua_getfield(L, input_i, "width");
	if(lua_isnumber(L, -1))
		width = luaL_checkinteger(L, -1);
	lua_pop(L, 1);
	lua_getfield(L, input_i, "items");
	std::vector<ItemStack> items = read_items(L, -1,getServer(L));
	lua_pop(L, 1); // items

	IGameDef *gdef = getServer(L);
	ICraftDefManager *cdef = gdef->cdef();
	CraftInput input(method, width, items);
	CraftOutput output;
	std::vector<ItemStack> output_replacements;
	bool got = cdef->getCraftResult(input, output, output_replacements, true, gdef);
	lua_newtable(L); // output table
	if (got) {
		ItemStack item;
		item.deSerialize(output.item, gdef->idef());
		LuaItemStack::create(L, item);
		lua_setfield(L, -2, "item");
		setintfield(L, -1, "time", output.time);
		push_items(L, output_replacements);
		lua_setfield(L, -2, "replacements");
	} else {
		LuaItemStack::create(L, ItemStack());
		lua_setfield(L, -2, "item");
		setintfield(L, -1, "time", 0);
		lua_newtable(L);
		lua_setfield(L, -2, "replacements");
	}
	lua_newtable(L); // decremented input table
	lua_pushstring(L, method_s.c_str());
	lua_setfield(L, -2, "method");
	lua_pushinteger(L, width);
	lua_setfield(L, -2, "width");
	push_items(L, input.items);
	lua_setfield(L, -2, "items");
	return 2;
}
コード例 #12
0
ファイル: l_mapgen.cpp プロジェクト: AnnXGame/Minetest
// register_biome({lots of stuff})
int ModApiMapgen::l_register_biome(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	BiomeManager *bmgr    = getServer(L)->getEmergeManager()->biomemgr;

	enum BiomeType biometype = (BiomeType)getenumfield(L, index, "type",
		es_BiomeTerrainType, BIOME_TYPE_NORMAL);
	Biome *b = bmgr->create(biometype);

	b->name            = getstringfield_default(L, index, "name", "");
	b->depth_top       = getintfield_default(L, index, "depth_top",          1);
	b->depth_filler    = getintfield_default(L, index, "depth_filler",       3);
	b->height_shore    = getintfield_default(L, index, "height_shore",       3);
	b->depth_water_top = getintfield_default(L, index, "depth_water_top",    0);
	b->y_min           = getintfield_default(L, index, "y_min",         -31000);
	b->y_max           = getintfield_default(L, index, "y_max",          31000);
	b->heat_point      = getfloatfield_default(L, index, "heat_point",     0.f);
	b->humidity_point  = getfloatfield_default(L, index, "humidity_point", 0.f);
	b->flags           = 0; //reserved

	u32 id = bmgr->add(b);
	if (id == (u32)-1) {
		delete b;
		return 0;
	}

	NodeResolveInfo *nri = new NodeResolveInfo(b);
	std::list<std::string> &nnames = nri->nodenames;
	nnames.push_back(getstringfield_default(L, index, "node_top",          ""));
	nnames.push_back(getstringfield_default(L, index, "node_filler",       ""));
	nnames.push_back(getstringfield_default(L, index, "node_shore_top",    ""));
	nnames.push_back(getstringfield_default(L, index, "node_shore_filler", ""));
	nnames.push_back(getstringfield_default(L, index, "node_underwater",   ""));
	nnames.push_back(getstringfield_default(L, index, "node_stone",        ""));
	nnames.push_back(getstringfield_default(L, index, "node_water_top",    ""));
	nnames.push_back(getstringfield_default(L, index, "node_water",        ""));
	nnames.push_back(getstringfield_default(L, index, "node_dust",         ""));
	ndef->pendNodeResolve(nri);

	verbosestream << "register_biome: " << b->name << std::endl;

	lua_pushinteger(L, id);
	return 1;
}
コード例 #13
0
ファイル: l_object.cpp プロジェクト: Nate-Devv/freeminer
// hud_add(self, form)
int ObjectRef::l_hud_add(lua_State *L)
{
	ObjectRef *ref = checkobject(L, 1);
	Player *player = getplayer(ref);
	if (player == NULL)
		return 0;

	HudElement *elem = new HudElement;

	elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
								es_HudElementType, HUD_ELEM_TEXT);

	lua_getfield(L, 2, "position");
	elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "scale");
	elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	elem->name   = getstringfield_default(L, 2, "name", "");
	elem->text   = getstringfield_default(L, 2, "text", "");
	elem->number = getintfield_default(L, 2, "number", 0);
	elem->item   = getintfield_default(L, 2, "item", 0);
	elem->dir    = getintfield_default(L, 2, "dir", 0);

	lua_getfield(L, 2, "alignment");
	elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "offset");
	elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
	lua_pop(L, 1);

	lua_getfield(L, 2, "world_pos");
	elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
	lua_pop(L, 1);

	u32 id = getServer(L)->hudAdd(player, elem);
	if (id == (u32)-1) {
		delete elem;
		return 0;
	}

	lua_pushnumber(L, id);
	return 1;
}
コード例 #14
0
ファイル: l_mapgen.cpp プロジェクト: Emu4Play/minetest
// register_biome({lots of stuff})
int ModApiMapgen::l_register_biome(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
	if (!bmgr) {
		verbosestream << "register_biome: BiomeDefManager not active" << std::endl;
		return 0;
	}

	enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
				"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
	Biome *b = bmgr->createBiome(terrain);

	b->name         = getstringfield_default(L, index, "name",
												"<no name>");
	b->nname_top    = getstringfield_default(L, index, "node_top",
												"mapgen_dirt_with_grass");
	b->nname_filler = getstringfield_default(L, index, "node_filler",
												"mapgen_dirt");
	b->nname_water  = getstringfield_default(L, index, "node_water",
												"mapgen_water_source");
	b->nname_dust   = getstringfield_default(L, index, "node_dust",
												"air");
	b->nname_dust_water = getstringfield_default(L, index, "node_dust_water",
												"mapgen_water_source");

	b->depth_top      = getintfield_default(L, index, "depth_top",    1);
	b->depth_filler   = getintfield_default(L, index, "depth_filler", 3);
	b->height_min     = getintfield_default(L, index, "height_min",   0);
	b->height_max     = getintfield_default(L, index, "height_max",   0);
	b->heat_point     = getfloatfield_default(L, index, "heat_point",     0.);
	b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);

	b->flags        = 0; //reserved
	b->c_top        = CONTENT_IGNORE;
	b->c_filler     = CONTENT_IGNORE;
	b->c_water      = CONTENT_IGNORE;
	b->c_dust       = CONTENT_IGNORE;
	b->c_dust_water = CONTENT_IGNORE;

	verbosestream << "register_biome: " << b->name << std::endl;
	bmgr->addBiome(b);

	return 0;
}
コード例 #15
0
ファイル: l_mapgen.cpp プロジェクト: DarkDracoon/minetest
bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco)
{
	int index = 1;

	deco->rotation = (Rotation)getenumfield(L, index, "rotation",
		ModApiMapgen::es_Rotation, ROTATE_0);

	StringMap replace_names;
	lua_getfield(L, index, "replacements");
	if (lua_istable(L, -1))
		read_schematic_replacements(L, -1, &replace_names);
	lua_pop(L, 1);

	lua_getfield(L, index, "schematic");
	Schematic *schem = get_or_load_schematic(L, -1, schemmgr, &replace_names);
	lua_pop(L, 1);

	deco->schematic = schem;
	return schem != NULL;
}
コード例 #16
0
// serialize_schematic(schematic, format, options={...})
int ModApiMapgen::l_serialize_schematic(lua_State *L)
{
	SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;

	//// Read options
	NodeResolveMethod resolve_method = (NodeResolveMethod)getenumfield(L, 3,
		"node_resolve_method", es_NodeResolveMethod, NODE_RESOLVE_NONE);
	bool register_on_load = getboolfield_default(L, 3, "register_on_load", false);
	bool use_comments = getboolfield_default(L, 3, "use_lua_comments", false);

	//// Read schematic
	Schematic *schem = get_or_load_schematic(L, 1, schemmgr, NULL,
		register_on_load, resolve_method);
	if (!schem) {
		errorstream << "serialize_schematic: failed to get schematic" << std::endl;
		return 0;
	}

	//// Read format of definition to save as
	int schem_format = SCHEM_FMT_MTS;
	const char *enumstr = lua_tostring(L, 2);
	if (enumstr)
		string_to_enum(es_SchematicFormatType, schem_format, std::string(enumstr));

	//// Serialize to binary string
	std::ostringstream os(std::ios_base::binary);
	switch (schem_format) {
	case SCHEM_FMT_MTS:
		schem->serializeToMts(&os);
		break;
	case SCHEM_FMT_LUA:
		schem->serializeToLua(&os, use_comments);
		break;
	default:
		return 0;
	}

	std::string ser = os.str();
	lua_pushlstring(L, ser.c_str(), ser.length());
	return 1;
}
コード例 #17
0
TileDef read_tiledef(lua_State *L, int index)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	TileDef tiledef;

	// key at index -2 and value at index
	if(lua_isstring(L, index)){
		// "default_lava.png"
		tiledef.name = lua_tostring(L, index);
	}
	else if(lua_istable(L, index))
	{
		// {name="default_lava.png", animation={}}
		tiledef.name = "";
		getstringfield(L, index, "name", tiledef.name);
		getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
		tiledef.backface_culling = getboolfield_default(
					L, index, "backface_culling", true);
		// animation = {}
		lua_getfield(L, index, "animation");
		if(lua_istable(L, -1)){
			// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
			tiledef.animation.type = (TileAnimationType)
					getenumfield(L, -1, "type", es_TileAnimationType,
					TAT_NONE);
			tiledef.animation.aspect_w =
					getintfield_default(L, -1, "aspect_w", 16);
			tiledef.animation.aspect_h =
					getintfield_default(L, -1, "aspect_h", 16);
			tiledef.animation.length =
					getfloatfield_default(L, -1, "length", 1.0);
		}
		lua_pop(L, 1);
	}

	return tiledef;
}
コード例 #18
0
// register_decoration({lots of stuff})
int ModApiBasic::l_register_decoration(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);
	
	EmergeManager *emerge = getServer(L)->getEmergeManager();
	BiomeDefManager *bdef = emerge->biomedef;

	enum DecorationType decotype = (DecorationType)getenumfield(L, index,
				"deco_type", es_DecorationType, -1);
	if (decotype == -1) {
		errorstream << "register_decoration: unrecognized "
			"decoration placement type";
		return 0;
	}
	
	Decoration *deco = createDecoration(decotype);
	if (!deco) {
		errorstream << "register_decoration: decoration placement type "
			<< decotype << " not implemented";
		return 0;
	}

	deco->c_place_on    = CONTENT_IGNORE;
	deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
	deco->sidelen       = getintfield_default(L, index, "sidelen", 8);
	deco->fill_ratio    = getfloatfield_default(L, index, "fill_ratio", 0.02);
	
	lua_getfield(L, index, "noise_params");
	deco->np = read_noiseparams(L, -1);
	lua_pop(L, 1);
	
	lua_getfield(L, index, "biomes");
	if (lua_istable(L, -1)) {
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			const char *s = lua_tostring(L, -1);
			u8 biomeid = bdef->getBiomeIdByName(s);
			if (biomeid)
				deco->biomes.insert(biomeid);

			lua_pop(L, 1);
		}
		lua_pop(L, 1);
	}
	
	switch (decotype) {
		case DECO_SIMPLE: {
			DecoSimple *dsimple = (DecoSimple *)deco;
			dsimple->c_deco     = CONTENT_IGNORE;
			dsimple->c_spawnby  = CONTENT_IGNORE;
			dsimple->spawnby_name    = getstringfield_default(L, index, "spawn_by", "air");
			dsimple->deco_height     = getintfield_default(L, index, "height", 1);
			dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
			dsimple->nspawnby        = getintfield_default(L, index, "num_spawn_by", -1);
			
			lua_getfield(L, index, "decoration");
			if (lua_istable(L, -1)) {
				lua_pushnil(L);
				while (lua_next(L, -2)) {
					const char *s = lua_tostring(L, -1);
					std::string str(s);
					dsimple->decolist_names.push_back(str);

					lua_pop(L, 1);
				}
			} else if (lua_isstring(L, -1)) {
				dsimple->deco_name  = std::string(lua_tostring(L, -1));
			} else {
				dsimple->deco_name = std::string("air");
			}
			lua_pop(L, 1);
			
			if (dsimple->deco_height <= 0) {
				errorstream << "register_decoration: simple decoration height"
					" must be greater than 0" << std::endl;
				delete dsimple;
				return 0;
			}

			break; }
		case DECO_SCHEMATIC: {
			//DecoSchematic *decoschematic = (DecoSchematic *)deco;
			
			break; }
		case DECO_LSYSTEM: {
			//DecoLSystem *decolsystem = (DecoLSystem *)deco;
		
			break; }
	}
	
	if (deco->sidelen <= 0) {
		errorstream << "register_decoration: sidelen must be "
			"greater than 0" << std::endl;
		delete deco;
		return 0;
	}
	
	emerge->decorations.push_back(deco);

	verbosestream << "register_decoration: decoration '" << deco->getName()
		<< "' registered" << std::endl;
	return 0;
}
コード例 #19
0
ファイル: c_content.cpp プロジェクト: BobMikfillin/minetest
ContentFeatures read_content_features(lua_State *L, int index)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	ContentFeatures f;

	/* Cache existence of some callbacks */
	lua_getfield(L, index, "on_construct");
	if(!lua_isnil(L, -1)) f.has_on_construct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "on_destruct");
	if(!lua_isnil(L, -1)) f.has_on_destruct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "after_destruct");
	if(!lua_isnil(L, -1)) f.has_after_destruct = true;
	lua_pop(L, 1);

	lua_getfield(L, index, "on_rightclick");
	f.rightclickable = lua_isfunction(L, -1);
	lua_pop(L, 1);
	
	/* Name */
	getstringfield(L, index, "name", f.name);

	/* Groups */
	lua_getfield(L, index, "groups");
	read_groups(L, -1, f.groups);
	lua_pop(L, 1);

	/* Visual definition */

	f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype",
			ScriptApiNode::es_DrawType,NDT_NORMAL);
	getfloatfield(L, index, "visual_scale", f.visual_scale);

	// tiles = {}
	lua_getfield(L, index, "tiles");
	// If nil, try the deprecated name "tile_images" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "tile_images",
				"Deprecated; new name is \"tiles\".");
		lua_getfield(L, index, "tile_images");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef[i] = read_tiledef(L, -1);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==6){
				lua_pop(L, 1);
				break;
			}
		}
		// Copy last value to all remaining textures
		if(i >= 1){
			TileDef lasttile = f.tiledef[i-1];
			while(i < 6){
				f.tiledef[i] = lasttile;
				i++;
			}
		}
	}
	lua_pop(L, 1);

	// special_tiles = {}
	lua_getfield(L, index, "special_tiles");
	// If nil, try the deprecated name "special_materials" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "special_materials",
				"Deprecated; new name is \"special_tiles\".");
		lua_getfield(L, index, "special_materials");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef_special[i] = read_tiledef(L, -1);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==6){
				lua_pop(L, 1);
				break;
			}
		}
	}
	lua_pop(L, 1);

	f.alpha = getintfield_default(L, index, "alpha", 255);

	bool usealpha = getboolfield_default(L, index,
			"use_texture_alpha", false);
	if (usealpha)
		f.alpha = 0;

	/* Other stuff */

	lua_getfield(L, index, "post_effect_color");
	if(!lua_isnil(L, -1))
		f.post_effect_color = readARGB8(L, -1);
	lua_pop(L, 1);

	f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
			ScriptApiNode::es_ContentParamType, CPT_NONE);
	f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
			ScriptApiNode::es_ContentParamType2, CPT2_NONE);

	// Warn about some deprecated fields
	warn_if_field_exists(L, index, "wall_mounted",
			"deprecated: use paramtype2 = 'wallmounted'");
	warn_if_field_exists(L, index, "light_propagates",
			"deprecated: determined from paramtype");
	warn_if_field_exists(L, index, "dug_item",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item_rarity",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "metadata_name",
			"deprecated: use on_add and metadata callbacks");

	// True for all ground-like things like stone and mud, false for eg. trees
	getboolfield(L, index, "is_ground_content", f.is_ground_content);
	f.light_propagates = (f.param_type == CPT_LIGHT);
	getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
	// This is used for collision detection.
	// Also for general solidness queries.
	getboolfield(L, index, "walkable", f.walkable);
	// Player can point to these
	getboolfield(L, index, "pointable", f.pointable);
	// Player can dig these
	getboolfield(L, index, "diggable", f.diggable);
	// Player can climb these
	getboolfield(L, index, "climbable", f.climbable);
	// Player can build on these
	getboolfield(L, index, "buildable_to", f.buildable_to);
	// Whether the node is non-liquid, source liquid or flowing liquid
	f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
			ScriptApiNode::es_LiquidType, LIQUID_NONE);
	// If the content is liquid, this is the flowing version of the liquid.
	getstringfield(L, index, "liquid_alternative_flowing",
			f.liquid_alternative_flowing);
	// If the content is liquid, this is the source version of the liquid.
	getstringfield(L, index, "liquid_alternative_source",
			f.liquid_alternative_source);
	// Viscosity for fluid flow, ranging from 1 to 7, with
	// 1 giving almost instantaneous propagation and 7 being
	// the slowest possible
	f.liquid_viscosity = getintfield_default(L, index,
			"liquid_viscosity", f.liquid_viscosity);
	f.liquid_range = getintfield_default(L, index,
			"liquid_range", f.liquid_range);
	f.leveled = getintfield_default(L, index, "leveled", f.leveled);

	getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
	getstringfield(L, index, "freezemelt", f.freezemelt);
	f.drowning = getintfield_default(L, index,
			"drowning", f.drowning);
	// Amount of light the node emits
	f.light_source = getintfield_default(L, index,
			"light_source", f.light_source);
	f.damage_per_second = getintfield_default(L, index,
			"damage_per_second", f.damage_per_second);

	lua_getfield(L, index, "node_box");
	if(lua_istable(L, -1))
		f.node_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	lua_getfield(L, index, "selection_box");
	if(lua_istable(L, -1))
		f.selection_box = read_nodebox(L, -1);
 	lua_pop(L, 1);

	// Set to true if paramtype used to be 'facedir_simple'
	getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
	// Set to true if wall_mounted used to be set to true
	getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);

	// Sound table
	lua_getfield(L, index, "sounds");
	if(lua_istable(L, -1)){
		lua_getfield(L, -1, "footstep");
		read_soundspec(L, -1, f.sound_footstep);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dig");
		read_soundspec(L, -1, f.sound_dig);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dug");
		read_soundspec(L, -1, f.sound_dug);
		lua_pop(L, 1);
	}
	lua_pop(L, 1);

	return f;
}
コード例 #20
0
ファイル: l_mapgen.cpp プロジェクト: DarkDracoon/minetest
// register_decoration({lots of stuff})
int ModApiMapgen::l_register_decoration(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef      = getServer(L)->getNodeDefManager();
	DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
	BiomeManager *biomemgr     = getServer(L)->getEmergeManager()->biomemgr;
	SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;

	enum DecorationType decotype = (DecorationType)getenumfield(L, index,
				"deco_type", es_DecorationType, -1);

	Decoration *deco = decomgr->create(decotype);
	if (!deco) {
		errorstream << "register_decoration: decoration placement type "
			<< decotype << " not implemented" << std::endl;
		return 0;
	}

	deco->name       = getstringfield_default(L, index, "name", "");
	deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
	deco->y_min      = getintfield_default(L, index, "y_min", -31000);
	deco->y_max      = getintfield_default(L, index, "y_max", 31000);
	deco->nspawnby   = getintfield_default(L, index, "num_spawn_by", -1);
	deco->sidelen    = getintfield_default(L, index, "sidelen", 8);
	if (deco->sidelen <= 0) {
		errorstream << "register_decoration: sidelen must be "
			"greater than 0" << std::endl;
		delete deco;
		return 0;
	}

	//// Get node name(s) to place decoration on
	size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames);
	deco->m_nnlistsizes.push_back(nread);

	//// Get decoration flags
	getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL);

	//// Get NoiseParams to define how decoration is placed
	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &deco->np))
		deco->flags |= DECO_USE_NOISE;
	lua_pop(L, 1);

	//// Get biomes associated with this decoration (if any)
	lua_getfield(L, index, "biomes");
	if (get_biome_list(L, -1, biomemgr, &deco->biomes))
		errorstream << "register_decoration: couldn't get all biomes " << std::endl;
	lua_pop(L, 1);

	//// Get node name(s) to 'spawn by'
	size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames);
	deco->m_nnlistsizes.push_back(nnames);
	if (nnames == 0 && deco->nspawnby != -1) {
		errorstream << "register_decoration: no spawn_by nodes defined,"
			" but num_spawn_by specified" << std::endl;
	}

	//// Handle decoration type-specific parameters
	bool success = false;
	switch (decotype) {
	case DECO_SIMPLE:
		success = read_deco_simple(L, (DecoSimple *)deco);
		break;
	case DECO_SCHEMATIC:
		success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco);
		break;
	case DECO_LSYSTEM:
		break;
	}

	if (!success) {
		delete deco;
		return 0;
	}

	ndef->pendNodeResolve(deco);

	ObjDefHandle handle = decomgr->add(deco);
	if (handle == OBJDEF_INVALID_HANDLE) {
		delete deco;
		return 0;
	}

	lua_pushinteger(L, handle);
	return 1;
}
コード例 #21
0
ファイル: l_mapgen.cpp プロジェクト: DarkDracoon/minetest
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	BiomeManager *bmgr    = getServer(L)->getEmergeManager()->biomemgr;
	OreManager *oremgr    = getServer(L)->getEmergeManager()->oremgr;

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_SCATTER);
	Ore *ore = oremgr->create(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type " << oretype << " not implemented\n";
		return 0;
	}

	ore->name           = getstringfield_default(L, index, "name", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->noise          = NULL;
	ore->flags          = 0;

	//// Get noise_threshold
	warn_if_field_exists(L, index, "noise_threshhold",
		"Deprecated: new name is \"noise_threshold\".");

	float nthresh;
	if (!getfloatfield(L, index, "noise_threshold", nthresh) &&
			!getfloatfield(L, index, "noise_threshhold", nthresh))
		nthresh = 0;
	ore->nthresh = nthresh;

	//// Get y_min/y_max
	warn_if_field_exists(L, index, "height_min",
		"Deprecated: new name is \"y_min\".");
	warn_if_field_exists(L, index, "height_max",
		"Deprecated: new name is \"y_max\".");

	int ymin, ymax;
	if (!getintfield(L, index, "y_min", ymin) &&
		!getintfield(L, index, "height_min", ymin))
		ymin = -31000;
	if (!getintfield(L, index, "y_max", ymax) &&
		!getintfield(L, index, "height_max", ymax))
		ymax = 31000;
	ore->y_min = ymin;
	ore->y_max = ymax;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	//// Get flags
	getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);

	//// Get biomes associated with this decoration (if any)
	lua_getfield(L, index, "biomes");
	if (get_biome_list(L, -1, bmgr, &ore->biomes))
		errorstream << "register_ore: couldn't get all biomes " << std::endl;
	lua_pop(L, 1);

	//// Get noise parameters if needed
	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &ore->np)) {
		ore->flags |= OREFLAG_USE_NOISE;
	} else if (ore->NEEDS_NOISE) {
		errorstream << "register_ore: specified ore type requires valid "
			"noise parameters" << std::endl;
		delete ore;
		return 0;
	}
	lua_pop(L, 1);

	//// Get type-specific parameters
	switch (oretype) {
		case ORE_SHEET: {
			OreSheet *oresheet = (OreSheet *)ore;

			oresheet->column_height_min = getintfield_default(L, index,
				"column_height_min", 1);
			oresheet->column_height_max = getintfield_default(L, index,
				"column_height_max", ore->clust_size);
			oresheet->column_midpoint_factor = getfloatfield_default(L, index,
				"column_midpoint_factor", 0.5f);

			break;
		}
		case ORE_PUFF: {
			OrePuff *orepuff = (OrePuff *)ore;

			lua_getfield(L, index, "np_puff_top");
			read_noiseparams(L, -1, &orepuff->np_puff_top);
			lua_pop(L, 1);

			lua_getfield(L, index, "np_puff_bottom");
			read_noiseparams(L, -1, &orepuff->np_puff_bottom);
			lua_pop(L, 1);

			break;
		}
		case ORE_VEIN: {
			OreVein *orevein = (OreVein *)ore;

			orevein->random_factor = getfloatfield_default(L, index,
				"random_factor", 1.f);

			break;
		}
		default:
			break;
	}

	ObjDefHandle handle = oremgr->add(ore);
	if (handle == OBJDEF_INVALID_HANDLE) {
		delete ore;
		return 0;
	}

	ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", ""));

	size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames);
	ore->m_nnlistsizes.push_back(nnames);

	ndef->pendNodeResolve(ore);

	lua_pushinteger(L, handle);
	return 1;
}
コード例 #22
0
ファイル: l_mapgen.cpp プロジェクト: AnnXGame/Minetest
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	OreManager *oremgr    = getServer(L)->getEmergeManager()->oremgr;

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_TYPE_SCATTER);
	Ore *ore = oremgr->create(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type " << oretype << " not implemented";
		return 0;
	}

	ore->name           = getstringfield_default(L, index, "name", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0);
	ore->noise          = NULL;
	ore->flags          = 0;

	warn_if_field_exists(L, index, "height_min",
		"Deprecated: new name is \"y_min\".");
	warn_if_field_exists(L, index, "height_max",
		"Deprecated: new name is \"y_max\".");

	int ymin, ymax;
	if (!getintfield(L, index, "y_min", ymin) &&
		!getintfield(L, index, "height_min", ymin))
		ymin = -31000;
	if (!getintfield(L, index, "y_max", ymax) &&
		!getintfield(L, index, "height_max", ymax))
		ymax = 31000;
	ore->y_min = ymin;
	ore->y_max = ymax;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);

	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &ore->np)) {
		ore->flags |= OREFLAG_USE_NOISE;
	} else if (ore->NEEDS_NOISE) {
		errorstream << "register_ore: specified ore type requires valid "
			"noise parameters" << std::endl;
		delete ore;
		return 0;
	}
	lua_pop(L, 1);

	if (oretype == ORE_TYPE_VEIN) {
		OreVein *orevein = (OreVein *)ore;
		orevein->random_factor = getfloatfield_default(L, index,
			"random_factor", 1.f);
	}

	u32 id = oremgr->add(ore);
	if (id == (u32)-1) {
		delete ore;
		return 0;
	}

	NodeResolveInfo *nri = new NodeResolveInfo(ore);
	nri->nodenames.push_back(getstringfield_default(L, index, "ore", ""));

	std::vector<const char *> wherein_names;
	getstringlistfield(L, index, "wherein", wherein_names);
	nri->nodelistinfo.push_back(NodeListInfo(wherein_names.size()));
	for (size_t i = 0; i != wherein_names.size(); i++)
		nri->nodenames.push_back(wherein_names[i]);

	ndef->pendNodeResolve(nri);

	verbosestream << "register_ore: " << ore->name << std::endl;

	lua_pushinteger(L, id);
	return 1;
}
コード例 #23
0
ファイル: l_mapgen.cpp プロジェクト: Emu4Play/minetest
// register_decoration({lots of stuff})
int ModApiMapgen::l_register_decoration(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

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

	enum DecorationType decotype = (DecorationType)getenumfield(L, index,
				"deco_type", es_DecorationType, -1);
	if (decotype == -1) {
		errorstream << "register_decoration: unrecognized "
			"decoration placement type";
		return 0;
	}

	Decoration *deco = createDecoration(decotype);
	if (!deco) {
		errorstream << "register_decoration: decoration placement type "
			<< decotype << " not implemented";
		return 0;
	}

	deco->c_place_on    = CONTENT_IGNORE;
	deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
	deco->fill_ratio    = getfloatfield_default(L, index, "fill_ratio", 0.02);
	deco->sidelen       = getintfield_default(L, index, "sidelen", 8);
	if (deco->sidelen <= 0) {
		errorstream << "register_decoration: sidelen must be "
			"greater than 0" << std::endl;
		delete deco;
		return 0;
	}

	lua_getfield(L, index, "noise_params");
	deco->np = read_noiseparams(L, -1);
	lua_pop(L, 1);

	lua_getfield(L, index, "biomes");
	if (lua_istable(L, -1)) {
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			const char *s = lua_tostring(L, -1);
			u8 biomeid = bdef->getBiomeIdByName(s);
			if (biomeid)
				deco->biomes.insert(biomeid);

			lua_pop(L, 1);
		}
		lua_pop(L, 1);
	}

	switch (decotype) {
		case DECO_SIMPLE: {
			DecoSimple *dsimple = (DecoSimple *)deco;
			dsimple->c_deco     = CONTENT_IGNORE;
			dsimple->c_spawnby  = CONTENT_IGNORE;
			dsimple->spawnby_name    = getstringfield_default(L, index, "spawn_by", "air");
			dsimple->deco_height     = getintfield_default(L, index, "height", 1);
			dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
			dsimple->nspawnby        = getintfield_default(L, index, "num_spawn_by", -1);

			lua_getfield(L, index, "decoration");
			if (lua_istable(L, -1)) {
				lua_pushnil(L);
				while (lua_next(L, -2)) {
					const char *s = lua_tostring(L, -1);
					std::string str(s);
					dsimple->decolist_names.push_back(str);

					lua_pop(L, 1);
				}
			} else if (lua_isstring(L, -1)) {
				dsimple->deco_name = std::string(lua_tostring(L, -1));
			} else {
				dsimple->deco_name = std::string("air");
			}
			lua_pop(L, 1);

			if (dsimple->deco_height <= 0) {
				errorstream << "register_decoration: simple decoration height"
					" must be greater than 0" << std::endl;
				delete dsimple;
				return 0;
			}

			break; }
		case DECO_SCHEMATIC: {
			DecoSchematic *dschem = (DecoSchematic *)deco;

			dschem->flags = 0;
			getflagsfield(L, index, "flags", flagdesc_deco_schematic,
				&dschem->flags, NULL);

			dschem->rotation = (Rotation)getenumfield(L, index,
				"rotation", es_Rotation, ROTATE_0);

			lua_getfield(L, index, "replacements");
			if (lua_istable(L, -1)) {
				int i = lua_gettop(L);
				lua_pushnil(L);
				while (lua_next(L, i) != 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);
				}
			}
			lua_pop(L, 1);

			lua_getfield(L, index, "schematic");
			if (!read_schematic(L, -1, dschem, getServer(L))) {
				delete dschem;
				return 0;
			}
			lua_pop(L, -1);

			if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
				errorstream << "register_decoration: failed to load schematic file '"
					<< dschem->filename << "'" << std::endl;
				delete dschem;
				return 0;
			}
			break; }
		case DECO_LSYSTEM: {
			//DecoLSystem *decolsystem = (DecoLSystem *)deco;

			break; }
	}

	emerge->decorations.push_back(deco);

	verbosestream << "register_decoration: decoration '" << deco->getName()
		<< "' registered" << std::endl;
	return 0;
}
コード例 #24
0
ファイル: l_mapgen.cpp プロジェクト: AnnXGame/Minetest
// register_decoration({lots of stuff})
int ModApiMapgen::l_register_decoration(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef      = getServer(L)->getNodeDefManager();
	DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
	BiomeManager *biomemgr     = getServer(L)->getEmergeManager()->biomemgr;

	enum DecorationType decotype = (DecorationType)getenumfield(L, index,
				"deco_type", es_DecorationType, -1);

	Decoration *deco = decomgr->create(decotype);
	if (!deco) {
		errorstream << "register_decoration: decoration placement type "
			<< decotype << " not implemented";
		return 0;
	}

	deco->name       = getstringfield_default(L, index, "name", "");
	deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
	deco->y_min      = getintfield_default(L, index, "y_min", -31000);
	deco->y_max      = getintfield_default(L, index, "y_max", 31000);
	deco->sidelen    = getintfield_default(L, index, "sidelen", 8);
	if (deco->sidelen <= 0) {
		errorstream << "register_decoration: sidelen must be "
			"greater than 0" << std::endl;
		delete deco;
		return 0;
	}

	NodeResolveInfo *nri = new NodeResolveInfo(deco);

	//// Get node name(s) to place decoration on
	std::vector<const char *> place_on_names;
	getstringlistfield(L, index, "place_on", place_on_names);
	nri->nodelistinfo.push_back(NodeListInfo(place_on_names.size()));
	for (size_t i = 0; i != place_on_names.size(); i++)
		nri->nodenames.push_back(place_on_names[i]);

	getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL);

	//// Get NoiseParams to define how decoration is placed
	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &deco->np))
		deco->flags |= DECO_USE_NOISE;
	lua_pop(L, 1);

	//// Get biomes associated with this decoration (if any)
	std::vector<const char *> biome_list;
	getstringlistfield(L, index, "biomes", biome_list);
	for (size_t i = 0; i != biome_list.size(); i++) {
		Biome *b = (Biome *)biomemgr->getByName(biome_list[i]);
		if (!b)
			continue;

		deco->biomes.insert(b->id);
	}

	//// Handle decoration type-specific parameters
	bool success = false;
	switch (decotype) {
		case DECO_SIMPLE:
			success = regDecoSimple(L, nri, (DecoSimple *)deco);
			break;
		case DECO_SCHEMATIC:
			success = regDecoSchematic(L, ndef, (DecoSchematic *)deco);
			break;
		case DECO_LSYSTEM:
			break;
	}

	ndef->pendNodeResolve(nri);

	if (!success) {
		delete deco;
		return 0;
	}

	u32 id = decomgr->add(deco);
	if (id == (u32)-1) {
		delete deco;
		return 0;
	}

	verbosestream << "register_decoration: " << deco->name << std::endl;

	lua_pushinteger(L, id);
	return 1;
}
コード例 #25
0
ContentFeatures read_content_features(lua_State *L, int index)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	ContentFeatures f;

	/* Cache existence of some callbacks */
	lua_getfield(L, index, "on_construct");
	if(!lua_isnil(L, -1)) f.has_on_construct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "on_destruct");
	if(!lua_isnil(L, -1)) f.has_on_destruct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "after_destruct");
	if(!lua_isnil(L, -1)) f.has_after_destruct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "on_activate");
	if(!lua_isnil(L, -1))
	{
		f.has_on_activate = true;
		f.is_circuit_element = true;
	}
	lua_pop(L, 1);
	lua_getfield(L, index, "on_deactivate");
	if(!lua_isnil(L, -1))
	{
		f.has_on_deactivate = true;
		f.is_circuit_element = true;
	}
	lua_pop(L, 1);

	lua_getfield(L, index, "on_rightclick");
	f.rightclickable = lua_isfunction(L, -1);
	lua_pop(L, 1);

	/* Name */
	getstringfield(L, index, "name", f.name);

	/* Groups */
	lua_getfield(L, index, "groups");
	read_groups(L, -1, f.groups);
	lua_pop(L, 1);

	/* Visual definition */

	f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype",
			ScriptApiNode::es_DrawType,NDT_NORMAL);
	getfloatfield(L, index, "visual_scale", f.visual_scale);

	/* Meshnode model filename */
	getstringfield(L, index, "mesh", f.mesh);

	// tiles = {}
	lua_getfield(L, index, "tiles");
	// If nil, try the deprecated name "tile_images" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "tile_images",
				"Deprecated; new name is \"tiles\".");
		lua_getfield(L, index, "tile_images");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef[i] = read_tiledef(L, -1);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==6){
				lua_pop(L, 1);
				break;
			}
		}
		// Copy last value to all remaining textures
		if(i >= 1){
			TileDef lasttile = f.tiledef[i-1];
			while(i < 6){
				f.tiledef[i] = lasttile;
				i++;
			}
		}
	}
	lua_pop(L, 1);
	
	/* Circuit options */
	lua_getfield(L, index, "is_wire");
	if(!lua_isnil(L, -1)) {
		f.is_wire = true;
	}
	lua_pop(L, 1);
	
	lua_getfield(L, index, "is_wire_connector");
	if(!lua_isnil(L, -1)) {
		f.is_wire_connector = true;
	}
	lua_pop(L, 1);
	
	lua_getfield(L, index, "wire_connections");
	if(!lua_isnil(L, -1) && lua_istable(L, -1)) {
		// Both can't be set to true
		f.is_wire |= !f.is_wire_connector;
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i;
		unsigned char current_shift = 1;
		for(i = 0; (i < 6) && (lua_next(L, table) != 0); ++i) {
			f.wire_connections[i] = lua_tonumber(L, -1);
			f.wire_connections[i] |= current_shift;
			current_shift <<= 1;
			lua_pop(L, 1);
		}
		if(i < 6) {
			luaL_error(L, "Wire connectins array must have exactly 6 integer numbers.");
		}

		// Convert to two-way wire (one-way may cause undefined behavior)
		for(i = 0; i < 6; ++i) {
			for(int j = 0; j < 6; ++j) {
				f.wire_connections[i] |= f.wire_connections[j] & (1 << i);
				f.wire_connections[j] |= f.wire_connections[i] & (1 << j);
			}
		}
		
	} else if(f.is_wire || f.is_wire_connector) {
		// Assuming that it's a standart wire or wire connector
		for(int i = 0; i < 6; ++i) {
			f.wire_connections[i] = 0x3F;
		}
	}
	lua_pop(L, 1);
	
	lua_getfield(L, index, "circuit_states");
	if(!lua_isnil(L, -1) && lua_istable(L, -1)) {
		f.is_circuit_element = true;
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i;
		for(i = 0; (i < 64) && (lua_next(L, table) != 0); ++i) {
			f.circuit_element_func[i] = lua_tonumber(L, -1);
			lua_pop(L, 1);
		}
		if(i < 64) {
			luaL_error(L, "Circuit element states table must have exactly 64 integer numbers.");
		}
	}
	lua_pop(L, 1);

	f.circuit_element_delay = getintfield_default(L, index, "circuit_element_delay", f.circuit_element_delay + 1) - 1;
	if(f.circuit_element_delay > 100) {
		luaL_error(L, "\"circuit_element_delay\" must be a positive integer number less than 101");
	}

	// special_tiles = {}
	lua_getfield(L, index, "special_tiles");
	// If nil, try the deprecated name "special_materials" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "special_materials",
				"Deprecated; new name is \"special_tiles\".");
		lua_getfield(L, index, "special_materials");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef_special[i] = read_tiledef(L, -1);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==CF_SPECIAL_COUNT){
				lua_pop(L, 1);
				break;
			}
		}
	}
	lua_pop(L, 1);

	f.alpha = getintfield_default(L, index, "alpha", 255);

	bool usealpha = getboolfield_default(L, index,
			"use_texture_alpha", false);
	if (usealpha)
		f.alpha = 0;

	/* Other stuff */

	lua_getfield(L, index, "post_effect_color");
	if(!lua_isnil(L, -1))
		f.post_effect_color = readARGB8(L, -1);
	lua_pop(L, 1);

	f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
			ScriptApiNode::es_ContentParamType, CPT_NONE);
	f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
			ScriptApiNode::es_ContentParamType2, CPT2_NONE);

	// Warn about some deprecated fields
	warn_if_field_exists(L, index, "wall_mounted",
			"deprecated: use paramtype2 = 'wallmounted'");
	warn_if_field_exists(L, index, "light_propagates",
			"deprecated: determined from paramtype");
	warn_if_field_exists(L, index, "dug_item",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item_rarity",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "metadata_name",
			"deprecated: use on_add and metadata callbacks");

	// True for all ground-like things like stone and mud, false for eg. trees
	getboolfield(L, index, "is_ground_content", f.is_ground_content);
	f.light_propagates = (f.param_type == CPT_LIGHT);
	getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
	// This is used for collision detection.
	// Also for general solidness queries.
	getboolfield(L, index, "walkable", f.walkable);
	// Player can point to these
	getboolfield(L, index, "pointable", f.pointable);
	// Player can dig these
	getboolfield(L, index, "diggable", f.diggable);
	// Player can climb these
	getboolfield(L, index, "climbable", f.climbable);
	// Player can build on these
	getboolfield(L, index, "buildable_to", f.buildable_to);
	// Whether the node is non-liquid, source liquid or flowing liquid
	f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
			ScriptApiNode::es_LiquidType, LIQUID_NONE);
	// If the content is liquid, this is the flowing version of the liquid.
	getstringfield(L, index, "liquid_alternative_flowing",
			f.liquid_alternative_flowing);
	// If the content is liquid, this is the source version of the liquid.
	getstringfield(L, index, "liquid_alternative_source",
			f.liquid_alternative_source);
	// Viscosity for fluid flow, ranging from 1 to 7, with
	// 1 giving almost instantaneous propagation and 7 being
	// the slowest possible
	f.liquid_viscosity = getintfield_default(L, index,
			"liquid_viscosity", f.liquid_viscosity);

	f.leveled = getintfield_default(L, index, "leveled", f.leveled);

	getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
	getstringfield(L, index, "freeze", f.freeze);
	getstringfield(L, index, "melt", f.melt);
	f.drowning = getintfield_default(L, index,
			"drowning", f.drowning);
	// Amount of light the node emits
	f.light_source = getintfield_default(L, index,
			"light_source", f.light_source);
	f.damage_per_second = getintfield_default(L, index,
			"damage_per_second", f.damage_per_second);

	lua_getfield(L, index, "node_box");
	if(lua_istable(L, -1))
		f.node_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	lua_getfield(L, index, "selection_box");
	if(lua_istable(L, -1))
		f.selection_box = read_nodebox(L, -1);
 	lua_pop(L, 1);

	lua_getfield(L, index, "collision_box");
	if(lua_istable(L, -1))
		f.collision_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	f.waving = getintfield_default(L, index,
			"waving", f.waving);

	// Set to true if paramtype used to be 'facedir_simple'
	getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
	// Set to true if wall_mounted used to be set to true
	getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);

	// Sound table
	lua_getfield(L, index, "sounds");
	if(lua_istable(L, -1)){
		lua_getfield(L, -1, "footstep");
		read_soundspec(L, -1, f.sound_footstep);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dig");
		read_soundspec(L, -1, f.sound_dig);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dug");
		read_soundspec(L, -1, f.sound_dug);
		lua_pop(L, 1);
	}
	lua_pop(L, 1);

	return f;
}
コード例 #26
0
ファイル: c_content.cpp プロジェクト: JJ/minetest
TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	TileDef tiledef;

	bool default_tiling = true;
	bool default_culling = true;
	switch (drawtype) {
		case NDT_PLANTLIKE:
		case NDT_FIRELIKE:
			default_tiling = false;
			// "break" is omitted here intentionaly, as PLANTLIKE
			// FIRELIKE drawtype both should default to having
			// backface_culling to false.
		case NDT_MESH:
		case NDT_LIQUID:
			default_culling = false;
			break;
		default:
			break;
	}

	// key at index -2 and value at index
	if(lua_isstring(L, index)){
		// "default_lava.png"
		tiledef.name = lua_tostring(L, index);
		tiledef.tileable_vertical = default_tiling;
		tiledef.tileable_horizontal = default_tiling;
		tiledef.backface_culling = default_culling;
	}
	else if(lua_istable(L, index))
	{
		// {name="default_lava.png", animation={}}
		tiledef.name = "";
		getstringfield(L, index, "name", tiledef.name);
		getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
		tiledef.backface_culling = getboolfield_default(
			L, index, "backface_culling", default_culling);
		tiledef.tileable_horizontal = getboolfield_default(
			L, index, "tileable_horizontal", default_tiling);
		tiledef.tileable_vertical = getboolfield_default(
			L, index, "tileable_vertical", default_tiling);
		// animation = {}
		lua_getfield(L, index, "animation");
		if(lua_istable(L, -1)){
			// {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
			tiledef.animation.type = (TileAnimationType)
				getenumfield(L, -1, "type", es_TileAnimationType,
				TAT_NONE);
			tiledef.animation.aspect_w =
				getintfield_default(L, -1, "aspect_w", 16);
			tiledef.animation.aspect_h =
				getintfield_default(L, -1, "aspect_h", 16);
			tiledef.animation.length =
				getfloatfield_default(L, -1, "length", 1.0);
		}
		lua_pop(L, 1);
	}

	return tiledef;
}
コード例 #27
0
ファイル: l_mapgen.cpp プロジェクト: guijun/minetest
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	OreManager *oremgr    = getServer(L)->getEmergeManager()->oremgr;

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_SCATTER);
	Ore *ore = oremgr->create(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type " << oretype << " not implemented";
		return 0;
	}

	ore->name           = getstringfield_default(L, index, "name", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0);
	ore->noise          = NULL;
	ore->flags          = 0;

	warn_if_field_exists(L, index, "height_min",
		"Deprecated: new name is \"y_min\".");
	warn_if_field_exists(L, index, "height_max",
		"Deprecated: new name is \"y_max\".");

	int ymin, ymax;
	if (!getintfield(L, index, "y_min", ymin) &&
		!getintfield(L, index, "height_min", ymin))
		ymin = -31000;
	if (!getintfield(L, index, "y_max", ymax) &&
		!getintfield(L, index, "height_max", ymax))
		ymax = 31000;
	ore->y_min = ymin;
	ore->y_max = ymax;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);

	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &ore->np)) {
		ore->flags |= OREFLAG_USE_NOISE;
	} else if (ore->NEEDS_NOISE) {
		errorstream << "register_ore: specified ore type requires valid "
			"noise parameters" << std::endl;
		delete ore;
		return 0;
	}
	lua_pop(L, 1);

	if (oretype == ORE_VEIN) {
		OreVein *orevein = (OreVein *)ore;
		orevein->random_factor = getfloatfield_default(L, index,
			"random_factor", 1.f);
	}

	ObjDefHandle handle = oremgr->add(ore);
	if (handle == OBJDEF_INVALID_HANDLE) {
		delete ore;
		return 0;
	}

	ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", ""));

	size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames);
	ore->m_nnlistsizes.push_back(nnames);

	ndef->pendNodeResolve(ore, NODE_RESOLVE_DEFERRED);

	lua_pushinteger(L, handle);
	return 1;
}
コード例 #28
0
ファイル: c_content.cpp プロジェクト: kaeza/minetest
ContentFeatures read_content_features(lua_State *L, int index)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	ContentFeatures f;

	/* Cache existence of some callbacks */
	lua_getfield(L, index, "on_construct");
	if(!lua_isnil(L, -1)) f.has_on_construct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "on_destruct");
	if(!lua_isnil(L, -1)) f.has_on_destruct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "after_destruct");
	if(!lua_isnil(L, -1)) f.has_after_destruct = true;
	lua_pop(L, 1);

	lua_getfield(L, index, "on_rightclick");
	f.rightclickable = lua_isfunction(L, -1);
	lua_pop(L, 1);

	/* Name */
	getstringfield(L, index, "name", f.name);

	/* Groups */
	lua_getfield(L, index, "groups");
	read_groups(L, -1, f.groups);
	lua_pop(L, 1);

	/* Visual definition */

	f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype",
			ScriptApiNode::es_DrawType,NDT_NORMAL);
	getfloatfield(L, index, "visual_scale", f.visual_scale);

	/* Meshnode model filename */
	getstringfield(L, index, "mesh", f.mesh);

	// tiles = {}
	lua_getfield(L, index, "tiles");
	// If nil, try the deprecated name "tile_images" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "tile_images",
				"Deprecated; new name is \"tiles\".");
		lua_getfield(L, index, "tile_images");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef[i] = read_tiledef(L, -1, f.drawtype);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==6){
				lua_pop(L, 1);
				break;
			}
		}
		// Copy last value to all remaining textures
		if(i >= 1){
			TileDef lasttile = f.tiledef[i-1];
			while(i < 6){
				f.tiledef[i] = lasttile;
				i++;
			}
		}
	}
	lua_pop(L, 1);

	// special_tiles = {}
	lua_getfield(L, index, "special_tiles");
	// If nil, try the deprecated name "special_materials" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "special_materials",
				"Deprecated; new name is \"special_tiles\".");
		lua_getfield(L, index, "special_materials");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef_special[i] = read_tiledef(L, -1, f.drawtype);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==CF_SPECIAL_COUNT){
				lua_pop(L, 1);
				break;
			}
		}
	}
	lua_pop(L, 1);

	f.alpha = getintfield_default(L, index, "alpha", 255);

	bool usealpha = getboolfield_default(L, index,
			"use_texture_alpha", false);
	if (usealpha)
		f.alpha = 0;

	// Read node color.
	lua_getfield(L, index, "color");
	read_color(L, -1, &f.color);
	lua_pop(L, 1);

	getstringfield(L, index, "palette", f.palette_name);

	/* Other stuff */

	lua_getfield(L, index, "post_effect_color");
	read_color(L, -1, &f.post_effect_color);
	lua_pop(L, 1);

	f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
			ScriptApiNode::es_ContentParamType, CPT_NONE);
	f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
			ScriptApiNode::es_ContentParamType2, CPT2_NONE);

	if (f.palette_name != "" &&
			!(f.param_type_2 == CPT2_COLOR ||
			f.param_type_2 == CPT2_COLORED_FACEDIR ||
			f.param_type_2 == CPT2_COLORED_WALLMOUNTED))
		warningstream << "Node " << f.name.c_str()
			<< " has a palette, but not a suitable paramtype2." << std::endl;

	// Warn about some deprecated fields
	warn_if_field_exists(L, index, "wall_mounted",
			"Deprecated; use paramtype2 = 'wallmounted'");
	warn_if_field_exists(L, index, "light_propagates",
			"Deprecated; determined from paramtype");
	warn_if_field_exists(L, index, "dug_item",
			"Deprecated; use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item",
			"Deprecated; use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item_rarity",
			"Deprecated; use 'drop' field");
	warn_if_field_exists(L, index, "metadata_name",
			"Deprecated; use on_add and metadata callbacks");

	// True for all ground-like things like stone and mud, false for eg. trees
	getboolfield(L, index, "is_ground_content", f.is_ground_content);
	f.light_propagates = (f.param_type == CPT_LIGHT);
	getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
	// This is used for collision detection.
	// Also for general solidness queries.
	getboolfield(L, index, "walkable", f.walkable);
	// Player can point to these
	getboolfield(L, index, "pointable", f.pointable);
	// Player can dig these
	getboolfield(L, index, "diggable", f.diggable);
	// Player can climb these
	getboolfield(L, index, "climbable", f.climbable);
	// Player can build on these
	getboolfield(L, index, "buildable_to", f.buildable_to);
	// Liquids flow into and replace node
	getboolfield(L, index, "floodable", f.floodable);
	// Whether the node is non-liquid, source liquid or flowing liquid
	f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
			ScriptApiNode::es_LiquidType, LIQUID_NONE);
	// If the content is liquid, this is the flowing version of the liquid.
	getstringfield(L, index, "liquid_alternative_flowing",
			f.liquid_alternative_flowing);
	// If the content is liquid, this is the source version of the liquid.
	getstringfield(L, index, "liquid_alternative_source",
			f.liquid_alternative_source);
	// Viscosity for fluid flow, ranging from 1 to 7, with
	// 1 giving almost instantaneous propagation and 7 being
	// the slowest possible
	f.liquid_viscosity = getintfield_default(L, index,
			"liquid_viscosity", f.liquid_viscosity);
	f.liquid_range = getintfield_default(L, index,
			"liquid_range", f.liquid_range);
	f.leveled = getintfield_default(L, index, "leveled", f.leveled);

	getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
	f.drowning = getintfield_default(L, index,
			"drowning", f.drowning);
	// Amount of light the node emits
	f.light_source = getintfield_default(L, index,
			"light_source", f.light_source);
	if (f.light_source > LIGHT_MAX) {
		warningstream << "Node " << f.name.c_str()
			<< " had greater light_source than " << LIGHT_MAX
			<< ", it was reduced." << std::endl;
		f.light_source = LIGHT_MAX;
	}
	f.damage_per_second = getintfield_default(L, index,
			"damage_per_second", f.damage_per_second);

	lua_getfield(L, index, "node_box");
	if(lua_istable(L, -1))
		f.node_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	lua_getfield(L, index, "connects_to");
	if (lua_istable(L, -1)) {
		int table = lua_gettop(L);
		lua_pushnil(L);
		while (lua_next(L, table) != 0) {
			// Value at -1
			f.connects_to.push_back(lua_tostring(L, -1));
			lua_pop(L, 1);
		}
	}
	lua_pop(L, 1);

	lua_getfield(L, index, "connect_sides");
	if (lua_istable(L, -1)) {
		int table = lua_gettop(L);
		lua_pushnil(L);
		while (lua_next(L, table) != 0) {
			// Value at -1
			std::string side(lua_tostring(L, -1));
			// Note faces are flipped to make checking easier
			if (side == "top")
				f.connect_sides |= 2;
			else if (side == "bottom")
				f.connect_sides |= 1;
			else if (side == "front")
				f.connect_sides |= 16;
			else if (side == "left")
				f.connect_sides |= 32;
			else if (side == "back")
				f.connect_sides |= 4;
			else if (side == "right")
				f.connect_sides |= 8;
			else
				warningstream << "Unknown value for \"connect_sides\": "
					<< side << std::endl;
			lua_pop(L, 1);
		}
	}
	lua_pop(L, 1);

	lua_getfield(L, index, "selection_box");
	if(lua_istable(L, -1))
		f.selection_box = read_nodebox(L, -1);
 	lua_pop(L, 1);

	lua_getfield(L, index, "collision_box");
	if(lua_istable(L, -1))
		f.collision_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	f.waving = getintfield_default(L, index,
			"waving", f.waving);

	// Set to true if paramtype used to be 'facedir_simple'
	getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
	// Set to true if wall_mounted used to be set to true
	getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);

	// Sound table
	lua_getfield(L, index, "sounds");
	if(lua_istable(L, -1)){
		lua_getfield(L, -1, "footstep");
		read_soundspec(L, -1, f.sound_footstep);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dig");
		read_soundspec(L, -1, f.sound_dig);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dug");
		read_soundspec(L, -1, f.sound_dug);
		lua_pop(L, 1);
	}
	lua_pop(L, 1);

	return f;
}