code:
-- farming/nodes.lua

-- support for MT game translation.
local S = farming.get_translator

minetest.override_item("default:dirt", {
	soil = {
		base = "default:dirt",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.override_item("default:dirt_with_grass", {
	soil = {
		base = "default:dirt_with_grass",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.override_item("default:dirt_with_dry_grass", {
	soil = {
		base = "default:dirt_with_dry_grass",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.override_item("default:dirt_with_rainforest_litter", {
	soil = {
		base = "default:dirt_with_rainforest_litter",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.override_item("default:dirt_with_coniferous_litter", {
	soil = {
		base = "default:dirt_with_coniferous_litter",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.override_item("default:dry_dirt", {
	soil = {
		base = "default:dry_dirt",
		dry = "farming:dry_soil",
		wet = "farming:dry_soil_wet"
	}
})

minetest.override_item("default:dry_dirt_with_dry_grass", {
	soil = {
		base = "default:dry_dirt_with_dry_grass",
		dry = "farming:dry_soil",
		wet = "farming:dry_soil_wet"
	}
})

minetest.register_node("farming:soil", {
	description = S("Soil"),
	tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"},
	drop = "default:dirt",
	groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1, field = 1},
	sounds = default.node_sound_dirt_defaults(),
	soil = {
		base = "default:dirt",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.register_node("farming:soil_wet", {
	description = S("Wet Soil"),
	tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"},
	drop = "default:dirt",
	groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1, field = 1},
	sounds = default.node_sound_dirt_defaults(),
	soil = {
		base = "default:dirt",
		dry = "farming:soil",
		wet = "farming:soil_wet"
	}
})

minetest.register_node("farming:dry_soil", {
	description = S("Savanna Soil"),
	tiles = {"default_dry_dirt.png^farming_soil.png", "default_dry_dirt.png"},
	drop = "default:dry_dirt",
	groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1, field = 1},
	sounds = default.node_sound_dirt_defaults(),
	soil = {
		base = "default:dry_dirt",
		dry = "farming:dry_soil",
		wet = "farming:dry_soil_wet"
	}
})

minetest.register_node("farming:dry_soil_wet", {
	description = S("Wet Savanna Soil"),
	tiles = {"default_dry_dirt.png^farming_soil_wet.png", "default_dry_dirt.png^farming_soil_wet_side.png"},
	drop = "default:dry_dirt",
	groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1, field = 1},
	sounds = default.node_sound_dirt_defaults(),
	soil = {
		base = "default:dry_dirt",
		dry = "farming:dry_soil",
		wet = "farming:dry_soil_wet"
	}
})

minetest.override_item("default:desert_sand", {
	groups = {crumbly=3, falling_node=1, sand=1, soil = 1},
	soil = {
		base = "default:desert_sand",
		dry = "farming:desert_sand_soil",
		wet = "farming:desert_sand_soil_wet"
	}
})
minetest.register_node("farming:desert_sand_soil", {
	description = S("Desert Sand Soil"),
	drop = "default:desert_sand",
	tiles = {"farming_desert_sand_soil.png", "default_desert_sand.png"},
	groups = {crumbly=3, not_in_creative_inventory = 1, falling_node=1, sand=1, soil = 2, desert = 1, field = 1},
	sounds = default.node_sound_sand_defaults(),
	soil = {
		base = "default:desert_sand",
		dry = "farming:desert_sand_soil",
		wet = "farming:desert_sand_soil_wet"
	}
})

minetest.register_node("farming:desert_sand_soil_wet", {
	description = S("Wet Desert Sand Soil"),
	drop = "default:desert_sand",
	tiles = {"farming_desert_sand_soil_wet.png", "farming_desert_sand_soil_wet_side.png"},
	groups = {crumbly=3, falling_node=1, sand=1, not_in_creative_inventory=1, soil=3, wet = 1, desert = 1, field = 1},
	sounds = default.node_sound_sand_defaults(),
	soil = {
		base = "default:desert_sand",
		dry = "farming:desert_sand_soil",
		wet = "farming:desert_sand_soil_wet"
	}
})

minetest.register_node("farming:straw", {
	description = S("Straw"),
	tiles = {"farming_straw.png"},
	is_ground_content = false,
	groups = {snappy=3, flammable=4, fall_damage_add_percent=-30},
	sounds = default.node_sound_leaves_defaults(),
})

-- Registered before the stairs so the stairs get fuel recipes.
minetest.register_craft({
	type = "fuel",
	recipe = "farming:straw",
	burntime = 3,
})

do
	local recipe = "farming:straw"
	local groups = {snappy = 3, flammable = 4}
	local images = {"farming_straw.png"}
	local sounds = default.node_sound_leaves_defaults()

	stairs.register_stair("straw", recipe, groups, images, S("Straw Stair"),
		sounds, true)
	stairs.register_stair_inner("straw", recipe, groups, images, "",
		sounds, true, S("Inner Straw Stair"))
	stairs.register_stair_outer("straw", recipe, groups, images, "",
		sounds, true, S("Outer Straw Stair"))
	stairs.register_slab("straw", recipe, groups, images, S("Straw Slab"),
		sounds, true)
end

minetest.register_abm({
	label = "Farming soil",
	nodenames = {"group:field"},
	interval = 15,
	chance = 4,
	action = function(pos, node)
		local n_def = minetest.registered_nodes[node.name] or nil
		local wet = n_def.soil.wet or nil
		local base = n_def.soil.base or nil
		local dry = n_def.soil.dry or nil
		if not n_def or not n_def.soil or not wet or not base or not dry then
			return
		end

		pos.y = pos.y + 1
		local nn = minetest.get_node_or_nil(pos)
		if not nn or not nn.name then
			return
		end
		local nn_def = minetest.registered_nodes[nn.name] or nil
		pos.y = pos.y - 1

		if nn_def and nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0 then
			minetest.set_node(pos, {name = base})
			return
		end
		-- check if there is water nearby
		local wet_lvl = minetest.get_item_group(node.name, "wet")
		if minetest.find_node_near(pos, 3, {"group:water"}) then
			-- if it is dry soil and not base node, turn it into wet soil
			if wet_lvl == 0 then
				minetest.set_node(pos, {name = wet})
			end
		else
			-- only turn back if there are no unloaded blocks (and therefore
			-- possible water sources) nearby
			if not minetest.find_node_near(pos, 3, {"ignore"}) then
				-- turn it back into base if it is already dry
				if wet_lvl == 0 then
					-- only turn it back if there is no plant/seed on top of it
					if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then
						minetest.set_node(pos, {name = base})
					end

				-- if its wet turn it back into dry soil
				elseif wet_lvl == 1 then
					minetest.set_node(pos, {name = dry})
				end
			end
		end
	end,
})

-- Make default:grass_* occasionally drop wheat seed

for i = 1, 5 do
	minetest.override_item("default:grass_"..i, {drop = {
		max_items = 1,
		items = {
			{items = {"farming:seed_wheat"}, rarity = 5},
			{items = {"default:grass_1"}},
		}
	}})
end

-- Make default:junglegrass occasionally drop cotton seed.

-- This is the old source of cotton seeds that makes no sense. It is a leftover
-- from Mapgen V6 where junglegrass was the only plant available to be a source.
-- This source is kept for now to avoid disruption but should probably be
-- removed in future as players get used to the new source.

minetest.override_item("default:junglegrass", {drop = {
	max_items = 1,
	items = {
		{items = {"farming:seed_cotton"}, rarity = 8},
		{items = {"default:junglegrass"}},
	}
}})

-- Wild cotton as a source of cotton seed

minetest.register_node("farming:cotton_wild", {
	description = S("Wild Cotton"),
	drawtype = "plantlike",
	waving = 1,
	tiles = {"farming_cotton_wild.png"},
	inventory_image = "farming_cotton_wild.png",
	wield_image = "farming_cotton_wild.png",
	paramtype = "light",
	sunlight_propagates = true,
	walkable = false,
	buildable_to = true,
	groups = {snappy = 3, attached_node = 1, flammable = 4},
	drop = "farming:seed_cotton",
	sounds = default.node_sound_leaves_defaults(),
	selection_box = {
		type = "fixed",
		fixed = {-6 / 16, -8 / 16, -6 / 16, 6 / 16, 5 / 16, 6 / 16},
	},
})


code:
Minetest Game mod: fire
=======================
See license.txt for license information.

Authors of source code
----------------------
Originally by Perttu Ahola (celeron55) <celeron55@gmail.com> (LGPLv2.1+)
Various Minetest developers and contributors (LGPLv2.1+)

Authors of media (textures and sounds)
--------------------------------------
Everything not listed in here:
Copyright (C) 2012 Perttu Ahola (celeron55) <celeron55@gmail.com> (CC BY-SA 3.0)

Muadtralk (CC BY-SA 3.0)
  fire_basic_flame_animated.png

Gambit (CC BY-SA 3.0)
  fire_flint_steel.png

dobroide (CC BY 3.0)
http://www.freesound.org/people/dobroide/sounds/4211/
  fire_small.ogg

Dynamicell (CC BY 3.0)
http://www.freesound.org/people/Dynamicell/sounds/17548/
  fire_large.ogg
  fire_fire.*.ogg

fire_small.ogg and fire_large.ogg are unused but kept temporarily to not break
other mods that may use them.

Benboncan (CC BY 3.0)
https://www.freesound.org/people/Benboncan/sounds/66457/
  fire_flint_and_steel.ogg

repo_name: Desour/PlayMinetestServer

license: mit


code:
-- fire/init.lua

-- Global namespace for functions
fire = {}

-- Load support for MT game translation.
local S = minetest.get_translator("fire")

-- 'Enable fire' setting
local fire_enabled = minetest.settings:get_bool("enable_fire")
if fire_enabled == nil then
	-- enable_fire setting not specified, check for disable_fire
	local fire_disabled = minetest.settings:get_bool("disable_fire")
	if fire_disabled == nil then
		-- Neither setting specified, check whether singleplayer
		fire_enabled = minetest.is_singleplayer()
	else
		fire_enabled = not fire_disabled
	end
end

--
-- Items
--

-- Flood flame function
local function flood_flame(pos, _, newnode)
	-- Play flame extinguish sound if liquid is not an 'igniter'
	if minetest.get_item_group(newnode.name, "igniter") == 0 then
		minetest.sound_play("fire_extinguish_flame",
			{pos = pos, max_hear_distance = 16, gain = 0.15}, true)
	end
	-- Remove the flame
	return false
end

-- Flame nodes
local fire_node = {
	drawtype = "firelike",
	tiles = {{
		name = "fire_basic_flame_animated.png",
		animation = {
			type = "vertical_frames",
			aspect_w = 16,
			aspect_h = 16,
			length = 1
		}}
	},
	inventory_image = "fire_basic_flame.png",
	paramtype = "light",
	light_source = 13,
	walkable = false,
	buildable_to = true,
	sunlight_propagates = true,
	floodable = true,
	damage_per_second = 4,
	groups = {igniter = 2, dig_immediate = 3, fire = 1},
	drop = "",
	on_flood = flood_flame
}

-- Basic flame node
local flame_fire_node = table.copy(fire_node)
flame_fire_node.description = S("Fire")
flame_fire_node.groups.not_in_creative_inventory = 1
flame_fire_node.on_timer = function(pos)
	if not minetest.find_node_near(pos, 1, {"group:flammable"}) then
		minetest.remove_node(pos)
		return
	end
	-- Restart timer
	return true
end
flame_fire_node.on_construct = function(pos)
	minetest.get_node_timer(pos):start(math.random(30, 60))
end

minetest.register_node("fire:basic_flame", flame_fire_node)

-- Permanent flame node
local permanent_fire_node = table.copy(fire_node)
permanent_fire_node.description = S("Permanent Fire")

minetest.register_node("fire:permanent_flame", permanent_fire_node)

-- Flint and Steel
minetest.register_tool("fire:flint_and_steel", {
	description = S("Flint and Steel"),
	inventory_image = "fire_flint_steel.png",
	sound = {breaks = "default_tool_breaks"},

	on_use = function(itemstack, user, pointed_thing)
		local sound_pos = pointed_thing.above or user:get_pos()
		minetest.sound_play("fire_flint_and_steel",
			{pos = sound_pos, gain = 0.5, max_hear_distance = 8}, true)
		local player_name = user:get_player_name()
		if pointed_thing.type == "node" then
			local node_under = minetest.get_node(pointed_thing.under).name
			local nodedef = minetest.registered_nodes[node_under]
			if not nodedef then
				return
			end
			if minetest.is_protected(pointed_thing.under, player_name) then
				minetest.chat_send_player(player_name, "This area is protected")
				return
			end
			if nodedef.on_ignite then
				nodedef.on_ignite(pointed_thing.under, user)
			elseif minetest.get_item_group(node_under, "flammable") >= 1
					and minetest.get_node(pointed_thing.above).name == "air" then
				minetest.set_node(pointed_thing.above, {name = "fire:basic_flame"})
			end
		end
		if not (creative and creative.is_enabled_for
				and creative.is_enabled_for(player_name)) then
			-- Wear tool
			local wdef = itemstack:get_definition()
			itemstack:add_wear(1000)

			-- Tool break sound
			if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
				minetest.sound_play(wdef.sound.breaks,
					{pos = sound_pos, gain = 0.5}, true)
			end
			return itemstack
		end
	end
})

minetest.register_craft({
	output = "fire:flint_and_steel",
	recipe = {
		{"default:flint", "default:steel_ingot"}
	}
})

-- Override coalblock to enable permanent flame above
-- Coalblock is non-flammable to avoid unwanted basic_flame nodes
minetest.override_item("default:coalblock", {
	after_destruct = function(pos)
		pos.y = pos.y + 1
		if minetest.get_node(pos).name == "fire:permanent_flame" then
			minetest.remove_node(pos)
		end
	end,
	on_ignite = function(pos)
		local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z}
		if minetest.get_node(flame_pos).name == "air" then
			minetest.set_node(flame_pos, {name = "fire:permanent_flame"})
		end
	end
})

--
-- Sound
--

-- Enable if no setting present
local flame_sound = minetest.settings:get_bool("flame_sound", true)

if flame_sound then
	local handles = {}
	local timer = 0

	-- Parameters
	local radius = 8 -- Flame node search radius around player
	local cycle = 3 -- Cycle time for sound updates

	-- Update sound for player
	function fire.update_player_sound(player)
		local player_name = player:get_player_name()
		-- Search for flame nodes in radius around player
		local ppos = player:get_pos()
		local areamin = vector.subtract(ppos, radius)
		local areamax = vector.add(ppos, radius)
		local fpos, num = minetest.find_nodes_in_area(
			areamin,
			areamax,
			{"fire:basic_flame", "fire:permanent_flame"}
		)
		-- Total number of flames in radius
		local flames = (num["fire:basic_flame"] or 0) +
			(num["fire:permanent_flame"] or 0)
		-- Stop previous sound
		if handles[player_name] then
			minetest.sound_stop(handles[player_name])
			handles[player_name] = nil
		end
		-- If flames
		if flames > 0 then
			-- Find centre of flame positions
			local fposmid = fpos[1]
			-- If more than 1 flame
			if #fpos > 1 then
				local fposmin = areamax
				local fposmax = areamin
				for i = 1, #fpos do
					local fposi = fpos[i]
					if fposi.x > fposmax.x then
						fposmax.x = fposi.x
					end
					if fposi.y > fposmax.y then
						fposmax.y = fposi.y
					end
					if fposi.z > fposmax.z then
						fposmax.z = fposi.z
					end
					if fposi.x < fposmin.x then
						fposmin.x = fposi.x
					end
					if fposi.y < fposmin.y then
						fposmin.y = fposi.y
					end
					if fposi.z < fposmin.z then
						fposmin.z = fposi.z
					end
				end
				fposmid = vector.divide(vector.add(fposmin, fposmax), 2)
			end
			-- Play sound
			local handle = minetest.sound_play("fire_fire", {
				pos = fposmid,
				to_player = player_name,
				gain = math.min(0.06 * (1 + flames * 0.125), 0.18),
				max_hear_distance = 32,
				loop = true -- In case of lag
			})
			-- Store sound handle for this player
			if handle then
				handles[player_name] = handle
			end
		end
	end

	-- Cycle for updating players sounds
	minetest.register_globalstep(function(dtime)
		timer = timer + dtime
		if timer < cycle then
			return
		end

		timer = 0
		local players = minetest.get_connected_players()
		for n = 1, #players do
			fire.update_player_sound(players[n])
		end
	end)

	-- Stop sound and clear handle on player leave
	minetest.register_on_leaveplayer(function(player)
		local player_name = player:get_player_name()
		if handles[player_name] then
			minetest.sound_stop(handles[player_name])
			handles[player_name] = nil
		end
	end)
end

-- Deprecated function kept temporarily to avoid crashes if mod fire nodes call it
function fire.update_sounds_around() end

--
-- ABMs
--

if fire_enabled then
	-- Ignite neighboring nodes, add basic flames
	minetest.register_abm({
		label = "Ignite flame",
		nodenames = {"group:flammable"},
		neighbors = {"group:igniter"},
		interval = 7,
		chance = 12,
		catch_up = false,
		action = function(pos)
			local p = minetest.find_node_near(pos, 1, {"air"})
			if p then
				minetest.set_node(p, {name = "fire:basic_flame"})
			end
		end
	})

	-- Remove flammable nodes around basic flame
	minetest.register_abm({
		label = "Remove flammable nodes",
		nodenames = {"fire:basic_flame"},
		neighbors = "group:flammable",
		interval = 5,
		chance = 18,
		catch_up = false,
		action = function(pos)
			local p = minetest.find_node_near(pos, 1, {"group:flammable"})
			if not p then
				return
			end
			local flammable_node = minetest.get_node(p)
			local def = minetest.registered_nodes[flammable_node.name]
			if def.on_burn then
				def.on_burn(p)
			else
				minetest.remove_node(p)
				minetest.check_for_falling(p)
			end
		end
	})
end


code:
# textdomain: fire
Fire=Feuer
Permanent Fire=Permanentes Feuer
Flint and Steel=Feuerstein und Stahl


code:
# textdomain: fire
Permanent Flame=Llama permanente
Flint and Steel=Yesca y pedernal


code:
# textdomain: fire
Permanent Flame=Flamme permanente
Flint and Steel=Briquet à silex en acier


code:
# textdomain: fire
Fire=Api
Permanent Fire=Api Abadi
Flint and Steel=Pemantik


code:
# textdomain: fire
Permanent Flame=Fiamma permanente
Flint and Steel=Acciarino


code:
# textdomain: fire
Permanent Flame=Api Abadi
Flint and Steel=Pemetik Api


code:
# textdomain: fire
Permanent Flame=Вечный Огонь
Flint and Steel=Огниво и Сталь


code:
# textdomain: fire
Permanent Flame=Permanent Eld
Flint and Steel=Flinta och Stål


code:
# textdomain: fire
Permanent Fire=永久火焰
Flint and Steel=火石和钢
Fire=火焰


code:
# textdomain: fire
Permanent Fire=永久火焰
Flint and Steel=火石和鋼
Fire=火焰


code:
# textdomain: fire
Fire=
Permanent Fire=
Flint and Steel=


code:
name = fire
description = Minetest Game mod: fire
depends = default


code:
Minetest Game mod: fireflies
============================
Adds fireflies to the world on mapgen, which can then be caught in a net and placed in
bottles to provide light.

Authors of source code
----------------------
Shara RedCat (MIT)

Authors of media (textures)
---------------------------
Shara RedCat (CC BY-SA 3.0):
  fireflies_firefly.png
  fireflies_firefly_animated.png
  fireflies_bugnet.png
  fireflies_bottle.png
  fireflies_bottle_animated.png

fireflies_bugnet.png is modified from a texture by tenplus1 (CC0)

fireflies_bottle.png and fireflies_bottle_animated.png are
modified from a texture by Vanessa Ezekowitz (CC BY-SA 3.0)


code:
-- firefly/init.lua

-- Load support for MT game translation.
local S = minetest.get_translator("fireflies")

minetest.register_node("fireflies:firefly", {
	description = S("Firefly"),
	drawtype = "plantlike",
	tiles = {{
		name = "fireflies_firefly_animated.png",
		animation = {
			type = "vertical_frames",
			aspect_w = 16,
			aspect_h = 16,
			length = 1.5
		},
	}},
	inventory_image = "fireflies_firefly.png",
	wield_image =  "fireflies_firefly.png",
	waving = 1,
	paramtype = "light",
	sunlight_propagates = true,
	buildable_to = true,
	walkable = false,
	groups = {catchable = 1},
	selection_box = {
		type = "fixed",
		fixed = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
	},
	light_source = 6,
	floodable = true,
	on_place = function(itemstack, placer, pointed_thing)
		local player_name = placer:get_player_name()
		local pos = pointed_thing.above

		if not minetest.is_protected(pos, player_name) and
				not minetest.is_protected(pointed_thing.under, player_name) and
				minetest.get_node(pos).name == "air" then
			minetest.set_node(pos, {name = "fireflies:firefly"})
			minetest.get_node_timer(pos):start(1)
			itemstack:take_item()
		end
		return itemstack
	end,
	on_timer = function(pos, elapsed)
		if minetest.get_node_light(pos) > 11 then
			minetest.set_node(pos, {name = "fireflies:hidden_firefly"})
		end
		minetest.get_node_timer(pos):start(30)
	end
})

minetest.register_node("fireflies:hidden_firefly", {
	description = S("Hidden Firefly"),
	drawtype = "airlike",
	inventory_image = "fireflies_firefly.png",
	wield_image =  "fireflies_firefly.png",
	paramtype = "light",
	sunlight_propagates = true,
	walkable = false,
	pointable = false,
	diggable = false,
	buildable_to = true,
	drop = "",
	groups = {not_in_creative_inventory = 1},
	floodable = true,
	on_place = function(itemstack, placer, pointed_thing)
		local player_name = placer:get_player_name()
		local pos = pointed_thing.above

		if not minetest.is_protected(pos, player_name) and
				not minetest.is_protected(pointed_thing.under, player_name) and
				minetest.get_node(pos).name == "air" then
			minetest.set_node(pos, {name = "fireflies:hidden_firefly"})
			minetest.get_node_timer(pos):start(1)
			itemstack:take_item()
		end
		return itemstack
	end,
	on_timer = function(pos, elapsed)
		if minetest.get_node_light(pos) <= 11 then
			minetest.set_node(pos, {name = "fireflies:firefly"})
		end
		minetest.get_node_timer(pos):start(30)
	end
})

-- bug net
minetest.register_tool("fireflies:bug_net", {
	description = S("Bug Net"),
	inventory_image = "fireflies_bugnet.png",
	on_use = function(itemstack, player, pointed_thing)
		if not pointed_thing or pointed_thing.type ~= "node" or
				minetest.is_protected(pointed_thing.under, player:get_player_name()) then
			return
		end
		local node_name = minetest.get_node(pointed_thing.under).name
		local inv = player:get_inventory()
		if minetest.get_item_group(node_name, "catchable") == 1 then
			minetest.set_node(pointed_thing.under, {name = "air"})
			local stack = ItemStack(node_name.." 1")
			local leftover = inv:add_item("main", stack)
			if leftover:get_count() > 0 then
				minetest.add_item(pointed_thing.under, node_name.." 1")
			end
		end
		if not (creative and creative.is_enabled_for(player:get_player_name())) then
			itemstack:add_wear(256)
			return itemstack
		end
	end
})

minetest.register_craft( {
	output = "fireflies:bug_net",
	recipe = {
		{"farming:string", "farming:string"},
		{"farming:string", "farming:string"},
		{"group:stick", ""}
	}
})

-- firefly in a bottle
minetest.register_node("fireflies:firefly_bottle", {
	description = S("Firefly in a Bottle"),
	inventory_image = "fireflies_bottle.png",
	wield_image = "fireflies_bottle.png",
	tiles = {{
		name = "fireflies_bottle_animated.png",
		animation = {
			type = "vertical_frames",
			aspect_w = 16,
			aspect_h = 16,
			length = 1.5
		},
	}},
	drawtype = "plantlike",
	paramtype = "light",
	sunlight_propagates = true,
	light_source = 9,
	walkable = false,
	groups = {vessel = 1, dig_immediate = 3, attached_node = 1},
	selection_box = {
		type = "fixed",
		fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25}
	},
	sounds = default.node_sound_glass_defaults(),
	on_rightclick = function(pos, node, player, itemstack, pointed_thing)
		local lower_pos = {x = pos.x, y = pos.y + 1, z = pos.z}
		if minetest.is_protected(pos, player:get_player_name()) or
				minetest.get_node(lower_pos).name ~= "air" then
			return
		end

		local upper_pos = {x = pos.x, y = pos.y + 2, z = pos.z}
		local firefly_pos

		if not minetest.is_protected(upper_pos, player:get_player_name()) and
				minetest.get_node(upper_pos).name == "air" then
			firefly_pos = upper_pos
		elseif not minetest.is_protected(lower_pos, player:get_player_name()) then
			firefly_pos = lower_pos
		end

		if firefly_pos then
			minetest.set_node(pos, {name = "vessels:glass_bottle"})
			minetest.set_node(firefly_pos, {name = "fireflies:firefly"})
			minetest.get_node_timer(firefly_pos):start(1)
		end
	end
})

minetest.register_craft( {
	output = "fireflies:firefly_bottle",
	recipe = {
		{"fireflies:firefly"},
		{"vessels:glass_bottle"}
	}
})

-- register fireflies as decorations

if minetest.get_mapgen_setting("mg_name") == "v6" then

	minetest.register_decoration({
		name = "fireflies:firefly_low",
		deco_type = "simple",
		place_on = "default:dirt_with_grass",
		place_offset_y = 2,
		sidelen = 80,
		fill_ratio = 0.0002,
		y_max = 31000,
		y_min = 1,
		decoration = "fireflies:hidden_firefly",
	})

	minetest.register_decoration({
		name = "fireflies:firefly_high",
		deco_type = "simple",
		place_on = "default:dirt_with_grass",
		place_offset_y = 3,
		sidelen = 80,
		fill_ratio = 0.0002,
		y_max = 31000,
		y_min = 1,
		decoration = "fireflies:hidden_firefly",
	})

else

	minetest.register_decoration({
		name = "fireflies:firefly_low",
		deco_type = "simple",
		place_on = {
			"default:dirt_with_grass",
			"default:dirt_with_coniferous_litter",
			"default:dirt_with_rainforest_litter",
			"default:dirt"
		},
		place_offset_y = 2,
		sidelen = 80,
		fill_ratio = 0.0005,
		biomes = {
			"deciduous_forest",
			"coniferous_forest",
			"rainforest",
			"rainforest_swamp"
		},
		y_max = 31000,
		y_min = -1,
		decoration = "fireflies:hidden_firefly",
	})

	minetest.register_decoration({
		name = "fireflies:firefly_high",
		deco_type = "simple",
		place_on = {
			"default:dirt_with_grass",
			"default:dirt_with_coniferous_litter",
			"default:dirt_with_rainforest_litter",
			"default:dirt"
		},
		place_offset_y = 3,
		sidelen = 80,
		fill_ratio = 0.0005,
		biomes = {
			"deciduous_forest",
			"coniferous_forest",
			"rainforest",
			"rainforest_swamp"
		},
		y_max = 31000,
		y_min = -1,
		decoration = "fireflies:hidden_firefly",
	})

end

-- get decoration IDs
local firefly_low = minetest.get_decoration_id("fireflies:firefly_low")
local firefly_high = minetest.get_decoration_id("fireflies:firefly_high")

minetest.set_gen_notify({decoration = true}, {firefly_low, firefly_high})

-- start nodetimers
minetest.register_on_generated(function(minp, maxp, blockseed)
	local gennotify = minetest.get_mapgen_object("gennotify")
	local poslist = {}

	for _, pos in ipairs(gennotify["decoration#"..firefly_low] or {}) do
		local firefly_low_pos = {x = pos.x, y = pos.y + 3, z = pos.z}
		table.insert(poslist, firefly_low_pos)
	end
	for _, pos in ipairs(gennotify["decoration#"..firefly_high] or {}) do
		local firefly_high_pos = {x = pos.x, y = pos.y + 4, z = pos.z}
		table.insert(poslist, firefly_high_pos)
	end

	if #poslist ~= 0 then
		for i = 1, #poslist do
			local pos = poslist[i]
			minetest.get_node_timer(pos):start(1)
		end
	end
end)


code:
# textdomain: fireflies
Firefly=Glühwürmchen
Hidden Firefly=Verborgenes Glühwürmchen
Bug Net=Insektennetz
Firefly in a Bottle=Glühwürmchen in einer Flasche


code:
# textdomain: fireflies
Firefly=Luciérnaga
Hidden Firefly=Luciérnaga oculta
Bug Net=Red de insectos
Firefly in a Bottle=Luciérnaga en botella


code:
# textdomain: fireflies
Firefly=Luciole
Hidden Firefly=Luciole cachée
Bug Net=Filet à papillon
Firefly in a Bottle=Luciole en bouteille


code:
# textdomain: fireflies
Firefly=Kunang-Kunang
Hidden Firefly=Kunang-Kunang Tersembunyi
Bug Net=Jaring Serangga
Firefly in a Bottle=Kunang-Kunang dalam Botol


code:
# textdomain: fireflies
Firefly=Lucciola
Hidden Firefly=Lucciola nascosta
Bug Net=Retino
Firefly in a Bottle=Lucciola imbottigliata


code:
# textdomain: fireflies
Firefly=Kelip-Kelip
Hidden Firefly=Kelip-Kelip Tersembunyi
Bug Net=Jaring Pepijat
Firefly in a Bottle=Kelip-Kelip dalam Botol


code:
# textdomain: fireflies
Firefly=Светлячок
Hidden Firefly=Притаившийся Светлячок
Bug Net=Сачок Для Ловли Насекомых
Firefly in a Bottle=Светлячок в Бутылке


code:
# textdomain: fireflies
Firefly=Eldfluga
Hidden Firefly=Gömd Eldfluga
Bug Net=Buggernät
Firefly in a Bottle=Eldfluga i en flaska


code:
# textdomain: fireflies
Firefly=萤火虫
Hidden Firefly=隐藏的萤火虫
Bug Net=虫网
Firefly in a Bottle=放在瓶子里的萤火虫


code:
# textdomain: fireflies
Firefly=螢火蟲
Hidden Firefly=隱藏的螢火蟲
Bug Net=蟲網
Firefly in a Bottle=放在瓶子裡的螢火蟲


code:
# textdomain: fireflies
Firefly=
Hidden Firefly=
Bug Net=
Firefly in a Bottle=


code:
name = fireflies
description = Minetest Game mod: fireflies
depends = default, vessels


code:
Minetest Game mod: flowers
==========================
See license.txt for license information.

Authors of source code
----------------------
Originally by Ironzorg (MIT) and VanessaE (MIT)
Various Minetest developers and contributors (MIT)

Authors of media (textures)
---------------------------
RHRhino (CC BY-SA 3.0):
  flowers_dandelion_white.png
  flowers_geranium.png
  flowers_rose.png
  flowers_tulip.png
  flowers_viola.png

Gambit (CC BY-SA 3.0):
  flowers_mushroom_brown.png
  flowers_mushroom_red.png
  flowers_waterlily.png

yyt16384 (CC BY-SA 3.0):
  flowers_waterlily_bottom.png -- Derived from Gambit's texture

paramat (CC BY-SA 3.0):
  flowers_dandelion_yellow.png -- Derived from RHRhino's texture
  flowers_tulip_black.png -- Derived from RHRhino's texture
  flowers_chrysanthemum_green.png


code:
-- flowers/init.lua

-- Minetest 0.4 mod: default
-- See README.txt for licensing and other information.

-- Namespace for functions

flowers = {}

-- Load support for MT game translation.
local S = minetest.get_translator("flowers")

-- Map Generation

dofile(minetest.get_modpath("flowers") .. "/mapgen.lua")

--
-- Flowers
--

-- Aliases for original flowers mod

minetest.register_alias("flowers:flower_rose", "flowers:rose")
minetest.register_alias("flowers:flower_tulip", "flowers:tulip")
minetest.register_alias("flowers:flower_dandelion_yellow", "flowers:dandelion_yellow")
minetest.register_alias("flowers:flower_geranium", "flowers:geranium")
minetest.register_alias("flowers:flower_viola", "flowers:viola")
minetest.register_alias("flowers:flower_dandelion_white", "flowers:dandelion_white")

-- Flower registration

local function add_simple_flower(name, desc, box, f_groups)
	-- Common flowers' groups
	f_groups.snappy = 3
	f_groups.flower = 1
	f_groups.flora = 1
	f_groups.attached_node = 1

	minetest.register_node("flowers:" .. name, {
		description = desc,
		drawtype = "plantlike",
		waving = 1,
		tiles = {"flowers_" .. name .. ".png"},
		inventory_image = "flowers_" .. name .. ".png",
		wield_image = "flowers_" .. name .. ".png",
		sunlight_propagates = true,
		paramtype = "light",
		walkable = false,
		buildable_to = true,
		groups = f_groups,
		sounds = default.node_sound_leaves_defaults(),
		selection_box = {
			type = "fixed",
			fixed = box
		}
	})
end

flowers.datas = {
	{
		"rose",
		S("Red Rose"),
		{-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16},
		{color_red = 1, flammable = 1}
	},
	{
		"tulip",
		S("Orange Tulip"),
		{-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16},
		{color_orange = 1, flammable = 1}
	},
	{
		"dandelion_yellow",
		S("Yellow Dandelion"),
		{-4 / 16, -0.5, -4 / 16, 4 / 16, -2 / 16, 4 / 16},
		{color_yellow = 1, flammable = 1}
	},
	{
		"chrysanthemum_green",
		S("Green Chrysanthemum"),
		{-4 / 16, -0.5, -4 / 16, 4 / 16, -1 / 16, 4 / 16},
		{color_green = 1, flammable = 1}
	},
	{
		"geranium",
		S("Blue Geranium"),
		{-2 / 16, -0.5, -2 / 16, 2 / 16, 2 / 16, 2 / 16},
		{color_blue = 1, flammable = 1}
	},
	{
		"viola",
		S("Viola"),
		{-5 / 16, -0.5, -5 / 16, 5 / 16, -1 / 16, 5 / 16},
		{color_violet = 1, flammable = 1}
	},
	{
		"dandelion_white",
		S("White Dandelion"),
		{-5 / 16, -0.5, -5 / 16, 5 / 16, -2 / 16, 5 / 16},
		{color_white = 1, flammable = 1}
	},
	{
		"tulip_black",
		S("Black Tulip"),
		{-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16},
		{color_black = 1, flammable = 1}
	},
}

for _,item in pairs(flowers.datas) do
	add_simple_flower(unpack(item))
end

-- Flower spread
-- Public function to enable override by mods

function flowers.flower_spread(pos, node)
	pos.y = pos.y - 1
	local under = minetest.get_node(pos)
	pos.y = pos.y + 1
	-- Replace flora with dry shrub in desert sand and silver sand,
	-- as this is the only way to generate them.
	-- However, preserve grasses in sand dune biomes.
	if minetest.get_item_group(under.name, "sand") == 1 and
			under.name ~= "default:sand" then
		minetest.set_node(pos, {name = "default:dry_shrub"})
		return
	end

	if minetest.get_item_group(under.name, "soil") == 0 then
		return
	end

	local light = minetest.get_node_light(pos)
	if not light or light < 13 then
		return
	end

	local pos0 = vector.subtract(pos, 4)
	local pos1 = vector.add(pos, 4)
	-- Testing shows that a threshold of 3 results in an appropriate maximum
	-- density of approximately 7 flora per 9x9 area.
	if #minetest.find_nodes_in_area(pos0, pos1, "group:flora") > 12 then
		return
	end

	local soils = minetest.find_nodes_in_area_under_air(
		pos0, pos1, "group:soil")
	local num_soils = #soils
	if num_soils >= 1 then
		for si = 1, math.min(3, num_soils) do
			local soil = soils[math.random(num_soils)]
			local soil_name = minetest.get_node(soil).name
			local soil_above = {x = soil.x, y = soil.y + 1, z = soil.z}
			light = minetest.get_node_light(soil_above)
			if light and light >= 13 and
					-- Only spread to same surface node
					soil_name == under.name and
					-- Desert sand is in the soil group
					soil_name ~= "default:desert_sand" then
				minetest.set_node(soil_above, {name = node.name})
			end
		end
	end
end

minetest.register_abm({
	label = "Flower spread",
	nodenames = {"group:flora"},
	interval = 13,
	chance = 300,
	action = function(...)
		flowers.flower_spread(...)
	end,
})

--
-- Mushrooms
--

minetest.register_node("flowers:mushroom_red", {
	description = S("Red Mushroom"),
	tiles = {"flowers_mushroom_red.png"},
	inventory_image = "flowers_mushroom_red.png",
	wield_image = "flowers_mushroom_red.png",
	drawtype = "plantlike",
	paramtype = "light",
	sunlight_propagates = true,
	walkable = false,
	buildable_to = true,
	groups = {mushroom = 1, snappy = 3, attached_node = 1, flammable = 1},
	sounds = default.node_sound_leaves_defaults(),
	on_use = minetest.item_eat(-5),
	selection_box = {
		type = "fixed",
		fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, -1 / 16, 4 / 16},
	}
})

minetest.register_node("flowers:mushroom_brown", {
	description = S("Brown Mushroom"),
	tiles = {"flowers_mushroom_brown.png"},
	inventory_image = "flowers_mushroom_brown.png",
	wield_image = "flowers_mushroom_brown.png",
	drawtype = "plantlike",
	paramtype = "light",
	sunlight_propagates = true,
	walkable = false,
	buildable_to = true,
	groups = {mushroom = 1, food_mushroom = 1, snappy = 3, attached_node = 1, flammable = 1},
	sounds = default.node_sound_leaves_defaults(),
	on_use = minetest.item_eat(1),
	selection_box = {
		type = "fixed",
		fixed = {-3 / 16, -0.5, -3 / 16, 3 / 16, -2 / 16, 3 / 16},
	}
})

-- Mushroom spread and death

function flowers.mushroom_spread(pos, node)
	if minetest.get_node_light(pos, 0.5) > 3 then
		if minetest.get_node_light(pos, nil) == 15 then
			minetest.remove_node(pos)
		end
		return
	end
	local positions = minetest.find_nodes_in_area_under_air(
		{x = pos.x - 1, y = pos.y - 2, z = pos.z - 1},
		{x = pos.x + 1, y = pos.y + 1, z = pos.z + 1},
		{"group:soil", "group:tree"})
	if #positions == 0 then
		return
	end
	local pos2 = positions[math.random(#positions)]
	pos2.y = pos2.y + 1
	if minetest.get_node_light(pos2, 0.5) <= 3 then
		minetest.set_node(pos2, {name = node.name})
	end
end

minetest.register_abm({
	label = "Mushroom spread",
	nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"},
	interval = 11,
	chance = 150,
	action = function(...)
		flowers.mushroom_spread(...)
	end,
})

-- These old mushroom related nodes can be simplified now

minetest.register_alias("flowers:mushroom_spores_brown", "flowers:mushroom_brown")
minetest.register_alias("flowers:mushroom_spores_red", "flowers:mushroom_red")
minetest.register_alias("flowers:mushroom_fertile_brown", "flowers:mushroom_brown")
minetest.register_alias("flowers:mushroom_fertile_red", "flowers:mushroom_red")
minetest.register_alias("mushroom:brown_natural", "flowers:mushroom_brown")
minetest.register_alias("mushroom:red_natural", "flowers:mushroom_red")

--
-- Waterlily
--

local waterlily_def = {
	description = S("Waterlily"),
	drawtype = "nodebox",
	paramtype = "light",
	paramtype2 = "facedir",
	tiles = {"flowers_waterlily.png", "flowers_waterlily_bottom.png"},
	inventory_image = "flowers_waterlily.png",
	wield_image = "flowers_waterlily.png",
	liquids_pointable = true,
	walkable = false,
	buildable_to = true,
	floodable = true,
	groups = {snappy = 3, flower = 1, flammable = 1},
	sounds = default.node_sound_leaves_defaults(),
	node_placement_prediction = "",
	node_box = {
		type = "fixed",
		fixed = {-0.5, -31 / 64, -0.5, 0.5, -15 / 32, 0.5}
	},
	selection_box = {
		type = "fixed",
		fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, -15 / 32, 7 / 16}
	},

	on_place = function(itemstack, placer, pointed_thing)
		local pos = pointed_thing.above
		local node = minetest.get_node(pointed_thing.under)
		local def = minetest.registered_nodes[node.name]

		if def and def.on_rightclick then
			return def.on_rightclick(pointed_thing.under, node, placer, itemstack,
					pointed_thing)
		end

		if def and def.liquidtype == "source" and
				minetest.get_item_group(node.name, "water") > 0 then
			local player_name = placer and placer:get_player_name() or ""
			if not minetest.is_protected(pos, player_name) then
				minetest.set_node(pos, {name = "flowers:waterlily" ..
					(def.waving == 3 and "_waving" or ""),
					param2 = math.random(0, 3)})
				if not (creative and creative.is_enabled_for
						and creative.is_enabled_for(player_name)) then
					itemstack:take_item()
				end
			else
				minetest.chat_send_player(player_name, "Node is protected")
				minetest.record_protection_violation(pos, player_name)
			end
		end

		return itemstack
	end
}

local waterlily_waving_def = table.copy(waterlily_def)
waterlily_waving_def.waving = 3
waterlily_waving_def.drop = "flowers:waterlily"
waterlily_waving_def.groups.not_in_creative_inventory = 1

minetest.register_node("flowers:waterlily", waterlily_def)
minetest.register_node("flowers:waterlily_waving", waterlily_waving_def)


code:
# textdomain: flowers
Red Rose=Rote Rose
Orange Tulip=Orange Tulpe
Yellow Dandelion=Gelber Löwenzahn
Green Chrysanthemum=Grüne Chrysantheme
Blue Geranium=Blaue Geranie
Viola=Veilchen
White Dandelion=Weißer Löwenzahn
Black Tulip=Schwarze Tulpe
Red Mushroom=Roter Pilz
Brown Mushroom=Brauner Pilz
Waterlily=Wasserlilie


code:
# textdomain: flowers
Red Rose=Rosa roja
Orange Tulip=Tulipán naranja
Yellow Dandelion=Diente de León amarillo
Green Chrysanthemum=Crisantemo verde
Blue Geranium=Geranio azul
Viola=Violeta
White Dandelion=Diente de León blanco
Black Tulip=Tulipán negro
Red Mushroom=Champiñón rojo
Brown Mushroom=Champiñón café
Waterlily=Nenúfar


code:
# textdomain: flowers
Red Rose=Rose rouge
Orange Tulip=Tulipe orange
Yellow Dandelion=Pissenlit jaune
Green Chrysanthemum=Chrysanthème vert
Blue Geranium=Géranium bleu
Viola=Violette
White Dandelion=Pissenlit blanc
Black Tulip=Tulipe noire
Red Mushroom=Champignon rouge
Brown Mushroom=Champignon brun
Waterlily=Nénuphar


code:
# textdomain: flowers
Red Rose=Mawar Merah
Orange Tulip=Tulip Oranye
Yellow Dandelion=Dandelion Kuning
Green Chrysanthemum=Krisan Hijau
Blue Geranium=Geranium Biru
Viola=Viola
White Dandelion=Dandelion Putih
Black Tulip=Tulip Hitam
Red Mushroom=Jamur Merah
Brown Mushroom=Jamur Cokelat
Waterlily=Teratai


code:
# textdomain: flowers
Red Rose=Rosa rossa
Orange Tulip=Tulipano arancione
Yellow Dandelion=Dente di leone giallo
Green Chrysanthemum=Crisantemo verde
Blue Geranium=Geranio blu
Viola=Viola
White Dandelion=Dente di leone bianco
Black Tulip=Tulipano nero
Red Mushroom=Fungo rosso
Brown Mushroom=Fungo marrone
Waterlily=Ninfea


code:
# textdomain: flowers
Red Rose=Ros Merah
Orange Tulip=Tulip Jingga
Yellow Dandelion=Dandelion Kuning
Green Chrysanthemum=Kekwa Hijau
Blue Geranium=Geranium Biru
Viola=Violet
White Dandelion=Dandelion Putih
Black Tulip=Tulip Hitam
Red Mushroom=Cendawan Merah
Brown Mushroom=Cendawan Perang
Waterlily=Teratai


code:
# textdomain: flowers
Red Rose=Красная Роза
Orange Tulip=Оранжевый Тюльпан
Yellow Dandelion=Желтый Одуванчик
Green Chrysanthemum=Зелёная Хризантема
Blue Geranium=Синяя Герань
Viola=Фиалка
White Dandelion=Белый Одуванчик
Black Tulip=Черный Тюльпан
Red Mushroom=Мухомор
Brown Mushroom=Коричневый Гриб
Waterlily=Кувшинка


code:
# textdomain: flowers
Red Rose=Röd ros
Orange Tulip=Orange Tulpan
Yellow Dandelion=Gul Maskros
Green Chrysanthemum=Grön Krysantemum
Blue Geranium=Blå Geranium
Viola=Violett Viola
White Dandelion=Vit Maskros
Black Tulip=Svart Tulpan
Red Mushroom=Röd Svamp
Brown Mushroom=Brun Svamp
Waterlily=Näckros


code:
# textdomain: flowers
Red Rose=红玫瑰
Orange Tulip=橙郁金香
Yellow Dandelion=黄蒲公英
Green Chrysanthemum=绿菊花
Blue Geranium=蓝天竺葵
Viola=三色堇
White Dandelion=白蒲公英
Black Tulip=黑郁金香
Red Mushroom=红蘑菇
Brown Mushroom=棕蘑菇
Waterlily=睡莲


code:
# textdomain: flowers
Red Rose=紅玫瑰
Orange Tulip=橙鬱金香
Yellow Dandelion=黃蒲公英
Green Chrysanthemum=綠菊花
Blue Geranium=藍天竺葵
Viola=三色堇
White Dandelion=白蒲公英
Black Tulip=黑鬱金香
Red Mushroom=紅蘑菇
Brown Mushroom=棕蘑菇
Waterlily=睡蓮


code:
# textdomain: flowers
Red Rose=
Orange Tulip=
Yellow Dandelion=
Green Chrysanthemum=
Blue Geranium=
Viola=
White Dandelion=
Black Tulip=
Red Mushroom=
Brown Mushroom=
Waterlily=


code:
--
-- Mgv6
--

local function register_mgv6_flower(flower_name)
	minetest.register_decoration({
		name = "flowers:"..flower_name,
		deco_type = "simple",
		place_on = {"default:dirt_with_grass"},
		sidelen = 16,
		noise_params = {
			offset = 0,
			scale = 0.006,
			spread = {x = 100, y = 100, z = 100},
			seed = 436,
			octaves = 3,
			persist = 0.6
		},
		y_max = 30,
		y_min = 1,
		decoration = "flowers:"..flower_name,
	})
end

local function register_mgv6_mushroom(mushroom_name)
	minetest.register_decoration({
		name = "flowers:"..mushroom_name,
		deco_type = "simple",
		place_on = {"default:dirt_with_grass"},
		sidelen = 16,
		noise_params = {
			offset = 0,
			scale = 0.04,
			spread = {x = 100, y = 100, z = 100},
			seed = 7133,
			octaves = 3,
			persist = 0.6
		},
		y_max = 30,
		y_min = 1,
		decoration = "flowers:"..mushroom_name,
		spawn_by = "default:tree",
		num_spawn_by = 1,
	})
end

local function register_mgv6_waterlily()
	minetest.register_decoration({
		name = "flowers:waterlily",
		deco_type = "simple",
		place_on = {"default:dirt"},
		sidelen = 16,
		noise_params = {
			offset = -0.12,
			scale = 0.3,
			spread = {x = 100, y = 100, z = 100},
			seed = 33,
			octaves = 3,
			persist = 0.7
		},
		y_max = 0,
		y_min = 0,
		decoration = "flowers:waterlily_waving",
		param2 = 0,
		param2_max = 3,
		place_offset_y = 1,
	})
end

function flowers.register_mgv6_decorations()
	register_mgv6_flower("rose")
	register_mgv6_flower("tulip")
	register_mgv6_flower("dandelion_yellow")
	register_mgv6_flower("geranium")
	register_mgv6_flower("viola")
	register_mgv6_flower("dandelion_white")

	register_mgv6_mushroom("mushroom_brown")
	register_mgv6_mushroom("mushroom_red")

	register_mgv6_waterlily()
end

--
-- All other biome API mapgens
--

local function register_flower(seed, flower_name)
	minetest.register_decoration({
		name = "flowers:"..flower_name,
		deco_type = "simple",
		place_on = {"default:dirt_with_grass"},
		sidelen = 16,
		noise_params = {
			offset = -0.02,
			scale = 0.04,
			spread = {x = 200, y = 200, z = 200},
			seed = seed,
			octaves = 3,
			persist = 0.6
		},
		biomes = {"grassland", "deciduous_forest"},
		y_max = 31000,
		y_min = 1,
		decoration = "flowers:"..flower_name,
	})
end

local function register_mushroom(mushroom_name)
	minetest.register_decoration({
		name = "flowers:"..mushroom_name,
		deco_type = "simple",
		place_on = {"default:dirt_with_grass", "default:dirt_with_coniferous_litter"},
		sidelen = 16,
		noise_params = {
			offset = 0,
			scale = 0.006,
			spread = {x = 250, y = 250, z = 250},
			seed = 2,
			octaves = 3,
			persist = 0.66
		},
		biomes = {"deciduous_forest", "coniferous_forest"},
		y_max = 31000,
		y_min = 1,
		decoration = "flowers:"..mushroom_name,
	})
end

local function register_waterlily()
	minetest.register_decoration({
		name = "default:waterlily",
		deco_type = "simple",
		place_on = {"default:dirt"},
		sidelen = 16,
		noise_params = {
			offset = -0.12,
			scale = 0.3,
			spread = {x = 200, y = 200, z = 200},
			seed = 33,
			octaves = 3,
			persist = 0.7
		},
		biomes = {"rainforest_swamp", "savanna_shore", "deciduous_forest_shore"},
		y_max = 0,
		y_min = 0,
		decoration = "flowers:waterlily_waving",
		param2 = 0,
		param2_max = 3,
		place_offset_y = 1,
	})
end

function flowers.register_decorations()
	register_flower(436,     "rose")
	register_flower(19822,   "tulip")
	register_flower(1220999, "dandelion_yellow")
	register_flower(800081,  "chrysanthemum_green")
	register_flower(36662,   "geranium")
	register_flower(1133,    "viola")
	register_flower(73133,   "dandelion_white")
	register_flower(42,      "tulip_black")

	register_mushroom("mushroom_brown")
	register_mushroom("mushroom_red")

	register_waterlily()
end

--
-- Detect mapgen to select functions
--

local mg_name = minetest.get_mapgen_setting("mg_name")
if mg_name == "v6" then
	flowers.register_mgv6_decorations()
else
	flowers.register_decorations()
end


code:
name = flowers
description = Minetest Game mod: flowers
depends = default


code:
Minetest Game mod: game_commands
================================
See license.txt for license information.

Authors of source code
----------------------
rubenwardy (MIT)


code:
-- game_commands/init.lua

-- Load support for MT game translation.
local S = minetest.get_translator("game_commands")

minetest.register_chatcommand("killme", {
	description = S("Kill yourself to respawn"),
	func = function(name)
		local player = minetest.get_player_by_name(name)
		if player then
			if minetest.settings:get_bool("enable_damage") then
				player:set_hp(0)
				return true
			else
				for _, callback in pairs(minetest.registered_on_respawnplayers) do
					if callback(player) then
						return true
					end
				end

				-- There doesn't seem to be a way to get a default spawn pos
				-- from the lua API
				return false, S("No static_spawnpoint defined")
			end
		else
			-- Show error message if used when not logged in, eg: from IRC mod
			return false, S("You need to be online to be killed!")
		end
	end
})


code:
# textdomain: game_commands
Kill yourself to respawn=Selbstmord begehen, um zu Respawnen
No static_spawnpoint defined=Kein static_spawnpoint definiert
You need to be online to be killed!=Sie müssen online sein, um getötet zu werden!


code:
# textdomain: game_commands
Kill yourself to respawn=Suicídate para reaparecer
No static_spawnpoint defined=No se ha definido un punto de aparición
You need to be online to be killed!=¡Necesitas estar en línea para que te maten!


code:
# textdomain: game_commands
Kill yourself to respawn=Se suicider pour réapparaître
No static_spawnpoint defined=Pas de point d'apparition défini
You need to be online to be killed!=Vous devez être en ligne pour être tué !


code:
# textdomain: game_commands
Kill yourself to respawn=Bunuh diri untuk bangkit kembali
No static_spawnpoint defined=Tiada static_spawnpoint (titik bangkit statis) yang diatur
You need to be online to be killed!=Anda harus daring untuk dibunuh!


code:
# textdomain: game_commands
Kill yourself to respawn=Ucciditi per ricomparire
No static_spawnpoint defined=Nessuno static_spawnpoint definito
You need to be online to be killed!=Devi essere in linea per essere ucciso!


code:
# textdomain: game_commands
Kill yourself to respawn=Bunuh diri anda untuk lahir semula
No static_spawnpoint defined=Tiada titik permulaan statik (tetapan static_spawnpoint) ditakrifkan
You need to be online to be killed!=Anda mesti berada dalam talian untuk dibunuh!


code:
# textdomain: game_commands
Kill yourself to respawn=Убейте себя, чтобы возродиться
No static_spawnpoint defined=static_spawnpoint не определён
You need to be online to be killed!=Вы должны быть онлайн, чтобы убить себя!


code:
# textdomain: game_commands
Kill yourself to respawn=Döda dig själv för att respawna
No static_spawnpoint defined=Ingen static_spawnpoint definierat
You need to be online to be killed!=Du måsta vara online för att bli dödad!


code:
# textdomain: game_commands
Kill yourself to respawn=杀死自己并重生
No static_spawnpoint defined=static_spawnpoint 未定义
You need to be online to be killed!=您需要在线才能被杀死！


code:
# textdomain: game_commands
Kill yourself to respawn=殺死自己並重生
No static_spawnpoint defined=static_spawnpoint 未定義
You need to be online to be killed!=您需要在線才能被殺死！


code:
# textdomain: game_commands
Kill yourself to respawn=
No static_spawnpoint defined=
You need to be online to be killed!=


code:
name = game_commands
description = Minetest Game mod: game_commands


code:
Minetest Game mod: give_initial_stuff
=====================================
See license.txt for license information.

Authors of source code
----------------------
Perttu Ahola (celeron55) <celeron55@gmail.com> (MIT)
Various Minetest developers and contributors (MIT)


code:
-- gave_initial_stuff/init.lua

local stuff_string = minetest.settings:get("initial_stuff") or
		"default:pick_steel,default:axe_steel,default:shovel_steel," ..
		"default:torch 99,default:cobble 99"

give_initial_stuff = {
	items = {}
}

function give_initial_stuff.give(player)
	minetest.log("action",
			"Giving initial stuff to player " .. player:get_player_name())
	local inv = player:get_inventory()
	for _, stack in ipairs(give_initial_stuff.items) do
		inv:add_item("main", stack)
	end
end

function give_initial_stuff.add(stack)
	give_initial_stuff.items[#give_initial_stuff.items + 1] = ItemStack(stack)
end

function give_initial_stuff.clear()
	give_initial_stuff.items = {}
end

function give_initial_stuff.add_from_csv(str)
	local items = str:split(",")
	for _, itemname in ipairs(items) do
		give_initial_stuff.add(itemname)
	end
end

function give_initial_stuff.set_list(list)
	give_initial_stuff.items = list
end

function give_initial_stuff.get_list()
	return give_initial_stuff.items
end

give_initial_stuff.add_from_csv(stuff_string)
if minetest.settings:get_bool("give_initial_stuff") then
	minetest.register_on_newplayer(give_initial_stuff.give)
end


code:
name = give_initial_stuff
description = Minetest Game mod: give_initial_stuff
depends = default


code:
Minetest Game mod: map
======================
See license.txt for license information.

Authors of source code
----------------------
paramat (MIT)

Authors of media (textures)
---------------------------
TumeniNodes (CC BY-SA 3.0):
  map_mapping_kit.png (map)

paramat (CC BY-SA 3.0):
  map_mapping_kit.png (compass and pen)

Crafting
--------
map:mapping_kit

default:glass G
default:paper P
group:stick S
default:steel_ingot I
group:wood W
dye:black D

GPS
IPI
WPD

Usage
-----
In survival mode, use of the minimap requires the mapping kit item in your
inventory. It can take up to 5 seconds for adding to or removal from inventory
to have an effect, however to instantly allow the use of the minimap 'use'
(leftclick) the item.
Minimap radar mode is always disallowed in survival mode.

Minimap and minimap radar mode are automatically allowed in creative mode and
for any player with the 'creative' privilege.

The 'map.update_hud_flags()' function is global so can be redefined by a mod for
alternative behaviour.


code:
-- map/init.lua

-- Mod global namespace

map = {}

-- Load support for MT game translation.
local S = minetest.get_translator("map")

-- Cache creative mode setting

local creative_mode_cache = minetest.settings:get_bool("creative_mode")

-- Update HUD flags
-- Global to allow overriding

function map.update_hud_flags(player)
	local creative_enabled =
		(creative and creative.is_enabled_for(player:get_player_name())) or
		creative_mode_cache

	local minimap_enabled = creative_enabled or
		player:get_inventory():contains_item("main", "map:mapping_kit")
	local radar_enabled = creative_enabled

	player:hud_set_flags({
		minimap = minimap_enabled,
		minimap_radar = radar_enabled
	})
end

-- Set HUD flags 'on joinplayer'

minetest.register_on_joinplayer(function(player)
	map.update_hud_flags(player)
end)

-- Cyclic update of HUD flags

local function cyclic_update()
	for _, player in ipairs(minetest.get_connected_players()) do
		map.update_hud_flags(player)
	end
	minetest.after(5.3, cyclic_update)
end

minetest.after(5.3, cyclic_update)

-- Mapping kit item

minetest.register_craftitem("map:mapping_kit", {
	description = S("Mapping Kit") .. "\n" .. S("Use with 'Minimap' key"),
	inventory_image = "map_mapping_kit.png",
	stack_max = 1,
	groups = {flammable = 3},

	on_use = function(itemstack, user, pointed_thing)
		map.update_hud_flags(user)
	end,
})

-- Crafting

minetest.register_craft({
	output = "map:mapping_kit",
	recipe = {
		{"default:glass", "default:paper", "group:stick"},
		{"default:steel_ingot", "default:paper", "default:steel_ingot"},
		{"group:wood", "default:paper", "dye:black"},
	}
})

-- Fuel

minetest.register_craft({
	type = "fuel",
	recipe = "map:mapping_kit",
	burntime = 5,
})


code:
# textdomain: map
Mapping Kit=Kartenset
Use with 'Minimap' key=Mit „Karte an/aus“-Taste benutzen


code:
# textdomain: map
Mapping Kit=Kit de cartografía
Use with 'Minimap' key=Usar con la tecla 'Minimapa'


code:
# textdomain: map
Mapping Kit=Kit de carthographie
Use with 'Minimap' key=Utiliser avec le bouton « Minimap »


code:
# textdomain: map
Mapping Kit=Alat Pemetaan
Use with 'Minimap' key=Pakai dengan tombol 'Peta Mini'


code:
# textdomain: map
Mapping Kit=Kit di mappatura
Use with 'Minimap' key=Usalo col tasto 'Minimappa'


code:
# textdomain: map
Mapping Kit=Alat Pemetaan
Use with 'Minimap' key=Guna dengan kekunci 'Peta Mini'


code:
# textdomain: map
Mapping Kit=Картографический комплект
Use with 'Minimap' key=Используйте с ключом 'Minimap'


code:
# textdomain: map
Mapping Kit=Kartläggningssats
Use with 'Minimap' key=Använd med 'Minimap' tangent


code:
# textdomain: map
Mapping Kit=地图绘制工具包
Use with 'Minimap' key=与“迷你地图”键一起使用


code:
# textdomain: map
Mapping Kit=地圖繪製工具包
Use with 'Minimap' key=與“迷你地圖”鍵一起使用


code:
# textdomain: map
Mapping Kit=
Use with 'Minimap' key=


code:
name = map
description = Minetest Game mod: map
depends = default, dye
optional_depends = creative


code:
Minetest Game mod: player_api
=============================
See license.txt for license information.

Provides an API to allow multiple mods to set player models and textures.
Also sets the default model, texture, and player flags.
This mod is only for content related to the Player API and the player object.

Authors of source code
----------------------
Originally by celeron55, Perttu Ahola <celeron55@gmail.com> (LGPLv2.1+)
Various Minetest developers and contributors (LGPLv2.1+)

Authors of media (textures, models and sounds)
----------------------------------------------
stujones11 (CC BY-SA 3.0):
  character.b3d
  character.blend -- Both derived from a model by MirceaKitsune (CC BY-SA 3.0)

An0n3m0us (CC BY-SA 3.0):
  character.b3d
  character.blend -- Player animation improvement

Jordach (CC BY-SA 3.0):
  character.png

celeron55, Perttu Ahola <celeron55@gmail.com> (CC BY-SA 3.0):
  player.png
  player_back.png


code:
-- Minetest 0.4 mod: player
-- See README.txt for licensing and other information.

player_api = {}

-- Player animation blending
-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
local animation_blend = 0

player_api.registered_models = { }

-- Local for speed.
local models = player_api.registered_models

function player_api.register_model(name, def)
	models[name] = def
end

-- Player stats and animations
local player_model = {}
local player_textures = {}
local player_anim = {}
local player_sneak = {}
player_api.player_attached = {}

function player_api.get_animation(player)
	local name = player:get_player_name()
	return {
		model = player_model[name],
		textures = player_textures[name],
		animation = player_anim[name],
	}
end

-- Called when a player's appearance needs to be updated
function player_api.set_model(player, model_name)
	local name = player:get_player_name()
	local model = models[model_name]
	if model then
		if player_model[name] == model_name then
			return
		end
		player:set_properties({
			mesh = model_name,
			textures = player_textures[name] or model.textures,
			visual = "mesh",
			visual_size = model.visual_size or {x = 1, y = 1},
			collisionbox = model.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
			stepheight = model.stepheight or 0.6,
			eye_height = model.eye_height or 1.47,
		})
		player_api.set_animation(player, "stand")
	else
		player:set_properties({
			textures = {"player.png", "player_back.png"},
			visual = "upright_sprite",
			visual_size = {x = 1, y = 2},
			collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.75, 0.3},
			stepheight = 0.6,
			eye_height = 1.625,
		})
	end
	player_model[name] = model_name
end

function player_api.set_textures(player, textures)
	local name = player:get_player_name()
	local model = models[player_model[name]]
	local model_textures = model and model.textures or nil
	player_textures[name] = textures or model_textures
	player:set_properties({textures = textures or model_textures,})
end

function player_api.set_animation(player, anim_name, speed)
	local name = player:get_player_name()
	if player_anim[name] == anim_name then
		return
	end
	local model = player_model[name] and models[player_model[name]]
	if not (model and model.animations[anim_name]) then
		return
	end
	local anim = model.animations[anim_name]
	player_anim[name] = anim_name
	player:set_animation(anim, speed or model.animation_speed, animation_blend)
end

minetest.register_on_leaveplayer(function(player)
	local name = player:get_player_name()
	player_model[name] = nil
	player_anim[name] = nil
	player_textures[name] = nil
end)

-- Localize for better performance.
local player_set_animation = player_api.set_animation
local player_attached = player_api.player_attached

-- Prevent knockback for attached players
local old_calculate_knockback = minetest.calculate_knockback
function minetest.calculate_knockback(player, ...)
	if player_attached[player:get_player_name()] then
		return 0
	end
	return old_calculate_knockback(player, ...)
end

-- Check each player and apply animations
minetest.register_globalstep(function()
	for _, player in pairs(minetest.get_connected_players()) do
		local name = player:get_player_name()
		local model_name = player_model[name]
		local model = model_name and models[model_name]
		if model and not player_attached[name] then
			local controls = player:get_player_control()
			local animation_speed_mod = model.animation_speed or 30

			-- Determine if the player is sneaking, and reduce animation speed if so
			if controls.sneak then
				animation_speed_mod = animation_speed_mod / 2
			end

			-- Apply animations based on what the player is doing
			if player:get_hp() == 0 then
				player_set_animation(player, "lay")
			-- Determine if the player is walking
			elseif controls.up or controls.down or controls.left or controls.right then
				if player_sneak[name] ~= controls.sneak then
					player_anim[name] = nil
					player_sneak[name] = controls.sneak
				end
				if controls.LMB or controls.RMB then
					player_set_animation(player, "walk_mine", animation_speed_mod)
				else
					player_set_animation(player, "walk", animation_speed_mod)
				end
			elseif controls.LMB or controls.RMB then
				player_set_animation(player, "mine", animation_speed_mod)
			else
				player_set_animation(player, "stand", animation_speed_mod)
			end
		end
	end
end)


code:
-- player/init.lua

dofile(minetest.get_modpath("player_api") .. "/api.lua")

-- Default player appearance
player_api.register_model("character.b3d", {
	animation_speed = 30,
	textures = {"character.png", },
	animations = {
		-- Standard animations.
		stand     = {x = 0,   y = 79},
		lay       = {x = 162, y = 166},
		walk      = {x = 168, y = 187},
		mine      = {x = 189, y = 198},
		walk_mine = {x = 200, y = 219},
		sit       = {x = 81,  y = 160},
	},
	collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
	stepheight = 0.6,
	eye_height = 1.47,
})

-- Update appearance when the player joins
minetest.register_on_joinplayer(function(player)
	player_api.player_attached[player:get_player_name()] = false
	player_api.set_model(player, "character.b3d")
	player:set_local_animation(
		{x = 0,   y = 79},
		{x = 168, y = 187},
		{x = 189, y = 198},
		{x = 200, y = 219},
		30
	)
end)


code:
name = player_api
description = Minetest Game mod: player_api


code:
Minetest Game mod: screwdriver
==============================
See license.txt for license information.

License of source code
----------------------
Originally by RealBadAngel, Maciej Kasatkin (LGPLv2.1+)
Various Minetest developers and contributors (LGPLv2.1+)

License of media (textures)
---------------------------
Created by Gambit (CC BY-SA 3.0):
  screwdriver.png


code:
-- screwdriver/init.lua

screwdriver = {}

-- Load support for MT game translation.
local S = minetest.get_translator("screwdriver")

screwdriver.ROTATE_FACE = 1
screwdriver.ROTATE_AXIS = 2
screwdriver.disallow = function(pos, node, user, mode, new_param2)
	return false
end
screwdriver.rotate_simple = function(pos, node, user, mode, new_param2)
	if mode ~= screwdriver.ROTATE_FACE then
		return false
	end
end

-- For attached wallmounted nodes: returns true if rotation is valid
-- simplified version of minetest:builtin/game/falling.lua#L148.
local function check_attached_node(pos, rotation)
	local d = minetest.wallmounted_to_dir(rotation)
	local p2 = vector.add(pos, d)
	local n = minetest.get_node(p2).name
	local def2 = minetest.registered_nodes[n]
	if def2 and not def2.walkable then
		return false
	end
	return true
end

screwdriver.rotate = {}

local facedir_tbl = {
	[screwdriver.ROTATE_FACE] = {
		[0] = 1, [1] = 2, [2] = 3, [3] = 0,
		[4] = 5, [5] = 6, [6] = 7, [7] = 4,
		[8] = 9, [9] = 10, [10] = 11, [11] = 8,
		[12] = 13, [13] = 14, [14] = 15, [15] = 12,
		[16] = 17, [17] = 18, [18] = 19, [19] = 16,
		[20] = 21, [21] = 22, [22] = 23, [23] = 20,
	},
	[screwdriver.ROTATE_AXIS] = {
		[0] = 4, [1] = 4, [2] = 4, [3] = 4,
		[4] = 8, [5] = 8, [6] = 8, [7] = 8,
		[8] = 12, [9] = 12, [10] = 12, [11] = 12,
		[12] = 16, [13] = 16, [14] = 16, [15] = 16,
		[16] = 20, [17] = 20, [18] = 20, [19] = 20,
		[20] = 0, [21] = 0, [22] = 0, [23] = 0,
	},
}

screwdriver.rotate.facedir = function(pos, node, mode)
	local rotation = node.param2 % 32 -- get first 5 bits
	local other = node.param2 - rotation
	rotation = facedir_tbl[mode][rotation] or 0
	return rotation + other
end

screwdriver.rotate.colorfacedir = screwdriver.rotate.facedir

local wallmounted_tbl = {
	[screwdriver.ROTATE_FACE] = {[2] = 5, [3] = 4, [4] = 2, [5] = 3, [1] = 0, [0] = 1},
	[screwdriver.ROTATE_AXIS] = {[2] = 5, [3] = 4, [4] = 2, [5] = 1, [1] = 0, [0] = 3}
}

screwdriver.rotate.wallmounted = function(pos, node, mode)
	local rotation = node.param2 % 8 -- get first 3 bits
	local other = node.param2 - rotation
	rotation = wallmounted_tbl[mode][rotation] or 0
	if minetest.get_item_group(node.name, "attached_node") ~= 0 then
		-- find an acceptable orientation
		for i = 1, 5 do
			if not check_attached_node(pos, rotation) then
				rotation = wallmounted_tbl[mode][rotation] or 0
			else
				break
			end
		end
	end
	return rotation + other
end

screwdriver.rotate.colorwallmounted = screwdriver.rotate.wallmounted

-- Handles rotation
screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses)
	if pointed_thing.type ~= "node" then
		return
	end

	local pos = pointed_thing.under
	local player_name = user and user:get_player_name() or ""

	if minetest.is_protected(pos, player_name) then
		minetest.record_protection_violation(pos, player_name)
		return
	end

	local node = minetest.get_node(pos)
	local ndef = minetest.registered_nodes[node.name]
	if not ndef then
		return itemstack
	end
	-- can we rotate this paramtype2?
	local fn = screwdriver.rotate[ndef.paramtype2]
	if not fn and not ndef.on_rotate then
		return itemstack
	end

	local should_rotate = true
	local new_param2
	if fn then
		new_param2 = fn(pos, node, mode)
	else
		new_param2 = node.param2
	end

	-- Node provides a handler, so let the handler decide instead if the node can be rotated
	if ndef.on_rotate then
		-- Copy pos and node because callback can modify it
		local result = ndef.on_rotate(vector.new(pos),
				{name = node.name, param1 = node.param1, param2 = node.param2},
				user, mode, new_param2)
		if result == false then -- Disallow rotation
			return itemstack
		elseif result == true then
			should_rotate = false
		end
	elseif ndef.on_rotate == false then
		return itemstack
	elseif ndef.can_dig and not ndef.can_dig(pos, user) then
		return itemstack
	end

	if should_rotate and new_param2 ~= node.param2 then
		node.param2 = new_param2
		minetest.swap_node(pos, node)
		minetest.check_for_falling(pos)
	end

	if not (creative and creative.is_enabled_for and
			creative.is_enabled_for(player_name)) then
		itemstack:add_wear(65535 / ((uses or 200) - 1))
	end

	return itemstack
end

-- Screwdriver
minetest.register_tool("screwdriver:screwdriver", {
	description = S("Screwdriver") .. "\n" .. S("(left-click rotates face, right-click rotates axis)"),
	inventory_image = "screwdriver.png",
	groups = {tool = 1},
	on_use = function(itemstack, user, pointed_thing)
		screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE, 200)
		return itemstack
	end,
	on_place = function(itemstack, user, pointed_thing)
		screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS, 200)
		return itemstack
	end,
})

minetest.register_craft({
	output = "screwdriver:screwdriver",
	recipe = {
		{"default:steel_ingot"},
		{"group:stick"}
	}
})

minetest.register_alias("screwdriver:screwdriver1", "screwdriver:screwdriver")
minetest.register_alias("screwdriver:screwdriver2", "screwdriver:screwdriver")
minetest.register_alias("screwdriver:screwdriver3", "screwdriver:screwdriver")
minetest.register_alias("screwdriver:screwdriver4", "screwdriver:screwdriver")


code:
# textdomain: screwdriver
Screwdriver=Schraubendreher
(left-click rotates face, right-click rotates axis)=(Linksklick dreht Seite, Rechtsklick dreht Achse)


code:
# textdomain: screwdriver
Screwdriver=Destornillador
(left-click rotates face, right-click rotates axis)=(clic-izquierdo gira la cara, clic-derecho rota el eje)


code:
# textdomain: screwdriver
Screwdriver=Tournevis
(left-click rotates face, right-click rotates axis)=(clic gauche pour changer de face, clic droit pour changer d'axe)


code:
# textdomain: screwdriver
Screwdriver=Obeng
(left-click rotates face, right-click rotates axis)=(klik kiri putar sisi, klik kanan putar sumbu)


code:
# textdomain: screwdriver
Screwdriver=Cacciavite
(left-click rotates face, right-click rotates axis)=(click sinistro ruota la faccia, click destro ruota l'asse)


code:
# textdomain: screwdriver
Screwdriver=Pemutar Skru
(left-click rotates face, right-click rotates axis)=(klik-kiri putar muka, klik-kanan putar paksi)


code:
# textdomain: screwdriver
Screwdriver=Отвёртка
(left-click rotates face, right-click rotates axis)=(клик левой кнопкой мыши вращает грань, клик правой кнопкой мыши вращает ось)


code:
# textdomain: screwdriver
Screwdriver=Skruvmejsel
(left-click rotates face, right-click rotates axis)=(vänster-klick roterar ansikte, höger-klick roterar axeln)


code:
# textdomain: screwdriver
Screwdriver=螺丝刀
(left-click rotates face, right-click rotates axis)=（左键单击旋转面，右键单击旋转轴）


code:
# textdomain: screwdriver
Screwdriver=螺絲刀
(left-click rotates face, right-click rotates axis)=（左鍵單擊旋轉面，右鍵單擊旋轉軸）


code:
# textdomain: screwdriver
Screwdriver=
(left-click rotates face, right-click rotates axis)=


code:
name = screwdriver
description = Minetest Game mod: screwdriver


code:
Minetest Game mod: sethome
==========================
See license.txt for license information.

Authors of source code
----------------------
sfan5 (MIT)


code:
-- sethome/init.lua

sethome = {}

-- Load support for MT game translation.
local S = minetest.get_translator("sethome")

local homes_file = minetest.get_worldpath() .. "/homes"
local homepos = {}

local function loadhomes()
	local input = io.open(homes_file, "r")
	if not input then
		return -- no longer an error
	end

	-- Iterate over all stored positions in the format "x y z player" for each line
	for pos, name in input:read("*a"):gmatch("(%S+ %S+ %S+)%s([%w_-]+)[\r\n]") do
		homepos[name] = minetest.string_to_pos(pos)
	end
	input:close()
end

loadhomes()

sethome.set = function(name, pos)
	local player = minetest.get_player_by_name(name)
	if not player or not pos then
		return false
	end
	player:set_attribute("sethome:home", minetest.pos_to_string(pos))

	-- remove `name` from the old storage file
	if not homepos[name] then
		return true
	end
	local data = {}
	local output = io.open(homes_file, "w")
	if output then
		homepos[name] = nil
		for i, v in pairs(homepos) do
			table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, i))
		end
		output:write(table.concat(data))
		io.close(output)
		return true
	end
	return true -- if the file doesn't exist - don't return an error.
end

sethome.get = function(name)
	local player = minetest.get_player_by_name(name)
	local pos = minetest.string_to_pos(player:get_attribute("sethome:home"))
	if pos then
		return pos
	end

	-- fetch old entry from storage table
	pos = homepos[name]
	if pos then
		return vector.new(pos)
	else
		return nil
	end
end

sethome.go = function(name)
	local pos = sethome.get(name)
	local player = minetest.get_player_by_name(name)
	if player and pos then
		player:set_pos(pos)
		return true
	end
	return false
end

minetest.register_privilege("home", {
	description = S("Can use /sethome and /home"),
	give_to_singleplayer = false
})

minetest.register_chatcommand("home", {
	description = S("Teleport you to your home point"),
	privs = {home = true},
	func = function(name)
		if sethome.go(name) then
			return true, S("Teleported to home!")
		end
		return false, S("Set a home using /sethome")
	end,
})

minetest.register_chatcommand("sethome", {
	description = S("Set your home point"),
	privs = {home = true},
	func = function(name)
		name = name or "" -- fallback to blank name if nil
		local player = minetest.get_player_by_name(name)
		if player and sethome.set(name, player:get_pos()) then
			return true, S("Home set!")
		end
		return false, S("Player not found!")
	end,
})


code:
# textdomain: sethome
Can use /sethome and /home=Kann /sethome und /home benutzen
Teleport you to your home point=Teleportieren Sie sich zu Ihrem Zuhause-Punkt
Teleported to home!=Nach Hause teleportiert!
Set a home using /sethome=Ein Zuhause mit /sethome setzen
Set your home point=Ihren Zuhause-Punkt setzen
Home set!=Zuhause gesetzt!
Player not found!=Spieler nicht gefunden!


code:
# textdomain: sethome
Can use /sethome and /home=Puedes usar /sethome y /home
Teleport you to your home point=Teletranspórtate a tu hogar
Teleported to home!=¡Teletransportado a tu hogar!
Set a home using /sethome=Establece tu hogar usando /sethome
Set your home point=Establece el sitio de tu hogar
Home set!=¡Hogar establecido!
Player not found!=¡Jugador no encontrado!


code:
# textdomain: sethome
Can use /sethome and /home=Peut utiliser /sethome et /home
Teleport you to your home point=Vous téléporter à votre domicile
Teleported to home!=Téléporté à votre domicile !
Set a home using /sethome=Définir un domicile en utilisant /sethome
Set your home point=Définir votre domicile
Home set!=Domicile défini !
Player not found!=Joueur non trouvé !


code:
# textdomain: sethome
Can use /sethome and /home=Boleh pakai /sethome dan /home
Teleport you to your home point=Teleportasi ke rumah Anda
Teleported to home!=Teleportasi ke rumah!
Set a home using /sethome=Atur letak rumah dengan /sethome
Set your home point=Atur letak rumah
Home set!=Letak rumah diatur!
Player not found!=Pemain tidak ditemukan!


code:
# textdomain: sethome
Can use /sethome and /home=Può usare /sethome e /home
Teleport you to your home point=Ti teletrasporta al tuo punto di domicilio
Teleported to home!=Teletrasportato a casa!
Set a home using /sethome=Imposta un domicilio usando /sethome
Set your home point=Imposta il tuo punto di domicilio
Home set!=Domicilio impostato!
Player not found!=Giocatore non trovato!


code:
# textdomain: sethome
Can use /sethome and /home=Boleh guna /sethome dan /home
Teleport you to your home point=Teleportasikan anda ke titik rumah anda
Teleported to home!=Diteleportasikan ke rumah!
Set a home using /sethome=Tetapkan rumah menggunakan /sethome
Set your home point=Tetapkan titik rumah anda
Home set!=Rumah ditetapkan!
Player not found!=Pemain tidak dijumpai!


code:
# textdomain: sethome
Can use /sethome and /home=Возможность использовать /sethome и /home
Teleport you to your home point=Вы телепортируетесь в свою домашнюю точку
Teleported to home!=Вы телепортировались домой!
Set a home using /sethome=Установите домашнюю точку, используя /sethome
Set your home point=Установите вашу домашнюю точку
Home set!=Домашняя точка установлена!
Player not found!=Игрок не обнаружен!


code:
# textdomain: sethome
Can use /sethome and /home=Kan används /sethome och /home
Teleport you to your home point=Teleportera dig till din hempunkt
Teleported to home!=Teleporterad hem!
Set a home using /sethome=Ställ in ett hem med /sethome
Set your home point=Ställ in din hempunkt
Home set!=Hem inställt!
Player not found!=Spelare inte hittad!


code:
# textdomain: sethome
Can use /sethome and /home=可以使用/sethome和/home
Teleport you to your home point=传送您到您家的地点
Teleported to home!=已传送到家！
Set a home using /sethome=使用/sethome设定家
Set your home point=设定您家的地点
Home set!=已设定家！
Player not found!=未找到玩家！


code:
# textdomain: sethome
Can use /sethome and /home=可以使用/sethome和/home
Teleport you to your home point=傳送您到您家的地點
Teleported to home!=已傳送到家！
Set a home using /sethome=使用/sethome設定家
Set your home point=設定您家的地點
Home set!=已設定家！
Player not found!=未找到玩家！


code:
# textdomain: sethome
Can use /sethome and /home=
Teleport you to your home point=
Teleported to home!=
Set a home using /sethome=
Set your home point=
Home set!=
Player not found!=


code:
name = sethome
description = Minetest Game mod: sethome


code:
Minetest Game mod: sfinv
========================
See license.txt for license information.

Simple Fast Inventory.
A cleaner, simpler, solution to having an advanced inventory in Minetest.
See game_api.txt for this mod's API.
Available for use outside of MTG here:
https://forum.minetest.net/viewtopic.php?t=19765

Authors of source code
----------------------
rubenwardy (MIT)

Authors of media
----------------
paramat (CC BY-SA 3.0):
  sfinv_crafting_arrow.png - derived from a texture by BlockMen (CC BY-SA 3.0)


code:
sfinv = {
	pages = {},
	pages_unordered = {},
	contexts = {},
	enabled = true
}

function sfinv.register_page(name, def)
	assert(name, "Invalid sfinv page. Requires a name")
	assert(def, "Invalid sfinv page. Requires a def[inition] table")
	assert(def.get, "Invalid sfinv page. Def requires a get function.")
	assert(not sfinv.pages[name], "Attempt to register already registered sfinv page " .. dump(name))

	sfinv.pages[name] = def
	def.name = name
	table.insert(sfinv.pages_unordered, def)
end

function sfinv.override_page(name, def)
	assert(name, "Invalid sfinv page override. Requires a name")
	assert(def, "Invalid sfinv page override. Requires a def[inition] table")
	local page = sfinv.pages[name]
	assert(page, "Attempt to override sfinv page " .. dump(name) .. " which does not exist.")
	for key, value in pairs(def) do
		page[key] = value
	end
end

function sfinv.get_nav_fs(player, context, nav, current_idx)
	-- Only show tabs if there is more than one page
	if #nav > 1 then
		return "tabheader[0,0;sfinv_nav_tabs;" .. table.concat(nav, ",") ..
				";" .. current_idx .. ";true;false]"
	else
		return ""
	end
end

local theme_inv = [[
		image[0,5.2;1,1;gui_hb_bg.png]
		image[1,5.2;1,1;gui_hb_bg.png]
		image[2,5.2;1,1;gui_hb_bg.png]
		image[3,5.2;1,1;gui_hb_bg.png]
		image[4,5.2;1,1;gui_hb_bg.png]
		image[5,5.2;1,1;gui_hb_bg.png]
		image[6,5.2;1,1;gui_hb_bg.png]
		image[7,5.2;1,1;gui_hb_bg.png]
		list[current_player;main;0,5.2;8,1;]
		list[current_player;main;0,6.35;8,3;8]
	]]

function sfinv.make_formspec(player, context, content, show_inv, size)
	local tmp = {
		size or "size[8,9.1]",
		sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx),
		show_inv and theme_inv or "",
		content
	}
	return table.concat(tmp, "")
end

function sfinv.get_homepage_name(player)
	return "sfinv:crafting"
end

function sfinv.get_formspec(player, context)
	-- Generate navigation tabs
	local nav = {}
	local nav_ids = {}
	local current_idx = 1
	for i, pdef in pairs(sfinv.pages_unordered) do
		if not pdef.is_in_nav or pdef:is_in_nav(player, context) then
			nav[#nav + 1] = pdef.title
			nav_ids[#nav_ids + 1] = pdef.name
			if pdef.name == context.page then
				current_idx = #nav_ids
			end
		end
	end
	context.nav = nav_ids
	context.nav_titles = nav
	context.nav_idx = current_idx

	-- Generate formspec
	local page = sfinv.pages[context.page] or sfinv.pages["404"]
	if page then
		return page:get(player, context)
	else
		local old_page = context.page
		local home_page = sfinv.get_homepage_name(player)

		if old_page == home_page then
			minetest.log("error", "[sfinv] Couldn't find " .. dump(old_page) ..
					", which is also the old page")

			return ""
		end

		context.page = home_page
		assert(sfinv.pages[context.page], "[sfinv] Invalid homepage")
		minetest.log("warning", "[sfinv] Couldn't find " .. dump(old_page) ..
				" so switching to homepage")

		return sfinv.get_formspec(player, context)
	end
end

function sfinv.get_or_create_context(player)
	local name = player:get_player_name()
	local context = sfinv.contexts[name]
	if not context then
		context = {
			page = sfinv.get_homepage_name(player)
		}
		sfinv.contexts[name] = context
	end
	return context
end

function sfinv.set_context(player, context)
	sfinv.contexts[player:get_player_name()] = context
end

function sfinv.set_player_inventory_formspec(player, context)
	local fs = sfinv.get_formspec(player,
			context or sfinv.get_or_create_context(player))
	player:set_inventory_formspec(fs)
end

function sfinv.set_page(player, pagename)
	local context = sfinv.get_or_create_context(player)
	local oldpage = sfinv.pages[context.page]
	if oldpage and oldpage.on_leave then
		oldpage:on_leave(player, context)
	end
	context.page = pagename
	local page = sfinv.pages[pagename]
	if page.on_enter then
		page:on_enter(player, context)
	end
	sfinv.set_player_inventory_formspec(player, context)
end

function sfinv.get_page(player)
	local context = sfinv.contexts[player:get_player_name()]
	return context and context.page or sfinv.get_homepage_name(player)
end

minetest.register_on_joinplayer(function(player)
	if sfinv.enabled then
		sfinv.set_player_inventory_formspec(player)
	end
end)

minetest.register_on_leaveplayer(function(player)
	sfinv.contexts[player:get_player_name()] = nil
end)

minetest.register_on_player_receive_fields(function(player, formname, fields)
	if formname ~= "" or not sfinv.enabled then
		return false
	end

	-- Get Context
	local name = player:get_player_name()
	local context = sfinv.contexts[name]
	if not context then
		sfinv.set_player_inventory_formspec(player)
		return false
	end

	-- Was a tab selected?
	if fields.sfinv_nav_tabs and context.nav then
		local tid = tonumber(fields.sfinv_nav_tabs)
		if tid and tid > 0 then
			local id = context.nav[tid]
			local page = sfinv.pages[id]
			if id and page then
				sfinv.set_page(player, id)
			end
		end
	else
		-- Pass event to page
		local page = sfinv.pages[context.page]
		if page and page.on_player_receive_fields then
			return page:on_player_receive_fields(player, context, fields)
		end
	end
end)


code:
-- sfinv/init.lua

dofile(minetest.get_modpath("sfinv") .. "/api.lua")

-- Load support for MT game translation.
local S = minetest.get_translator("sfinv")

sfinv.register_page("sfinv:crafting", {
	title = S("Crafting"),
	get = function(self, player, context)
		return sfinv.make_formspec(player, context, [[
				list[current_player;craft;1.75,0.5;3,3;]
				list[current_player;craftpreview;5.75,1.5;1,1;]
				image[4.75,1.5;1,1;sfinv_crafting_arrow.png]
				listring[current_player;main]
				listring[current_player;craft]
			]], true)
	end
})


code:
# textdomain:sfinv
Crafting=Fertigung


code:
# textdomain:sfinv
Crafting=Creación


code:
# textdomain:sfinv
Crafting=Artisanat


code:
# textdomain: sfinv
Crafting=Kerajinan


code:
# textdomain:sfinv
Crafting=Pertukangan


code:
# textdomain:sfinv
Crafting=Крафтинг


code:
# textdomain:sfinv
Crafting=合成


code:
# textdomain: sfinv
Crafting=


code:
name = sfinv
description = Minetest Game mod: sfinv


code:
Minetest Game mod: spawn
========================
See license.txt for license information.

Authors of source code
----------------------
paramat (MIT)


code:
-- spawn/init.lua

-- Disable by mapgen, setting or if 'static_spawnpoint' is set
--------------------------------------------------------------

local mg_name = minetest.get_mapgen_setting("mg_name")
if mg_name == "v6" or mg_name == "singlenode" or
		minetest.settings:get("static_spawnpoint") or
		minetest.settings:get_bool("engine_spawn") then
	return
end

-- Parameters
-------------

-- Resolution of search grid in nodes.
local res = 64
-- Number of points checked in the square search grid (edge * edge).
local checks = 128 * 128
-- Starting point for biome checks. This also sets the y co-ordinate for all
-- points checked, so the suitable biomes must be active at this y.
local pos = {x = 0, y = 8, z = 0}

-- Table of suitable biomes

local biome_ids = {
	minetest.get_biome_id("taiga"),
	minetest.get_biome_id("coniferous_forest"),
	minetest.get_biome_id("deciduous_forest"),
	minetest.get_biome_id("grassland"),
	minetest.get_biome_id("savanna"),
}

-- End of parameters
--------------------

-- Direction table

local dirs = {
	{x = 0, y = 0, z = 1},
	{x = -1, y = 0, z = 0},
	{x = 0, y = 0, z = -1},
	{x = 1, y = 0, z = 0},
}

-- Initial variables

local edge_len = 1
local edge_dist = 0
local dir_step = 0
local dir_ind = 1
local searched = false
local success = false
local spawn_pos = {}

-- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'.
-- This accounts for how mapchunks are not generated if they or their shell exceed
-- 'mapgen_limit'.

local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit"))
local chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
local spawn_limit = math.max(mapgen_limit - (chunksize + 1) * 16, 0)

--Functions
-----------

-- Get next position on square search spiral

local function next_pos()
	if edge_dist == edge_len then
		edge_dist = 0
		dir_ind = dir_ind + 1
		if dir_ind == 5 then
			dir_ind = 1
		end
		dir_step = dir_step + 1
		edge_len = math.floor(dir_step / 2) + 1
	end

	local dir = dirs[dir_ind]
	local move = vector.multiply(dir, res)

	edge_dist = edge_dist + 1

	return vector.add(pos, move)
end

-- Spawn position search

local function search()
	for iter = 1, checks do
		local biome_data = minetest.get_biome_data(pos)
		-- Sometimes biome_data is nil
		local biome = biome_data and biome_data.biome
		for id_ind = 1, #biome_ids do
			local biome_id = biome_ids[id_ind]
			if biome == biome_id then
				local spawn_y = minetest.get_spawn_level(pos.x, pos.z)
				if spawn_y then
					spawn_pos = {x = pos.x, y = spawn_y, z = pos.z}
					return true
				end
			end
		end

		pos = next_pos()
		-- Check for position being outside world edge
		if math.abs(pos.x) > spawn_limit or math.abs(pos.z) > spawn_limit then
			return false
		end
	end

	return false
end

-- On new player spawn and player respawn

-- Search for spawn position once per server session. If successful, store
-- position and reposition players, otherwise leave them at engine spawn
-- position.

local function on_spawn(player)
	if not searched then
		success = search()
		searched = true
	end
	if success then
		player:set_pos(spawn_pos)
	end
	return success
end

minetest.register_on_newplayer(function(player)
	on_spawn(player)
end)

local enable_bed_respawn = minetest.settings:get_bool("enable_bed_respawn")
if enable_bed_respawn == nil then
	enable_bed_respawn = true
end

minetest.register_on_respawnplayer(function(player)
	-- Avoid respawn conflict with beds mod
	if beds and enable_bed_respawn and
			beds.spawn[player:get_player_name()] then
		return
	end

	return on_spawn(player)
end)


code:
name = spawn
description = Minetest Game mod: spawn
depends = default
optional_depends = beds


code:
Minetest Game mod: stairs
=========================
See license.txt for license information.

Authors of source code
----------------------
Originally by Kahrl <kahrl@gmx.net> (LGPLv2.1+) and
celeron55, Perttu Ahola <celeron55@gmail.com> (LGPLv2.1+)
Various Minetest developers and contributors (LGPLv2.1+)

Authors of media (textures)
---------------------------

Textures
--------
Copyright (c) 2018 Shara RedCat (CC BY-SA 3.0):
  Derived from a texture by PilzAdam (CC BY-SA 3.0):
    stairs_obsidian_glass_outer_stairside.png
    stairs_obsidian_glass_stairside.png

Copyright (c) 2018 TumeniNodes (CC BY-SA 3.0):
  Derived from a texture by celeron55 (CC BY-SA 3.0) and
      converted to bright white by Krock (CC BY-SA 3.0):
    stairs_glass_stairside.png
    stairs_glass_split.png
  Derived from a texture by PilzAdam (CC BY-SA 3.0):
    stairs_obsidian_glass_split.png