-- This is the Minefall garbage core repository.
-- Author: Astrobe
-- Licence (code): same as Minetest.
-- Licence (sound): teleport sound from Nether mod, CC0 1.0

mfplayers = {}
local MAX_ENERGY=5 
local talents=minetest.get_mod_storage()

local random=math.random
mf={}

function mf.is_keymaster(name) return mfplayers[name].talent=="keymaster" end
function mf.is_flyer(name) return mfplayers[name].talent=="flyer" end
function mf.is_diver(name) return mfplayers[name].talent=="diver" end

function mf.clan_ok(name, pos)
	local meta=minetest.get_meta(pos)
	if not meta then return true end
	local owner=meta:get_string("owner") or ""
	if owner=="" then return true end
	if (string.len(owner)+string.len(name))%2==0 then return true end
	minetest.chat_send_player(name, "Sorry, this was placed by the other clan")
end



hb.register_hudbar("energy", 0xFFFFFF, "Mana",
{ bar = "sprint_stamina_bar.png", icon = "sprint_stamina_icon.png^[transform1" },
0, 0,
false, "%s: %.1f/%.1f")

-- local spawnpos =minetest.setting_get_pos("static_spawnpoint") or {x=0,y=0,z=0}
local function givetip(name)
	local tips=
	{
		"Eating when you are full HP will refill your mana instead.",
		"Coal in stone can catch fire and explode.",
		"When you get your crafting guide, make a copy before you make your crafting sign.",
		"Bored at night? Keep the crafting and furnace work for night time.",
		"Get a tip with /tips.",
		"The compass can detect nearby ores, and lava.",
		"Hit a beacon with a compass to set your secondary waypoint.",
		"Get the news with /news.",
		"Keep track of how many lamps you have. You don't want to forget one somewhere.",
		"Keep spare food, lamps, weapons, armor near your home so you can retrieve your stuff if something bad happens.",
		"Catch butterflies with a net and place them in a hive to get honey. Place flowers next to the hive.",
		"You can catch fish with a net.",
		'Check who is online with /status.',
		"Storms bring bad news. Take cover.",
		"Danger often comes from above. Look *up*.",
		"One day is one hour.",
		"Beware: seawater floods.", 
		"Whales appear during the day, near snow above 75 meters.",
		"Different woods have different burning times.",
		"Most mobs regenerate HP over time. Finish them off quickly and be careful when you chase one.",
		"Know when to run away.",
		"The rock crab, the ice spider, the red and green giant wasps can drop colored Mese.",
		"The giant beetle and the manticore drop seeds.",
		"Ice can act as water for crops, but it will eventually melt.",
		"Don't spam the sword. Wait until it comes back to rest position for another hit.",
		"The hammer is slow but has a great stun effect.",
		"You can set your home beacon by hitting a beacon with a green mese crystal. The HUD X mark will be updated accordingly.",
		"Beware not to hit your allies.",
		"There are two clans: men and women. Players can only use the beacons and void chests of their clan.",
		"Beginners: don't assume, check or ask and listen. Regulars: just because you got yourself good equipment doesn't mean you are invincible.",
		"Placing loot boxes is the only way to get RP.",
		"You can check if a block is under your protection with the screwdriver.",
		"You can open a loot box for 0 RP with a green mese crystal fragment.",
		"You can pick up most blocks (including ruins walls) with an obsidian shard.",
	}
	minetest.chat_send_player(name, minetest.colorize("pink",tips[random(1,#tips)]))
end

minetest.register_chatcommand("tips", { func = function(name) givetip(name) end})


minetest.register_on_item_eat(function(hp_change, replace, itemstack, user)
	if hp_change + user:get_hp() <= 20 then return end
	local name=user:get_player_name()
	if not name then return end
	local e=hp_change+user:get_hp() - 20
	mfplayers[name].energy=math.min(mfplayers[name].max_energy, mfplayers[name].energy+e)
	hb.change_hudbar(user, "energy", mfplayers[name].energy)
	return nil
end)
	


local max=math.max
minetest.register_globalstep(function(dtime)
	--Loop through all connected players
	--[[
	local lag=dtime>=1
	if lag then minetest.log("warning", "Lag detected") end
	]]

	for playerName,playerInfo in pairs(mfplayers) do
		local player = minetest.get_player_by_name(playerName)
		local change=false
		local maxe=playerInfo.max_energy
		local cached_e=playerInfo.cached_e or 0
		-- if lag happens while a player is levitating, they might fall hard or go higher than expected.
		-- We give a free damage cancellation so that they don't take unfair damage.
		-- if lag then mfplayers[playerName].shielded=true end
		if player ~= nil then
				local physics=player:get_physics_override()
				local ctrl=player:get_player_control_bits()%32
				if (ctrl>=16) and playerInfo.energy>dtime then
					physics.gravity= -0.1
					local drain= (mf.is_flyer(playerName) and 1) or 4 
					playerInfo.energy=max(playerInfo.energy-dtime*(drain-playerInfo.regen), 0)
					change=true
				elseif playerInfo.energy < maxe then
					physics.gravity=1
					playerInfo.energy=math.min(playerInfo.energy+dtime*playerInfo.regen, maxe)
					change=true
				else
					change=physics.gravity~=1
					physics.gravity=1
				end
				if change==true then
					player:set_physics_override(physics)
					if math.abs(cached_e-playerInfo.energy)>=0.1 or (playerInfo.energy==maxe and cached_e ~= maxe) then
						hb.change_hudbar(player, "energy", playerInfo.energy, max(maxe,5))
						playerInfo.cached_e=playerInfo.energy
					end
				end
		end
	end
end)


-- Trash can by Prestidigitator
--[[
    local trashInv = minetest.create_detached_inventory(
                        "trash",
                        {
                           on_put = function(inv, toList, toIndex, stack, player)
                              inv:set_stack(toList, toIndex, ItemStack(nil))
                           end
                        })
    trashInv:set_size("main", 1)

    minetest.register_on_joinplayer(
       function(player)
          player:set_inventory_formspec(
             "size[10,7.5]"..
             "list[current_player;main;0,3.5;8,4;]"..
             "list[current_player;craft;3,0;3,3;]"..
             "list[current_player;craftpreview;7,1;1,1;]"..
             "label[9,3.5;Trash]"..
             "list[detached:trash;main;9,4.5;1,1;]"
             )
    end)
--]]
-- watercraft
minetest.register_craft({
	output = 'default:snowblock 4',
	type="shapeless",
	recipe = { "default:ice" }
})


-- News code derived from "szutil_motd".
-- Calculate form dimensions (configurable) and spec strings.
local fspref, fssuff
do
	local fsw = 15
	local fsh = 12
	local tbw = fsw - 0.5
	local tbh = fsh - 0.5
	fspref = "size[" .. fsw .. "," .. fsh .. ",true]" .. "textarea[0.25,0.25;" .. tbw .. "," .. tbh .. ";;;"
	fssuff = "]button_exit[0," .. tbh .. ";" .. fsw .. ",1;ok;Continue]"
end

local function sendmotd(name)
	local news=""
	if name =="singleplayer" then
		news="You might have no time to read depending on where you spawn. Collect some gravel or sand, build yourself a quick shelter, then read the HELP tab of your inventory.\n\n"
	elseif not minetest.check_player_privs(name, "interact") then
		news="You are in GUEST MODE. You may not interact with the world until you gain reputation points (RPs). Try to chat with players, they may accept to give you some.\n\n"
	end
	news=news..
	"= Minefall: Psychopathy In Red =\n\n" ..

	"\nANNOUNCEMENTS:\n\n"..
	"- New: Blast wand\n"..
	"- Change: Diver talent get 2x net durability\n"..
	"- Change: Anvil is protected and clan-restricted\n"..
        "- Change: mushroom spread algorithm (more predictable)\n"..
	"- Change: Cleaner aggregate texture\n"..
	"- Change: Bcard no longer obtainable (but still works\n"..
	"- Change: summon an NPC by feeding a green mese shard to a beacon\n"..
	"- Change: Yellow wasp HP nerf\n"..
	"- Change: No more sapling crafting, except for cactus (recipe changed)\n".. 
	"- Change: Savanna's ground is no longer flammable\n"..
	"- Change: Ice wand's ice cube removes melding blocks\n"..
	"- Fix: crash when an explosion hits a tree\n"..
        "- Various minor fixes\n"..
	"\n\nYou can recall this screen with the /news command.\n"
	minetest.show_formspec(
	name,
	"mf",
	fspref..minetest.formspec_escape(news)..fssuff
	)
end
minetest.register_chatcommand("news", { func = function(name) sendmotd(name) end})


minetest.register_on_newplayer(function(player)
	local name=player:get_player_name()
	sendmotd(name)
	local inv=player:get_inventory()
	if name=="singleplayer" then
		inv:add_item("main", "craftguide:book")
		inv:add_item("main", "mob_bee:sprinkles 27")
		rp.award(name, 30)
	end
	minetest.chat_send_all(minetest.colorize("orange", "Welcome to "..name.." !"))
	end)

minetest.register_on_joinplayer(function(player)
	local playerName = player:get_player_name()

	mfplayers[playerName] = {max_energy=MAX_ENERGY, energy=0, drain=2, regen=1, invisible=false, shielded=true}
	local talent=talents:get_string(playerName)
	mfplayers[playerName].talent=talents:get_string(playerName)
	hb.init_hudbar(player, "energy")
	-- we do want players to use compass and waypoints instead of unusable 3D coordinates.
	player:hud_set_flags {basic_debug=false}
	player:set_moon {scale=4}

	-- hide nametag
	local c=player:get_nametag_attributes().color
	c.a=0
	player:set_nametag_attributes {color=c}
	-- show name when pointing and allow zoom
	player:set_properties { infotext=playerName }
	player:set_lighting { shadows={intensity=0.1 } }
	local phy=player:get_physics_override()
	phy.sneak_glitch=true
	player:set_physics_override(phy)

	givetip(playerName)
	if not (minetest.get_player_privs(playerName).interact == true)  then
		sendmotd(playerName)
	end
end)

minetest.register_on_leaveplayer(function(player)
	local playerName = player:get_player_name()
	mfplayers[playerName] = nil

end)


minetest.register_abm {
	label="Unified fire/lava cooling",
		nodenames={"fire:basic_flame", "default:lava_source", "default:lava_flowing"},
		neighbors={"group:cools_lava"},
		interval=5,
		chance=1,
		catch_up=false,
		action=function(pos, node, active_object_count, active_object_count_wider)
			local cooler=minetest.find_node_near(pos, 1, {"group:cools_lava"})
			if not cooler then return end
			minetest.remove_node(cooler)
			if node.name=="fire:basic_flame" then
				minetest.remove_node(pos)
			else
				local blocks={"default:obsidian_glass","default:obsidian"}
				minetest.set_node(pos, {name=blocks[random(1, #blocks)]})
			end

			minetest.sound_play("default_cool_lava", {pos=pos, max_hear_distance=16, gain=0.20})
			end
}

-- Water sports
minetest.register_abm {
	label="Convert flowing sea water into sea water sources",
	nodenames={"default:water_flowing"},
	interval=7,
	chance=1,
	catch_up=false,
	max_y=10, -- sea level can raise.
	action=function(pos, node, active_object_count, active_object_count_wider)
		local u={x=pos.x, y=pos.y-1, z=pos.z}
		local n=minetest.get_node(u).name
		local d=minetest.registered_nodes[n]
		if d and (d.walkable~=false or n=="default:water_source") then minetest.set_node(pos, {name="default:water_source"}) end
	end }

local function node_explode(pos)
	minetest.remove_node(pos)
	minetest.after(math.random()/2, function(pos) mobs:explosion(pos, 3) end, pos)
end


--[[
minetest.register_craft{
	output="default:diamond",
	type="shapeless",
	recipe= {"default:coalblock","default:mese_crystal","default:coalblock"}
}
]]

-- ice melts outside of freezing biomes

minetest.override_item("default:ice",
{
	on_timer=minetest.remove_node,
	on_construct=function(pos)
		if minetest.get_heat(pos)>35 then
			minetest.get_node_timer(pos):start(random(600, 900))
		end
	end
})

--[[
minetest.register_craft {
	type="cooking",
	recipe="group:tree",
	output="default:coal_lump",
	cooktime=90,
}
]]

-- Floods destroy foliage, in order to get consistent landscapes in particular in
-- cold swamps.

for node, _ in pairs(minetest.registered_nodes) do
	if minetest.get_item_group(node, "leafdecay_drop")>0 then
		minetest.override_item(node, { floodable=true })
	end
end

sfinv.register_page("help", {
	title="HELP",
	get= function(self, player, context)
		local credits="textarea[0.1,0;8,10;;;"..
			minetest.formspec_escape(
			"\nStarting (singleplayer, assuming you used the seed 12341234):\n\n"..
			"- Look for loot boxes (see inventory tab) in ruins and dungeons (there are ruins east and west to the beacon). Dig them until you get at least one crafting table and 3 bronze ingots\n"..
			"- Small spiders might get in the way; although you could beat them with bare hands, it's however best to lose them and go inspect another ruin.\n"..
			"- Collect all the food you see on your way, and red mushrooms as well\n"..
			"- Once you have those items, dig a couple of bushes and make a pick. Spend the extra bronze in a sword\n"..
			"- From there you can mine for more metal; also get a good amount of coal (at least 9, as a coal block burns a bit longer)\n"..
			"- Make an axe to be able to chop down trees (coal is best used to make diamonds), and go hunting mobs for seeds (see FAQ tab) and start a farm; farming will let you get RPs and level up.\n"..

			"\nStarting (multiplayer):\n\n"..
			"- Don't be too eager to play, enjoy your guest status a little. You cannot interact with the world, but the world does not interact with you either: mobs will ignore you. Look around, watch other players, or talk with them. Minefall is so awesome that doing just that is already fun ;-).\n"..
			"- Ask in the chat for an invitation when you feel ready (be a little patient, players might be busy fighting). There might be some questions. Not because we pretend to be 'serious gamers', but because inviting someone costs resources. Minefall is not for everyone, so we just want to make sure you are likely to enjoy the game before 'investing'.\n"..
			"- 'Resurrecting' a player costs resources as well, so don't take unecessary risks and do your best to stay alive. Keep yourself at full HP, keep your food stack high, make sure you can run away.\n"..
			"- There's no tutorial. Read the rest of this file at least once, then ask questions in the chat and listen carefully to what other players tell you.\n"..

			"\n\nMain differences from default Minetest gameplay:\n\n"..
			"- You need a crafting table.\n"..
			"- A crafting guide sign should be available near the crafting table at the main spawning point in multiplayer (later on you will receive your own crafting book). Singleplayer gets a unique crafting book (don't lose it!).\n"..
			"- Trees must be cut down from top with an axe.\n"..
			"- No sticks: use bush stems instead.\n"..
			"- You cannot build in seawater; seawater floods mostly as in real life.\n"..
			"- No hoes: right-click the dirt (not grass) with the shovel.\n"..
			"- harvesting gives back less seeds than what you sow. Seeds are obtained from mobs.\n"..
			"- Dirt, snow and gravel fall.\n"..
			"- Days are longer, plants take a lot more time to grow.\n"..
			"- Fruits regrow a limited number of times.\n"..
			"- It take a lot more time (and fuel) to melt things in the furnace.\n"..
			"- bookshelves do not allow storing book; they are furniture\n"..
			"- Some blocks can only be removed with obsidian glass shards. Obsidian glass is obtained by cooling lava, which can be found in basalt (dark stone, permafrost biome).\n"..


			"\nLevels:\n\n"..
			"- Guest: cannot do anything and mobs ignore you. A player must give them at least 1 RP in order to actually play.\n"..
			"- Beginner: keeps their inventory on death. Cannot use armor and some wands. Level up by choosing a Focus (see /focus).\n"..
			"- Regular: Inventory is stored into 'bones' on death. Can use armor and focus wand. Level up by choosing a Talent (see /talent).\n"..
			"- Advanced: Can use Abyss portals. Inventory drops on the floor on death.\n"..

			"\nProtection:\n\n"..
			"Protective blocks protect themselves and their neighbors against digging (by others), fire and blasts. Protective blocks are mainly blocks crafted using a key or a significant amount of metal. Look for 'protection' in the tooltips of the crafting guide.\n"..

			"\nArmor bonus:\n\n"..
			"- Helmet: mana regeneration\n"..
			"- Chestplate: mana pool\n"..
			"- Leggings: jump height\n"..
			"- Boots: walk speed\n\n"..
			"Damage: there is a chance that the armor absorbs all of the incoming damage but 1HP. In this case, all armor elements take damage. Each armor element you wear adds 20% chance.\n"..
			"All armor elements have a weight, which reduces jump height and walk speed (leggings and boots bonus compensate more than their own weight).\n"..

			"\n\nRP System:\n\n"..
			"- You lose RPs if you die\n"..
			"- Losing all your RPs reverts you to guest status; you don't lose your level, just the 'interact' privilege. Singleplayer cannot lose 'interact', but won't be able to dig loot boxes\n"..
			"- -1 RP for digging a loot boxes, +1 RP for placing one.\n"..
			"- You can give/check RPs with the /rep command\n"..

			"\n\nNPC traders:\n\n"..
			"    Mese block -> Beacon\n"..
			"    Mese crystal -> trader's business card (see beacon block)\n"..
			"    Red Mese Crystal -> random uncraftable superior armor\n"..
			"    Sandwich or candy apple -> loot box\n"..
                        "    Orange Mese -> Scroll of Return\n"..
			"Traders spawn on any cloth block near a shop, bookshelf, void chest or cabinet, under mild lighting.\n"..

			"\n\nKeys\n\n"..
			"    Make a skeleton key\n"..
			"    Hit a metal doortrap to make a key for it\n"..
			"    Or hit a lock container to make a key for it\n"..
			"You can give those keys to others so they can use it on the matching door/chest etc.\n"..
			
			"\n\nBeacons (red):\n\n"..
			"    - Feed it a green mese crystal to set it as home beacon\n"..
			"    - Feed it a diamond to teleport back to home\n"..
			"In both cases, the item is consumed. 'Traveler' talent lets you use a mese crystal fragment instead of a diamond\n"..

			"\n\nDungeon Beacons (\"D-eacons\"):\n\n"..
			"    - Inactive D-eacons are found in dungeons. Click then with a green mese crystal to retrieve them.\n"..
			"    - Place your D-eacon somewhere else. If you feed it a diamond, you will be teleported to the location where the inactive D-eacon was.\n"..
			"    - You can label an D-eacon by hitting a sign with it (the label will be the text of the sign). You can also label keys that way.\n"..
			" 'Traveler' talent also applies.\n"..

			"\n\nClans\n\n"..
			"- Players belong either to the Men or Women clan, according to their skin (see /skin)"..
			"- Players of one clan cannot use beacons, D-eacons or Void Chests of the other clan."..
			""
			).. "]"
		return sfinv.make_formspec(player, context, credits, false, nil)
		end
	})

sfinv.register_page("faq", {
	title="FAQ",
	get= function(self, player, context)
		local credits="textarea[0.1,0;8,10;;;"..
			minetest.formspec_escape(
			"\nHOW DO I GET ...?\n"..
			"- Crafting tables: from loot boxes in dungeons and ruins\n"..
			"- Cotton seeds: dropped by scorpions (aka manticores). They can be found in dirt desert, savanna, and jungle biomes\n"..
			"- Wheat seeds: dropped by giant beetles. They can be found in aspen forests and pine forests\n"..
			"- Yellow Mese: dropped by all hostile mobs (chance depend on size)\n"..
			"- Green Mese: dropped by the green wasp\n"..
			"- Grey Mese: dropped by the beach crab\n"..
			"- blue Mese: dropped by the ice spider (snowy biomes)\n"..
			"- red Mese: dropped by the red wasp (dangerous)\n"..
			"- orange Mese: dropped by abyss spider (abyss biome)\n"..
			"- loot boxes: trade with travelers (see HELP)\n"..
			"- RPs: by placing loot boxes\n"..

			"\nHOW DEEP SHOULD I DIG TO GET ...?\n"..
			"You don't have to dig deep, as ores are present at all levels, in all rocks except for limestone. Ore blocks all drop a random ore, but of course gold is rarer than copper.\n"..
			"For Mese, see above.\n"..

			"\nWHY CAN'T I DIG RUIN WALLS ?\n"..
			"To dig those blocks, you will need an obsidian shard. Obsidian shards are obtained by digging obsidian glass which is the product of lava cooling. Lava can be found below surface in basalt rock (dark stone).\n"..
			"Actually, obsidian glass allows you to pick up most block as they are.\n"..

			"\nWHAT CAN I DO WITH THE LOOT BOXES I GET FROM TRADERS ?\n"..
			"Three options:\n"..
			"- Bury them somewhere;\n"..
			"- Refill ruins and dungeons (so that new players won't have to go far to find them);\n"..
			"- Place and open them with a mese crystal fragment. This way you get the RP and the item.\n"..
			"\nWHAT DOES THE 'SCROLL OF RETURN' ACTUALLY DO ?\n"..
			"The Scroll of Return teleports you to your secondary waypoint (that you can set by feed a compass to a beacon), and sets your secondary waypoint to your previous location. In other words, it acts as a 'savepoint' for your current location. Can be obtained by trading an orange mese fragment. Item is single-use.\n"..

			"\nWHAT IS 'THE MELDING' ?\n"..
			"The melding are purple blocks that appear sometimes. They are not directly lethal.\n"..
			"The melding expands slowly over time; left alone, it can become a serious problem.\n"..
			"The only way to remove melding is to have traders around. A Trader grants players within 100m (a bit less than the minimap's range) the passive ability to remove melding next to them.\n One trader grants this ability to one player at a time; they chose randomly. It can take up to 30s before they notice a player is near melding.\n"..
			""
			).. "]"
		return sfinv.make_formspec(player, context, credits, false, nil)
		end
	})

sfinv.register_page("portals", {
	title="Portals",
	get= function(self, player, context)
		local content="image[2,0.1;2,6;nether_book_diagram_traditional.png]textarea[0.1,6;8,10;;;"..
			minetest.formspec_escape([["I've found this old document... Looked like the picture of some sort of portal. On the back it said 'obsidian', which was quite helpful. The only thing I had to figure out was, how to activate it? After countless experiments, and not until I reached an +Advanced+ level, I found it out: a shard of red Mese, no less. These portals lead to a strange world deep underground. Hopefully the first step on my way back home..."]])
			.."]"
		return sfinv.make_formspec(player, context, content, false, nil)
	end
})

sfinv.register_page("credits", {
	title="Credits",
	get= function(self, player, context)
		local credits="textarea[0.1,0;8,10;;;"..
			minetest.formspec_escape(
			"Minefall by Astrobe, 2022\n"..
			"\nSPECIAL THANKS\n"..
			"D00med for his wonderful and lightweight mobs\n"..
			"TenPlus1 for his many mods\n".. 
			"The Farlands team for their inspirational Minetest game\n"..
			"Red5 Studio for Firefall, which this game tries to replace.\n"..
			"\nTHANKS\n"..
			"The Minetest and MTG team\n"..
			"The minetest modding community for their many mods\n"
			).."]"
		return sfinv.make_formspec(player, context, credits, false, nil)
		end
	})

minetest.register_chatcommand("talent", 
{
	description="Select a talent",
	params="<talent name>",
	func = function(name, param)
		local player=minetest.get_player_by_name(name)
		if not player then return end
		local talent=mfplayers[name].talent
		if talent == "" then talent= nil end
		local bmode=bones.get_mode_for(player)
		if param=="" then
			minetest.chat_send_player(name, "Choosing (or changing) your talent costs 30 RP. You will also be promoted to Advanced player. The available talents are:")
			minetest.chat_send_player(name, "- traveler: beacon teleportation requires a yellow (instead of grey) mese crystal fragment.")
			minetest.chat_send_player(name, "- diver: no drowing, 2x net durability.")
			minetest.chat_send_player(name, "- flyer: levitation mana const divided by 2.")
			if talent then
				minetest.chat_send_player(name,"Your current talent is: "..
				({keymaster="traveler", diver="diver", flyer="flyer"})[talent])
			end
			return true
		end
		if bmode=="keep" then
			minetest.chat_send_player(name, "You need to level up to Regular player first")
			return true
		end 
		-- Due to various name changes, we have to transpose. Yes, it's a mess.
		local realTalent=({traveler="keymaster", diver="diver", flyer="flyer" })[param]
		if not realTalent then
			minetest.chat_send_player(name, "This is not the name of a talent")
			return true
		end
		if realTalent==mfplayers[name].talent then
			minetest.chat_send_player(name, "This is already your talent.")
			return true
		end
		if rp.get_player_count(name) <= 30 then
			minetest.chat_send_player(name, "You don't have enough RPs")
			return true
		else
			rp.award(name, -30) 
		end
		talents:set_string(name, realTalent)
		if bmode ~= "drop" then
			 minetest.chat_send_all(minetest.colorize("green", name.." became a Advanced player!"))
			 bones.set_mode_for(player, "drop")	
			end
		mfplayers[name].talent=realTalent
		minetest.chat_send_player(name, "You have now the '"..param.."' talent")
		return true	
	end
})

--[[
minetest.register_chatcommand("h",
{
	description="test",
	params="",
	func=function(name, param)
		local player=minetest.get_player_by_name(name)
		if not player then return end
		local p=vector.round(player:get_pos())
		minetest.chat_send_player(name, "pos = "..minetest.serialize(p))
		local h=minetest.hash_node_position(p)
		minetest.chat_send_player(name, "hash/dehash = ".. minetest.serialize(minetest.get_position_from_hash(h)))
		return true
	end
})
--]]

-- This randomly rotates dirt-like nodes, so that if players take a path frequently,
-- it will show in a more-or-less subtle way.
local disturbable={
	["default:dirt_with_grass"]=true,
	["default:dirt_with_dry_grass"]=true,
	["default:dirt_with_coniferous_litter"]=true,
	["default:dirt_with_snow"]=true,
	["default:gravel"]=true,
	["default:dirt"]=true,
	["default:dry_dirt"]=true,
	["default:dry_dirt_with_stones"]=true,
	["default:snowblock"]=true,
	["default:sand"]=true,
	["default:desert_sand"]=true,
	-- won't disturb permafrost because stone-like.
}


local acc=0
minetest.register_globalstep(function(dtime)
	acc=acc+dtime
	if acc >= random(3,10) then
		acc=0
		for _, player in ipairs(minetest.get_connected_players()) do
			local pos=player:get_pos()
			pos.y=pos.y-0.5
			local node=minetest.get_node(pos)
			-- I don't think we have to check for protection for that. This
			-- won't even make a falling node fall.
			if node and disturbable[node.name] and (node.param2 or 0) == 0 then
				node.param2=random(1,23)
				minetest.set_node(pos, node)
				minetest.check_for_falling(pos)
			end
		end
	end
end)


-- ALCHEMY
-- Not sure about that. Maybe it is a too good mese sink,
-- maybe it removes the incentive to to more dangerous places 
-- to mine better metals.
--[[
minetest.register_craft {
	output = 'default:tin_lump',
	type="shapeless",
	recipe = {"default:mese_crystal", "default:copper_ingot" }
} 
minetest.register_craft {
	output = 'default:iron_lump',
	type="shapeless",
	recipe = {"default:mese_crystal", "default:tin_ingot" }
} 
minetest.register_craft {
	output = 'default:gold_lump',
	type="shapeless",
	recipe = {"default:mese_crystal", "default:steel_ingot" }
} 
]]

minetest.override_item("default:stone_with_coal", { on_blast=node_explode, on_burn=node_explode })

minetest.register_on_prejoinplayer(function(name, ip)
	if string.find(name, "[^%a-]") then
		minetest.log("Rejecting name: ["..name.."]")
		return "names can only contain letters."
		 end
	end)

minetest.set_mapgen_params
{
	mgname="v7",
	flags="dungeons,caves",
}

minetest.register_on_mapgen_init(function(mgp)
	for k,v in pairs{
		mgv7_spflags="mountains,noridges,nofloatlands,nocaverns",
	} do minetest.set_mapgen_setting(k, v, true) end end)
