code:
--changed bathroom_faucet to bath_faucet and added craft
minetest.register_craft({
	output = 'ma_pops_furniture:bath_faucet',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','','mesecraft_bucket:bucket_water',},
	{'default:steel_ingot','','',},
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:toilet_paper_roll_dispenser',
	recipe = {
	{'default:stone','default:stone','default:stone',},
	{'default:paper','default:water_source','default:paper',},
	{'','default:paper','',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:toilet_close',
	recipe = {
	{'','','default:steel_ingot',},
	{'default:steel_ingot','stairs:slab_wood','default:steel_ingot',},
	{'default:steel_ingot','mesecraft_bucket:bucket_water','default:steel_ingot',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:br_sink',
	recipe = {
	{'default:steel_ingot','','default:steel_ingot',},
	{'','default:steel_ingot','',},
	{'','default:steel_ingot','',},
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:mirror_closed',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:glass','default:glass','default:glass',},
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:shower_base',
	recipe = {
	{'','','',},
	{'','','',},
	{'default:steel_ingot','mesecraft_bucket:bucket_empty','default:steel_ingot',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:shower_top',
	recipe = {
	{'','default:steel_ingot','',},
	{'default:steel_ingot','mesecraft_bucket:bucket_water','default:steel_ingot',},
	{'default:steel_ingot','','default:steel_ingot',},
	}
})

--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:dw',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','mesecraft_bucket:bucket_water','default:steel_ingot',},
	{'default:steel_ingot','default:mese_crystal','default:steel_ingot',},
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:oven',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','default:furnace','default:steel_ingot',},
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:oven_overhead',
	recipe = {
	{'default:steel_ingot','default:mese_crystal_fragment','default:steel_ingot',},
	{'','','',},
	{'','','',},
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:microwave',
	recipe = {
	{'','','',},
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','default:furnace','default:steel_ingot',},
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:coffee_maker',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','default:copper_ingot','default:steel_ingot',},
	{'','default:glass','',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:toaster',
	recipe = {
	{'','','',},
	{'default:steel_ingot','default:mese_crystal','default:steel_ingot',},
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:kitchen_faucet',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','','default:steel_ingot',},
	{'default:steel_ingot','','',},
	}
})

--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:fridge',
	recipe = {
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	{'default:steel_ingot','default:snow','default:steel_ingot',},
	{'default:steel_ingot','default:steel_ingot','default:steel_ingot',},
	}
})
--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:freezer',
	recipe = {
	{'default:steel_ingot','default:mese_crystal','default:steel_ingot',},
	{'default:steel_ingot','default:ice','default:steel_ingot',},
	{'default:steel_ingot','default:mese_crystal','default:steel_ingot',},
	}
})

local chair2_table = { --color
{'black'},
{'blue'},
{'brown'},
{'cyan'},
{'dark_green'},
{'dark_grey'},
{'green'},
{'grey'},
{'magenta'},
{'orange'},
{'pink'},
{'red'},
{'violet'},
{'yellow'},
}

for i in ipairs (chair2_table) do
	local color = chair2_table[i][1]

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_'..color,
	recipe = {
	{'wool:'..color, 'wool:'..color, 'wool:'..color, },
	{'wool:'..color, 'wool:'..color, 'wool:'..color, },
	{'group:wood', '', 'group:wood', },
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_'..color,
	recipe = {
	{'ma_pops_furniture:chair2_white', 'dye:'..color}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_white',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:white'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_black',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:black'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_blue',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:blue'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_brown',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:brown'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_cyan',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:cyan'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_dark_grey',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:dark_grey'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_grey',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:grey'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_green',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:green'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_magenta',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:magenta'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_orange',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:orange'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_pink',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:pink'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_red',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:red'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_violet',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:violet'}
	}
})

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_yellow',
	recipe = {
	{'ma_pops_furniture:chair2_'..color, 'dye:yellow'}
	}
})
end

minetest.register_craft({
	output = 'ma_pops_furniture:chair2_white',
	recipe = {
	{'wool:white', 'wool:white', 'wool:white', },
	{'wool:white', 'wool:white', 'wool:white', },
	{'group:wood', '', 'group:wood', },
	}
})

--added craft
minetest.register_craft({
	output = 'ma_pops_furniture:birdbath',
	recipe = {
	{'','','',},
	{'default:steel_ingot','mesecraft_bucket:bucket_water','default:steel_ingot',},
	{'','default:steel_ingot','',},
	}
})


code:
ma_pops_furniture.fireplace_formspec =
	'size[8,6]'..
	default.gui_bg..
	default.gui_bg_img..
	default.gui_slots..
	'background[8,6;0,0;default_brick.png;true]'..
	'list[current_name;fuel;1,0;1,1;]'..
	'list[current_player;main;0,2.5;8,4;]'
	default.get_hotbar_bg(0,4.85)

repo_name: korkut/MeseCraft

license: mit


code:
--
-- Freezer for mintest: a device which turns water (in buckets) into ice
-- And does a couple of other tricks, discovering which is left as a pleasant
-- surprise for the player.
--

-- enable extra popsicle types provided there are both vessels and fruits/veggies available
-- fruit + glass -> juice; juice @ freezer -> popsicle + empty glass

--
-- Formspecs
--

local function active_formspec(fuel_percent, item_percent)
	local formspec =
		"size[8,8.5]"..
		default.gui_bg..
		default.gui_bg_img..
		default.gui_slots..
		"list[current_name;src;2.5,1;1,1;]"..
		"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
		(item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
		"list[current_name;dst;4.75,0.96;3,2;]"..
		"list[current_player;main;0,4.25;8,1;]"..
		"list[current_player;main;0,5.5;8,3;8]"..
		"listring[current_name;dst]"..
		"listring[current_player;main]"..
		"listring[current_name;src]"..
		"listring[current_player;main]"..
		default.get_hotbar_bg(0, 4.25)
	return formspec
end

local inactive_formspec =
	"size[8,8.5]"..
	default.gui_bg..
	default.gui_bg_img..
	default.gui_slots..
	"list[current_name;src;2.5,1.5;1,1;]"..
	"image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"..
	"list[current_name;dst;4.75,0.96;3,2;]"..
	"list[current_player;main;0,4.25;8,1;]"..
	"list[current_player;main;0,5.5;8,3;8]"..
	"listring[current_name;dst]"..
	"listring[current_player;main]"..
	"listring[current_name;src]"..
	"listring[current_player;main]"..
	default.get_hotbar_bg(0, 4.25)

--
-- Node callback functions that are the same for active and inactive freezer
--

local function can_dig(pos, player)
	local meta = minetest.get_meta(pos);
	local inv = meta:get_inventory()
	return inv:is_empty("dst") and inv:is_empty("src")
end

local function allow_metadata_inventory_put(pos, listname, index, stack, player)
	if minetest.is_protected(pos, player:get_player_name()) then
		return 0
	end
	local meta = minetest.get_meta(pos)
	local inv = meta:get_inventory()
	if listname == "src" then
		return stack:get_count()
	elseif listname == "dst" then
		return 0
	end
end

local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
	local meta = minetest.get_meta(pos)
	local inv = meta:get_inventory()
	local stack = inv:get_stack(from_list, from_index)
	return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end

local function allow_metadata_inventory_take(pos, listname, index, stack, player)
	if minetest.is_protected(pos, player:get_player_name()) then
		return 0
	end
	return stack:get_count()
end

local function swap_node(pos, name)
	local node = minetest.get_node(pos)
	if node.name == name then
		return
	end
	node.name = name
	minetest.swap_node(pos, node)
end

local function freezer_node_timer(pos, elapsed)
	--
	-- Inizialize metadata
	--
	local meta = minetest.get_meta(pos)

	local src_time = meta:get_float("src_time") or 0

	local inv = meta:get_inventory()
	local srclist = inv:get_list("src")

	local dstlist = inv:get_list("dst")

	--
	-- Cooking
	--

	-- takes both regular and river water
	if inv:contains_item("src", "mesecraft_bucket:bucket_water") or
	      inv:contains_item("src", "mesecraft_bucket:bucket_river_water") then
		if inv:room_for_item("dst", "default:ice") then
			inv:remove_item("src", "mesecraft_bucket:bucket_water")
			inv:remove_item("src", "mesecraft_bucket:bucket_river_water")
			inv:add_item("dst", "default:ice")
			inv:add_item("dst", "mesecraft_bucket:bucket_empty")
	      end
	end

	-- Check if we have cookable content
	return
end

--
-- Node definitions
--

minetest.register_node("ma_pops_furniture:freezer", {
	description = "Freezer",
	tiles = {
		"mp_froz_top.png",
		"mp_froz_bottom.png",
		"mp_froz_right.png",
		"mp_froz_left.png",
		"mp_froz_back.png",
		"mp_froz_front.png"
	},
	paramtype2 = "facedir",
	groups = {cracky = 2, tubedevice = 1, tubedevice_receiver = 1},
	legacy_facedir_simple = true,
	is_ground_content = false,
	sounds = default.node_sound_stone_defaults(),
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5}, -- NodeBox1
			{-0.5, -0.4375, -0.375, 0.4375, 0.5, -0.3125}, -- NodeBox2
			{0.3125, -0.25, -0.5, 0.375, 0.25, -0.4375}, -- NodeBox6
			{0.3125, -0.25, -0.4375, 0.375, -0.1875, -0.375}, -- NodeBox7
			{0.3125, 0.1875, -0.4375, 0.375, 0.25, -0.375}, -- NodeBox8
		}
	},
	tube = (function() if minetest.get_modpath("pipeworks") then return {
		-- using a different stack from defaut when inserting
		insert_object = function(pos, node, stack, direction)
			local meta = minetest.get_meta(pos)
			local inv = meta:get_inventory()
			local timer = minetest.get_node_timer(pos)
			if not timer:is_started() then
				timer:start(1.0)
			end
			return inv:add_item("src", stack)
		end,
		can_insert = function(pos,node,stack,direction)
			local meta = minetest.get_meta(pos)
			local inv = meta:get_inventory()
			return inv:room_for_item("src", stack)
		end,
		-- the default stack, from which objects will be taken
		input_inventory = "dst",
		connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
	} end end)(),

	can_dig = can_dig,

	on_timer = freezer_node_timer,

	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		meta:set_string("formspec", inactive_formspec)
		local inv = meta:get_inventory()
		inv:set_size('src', 1)
		inv:set_size('dst', 6)
	end,

	on_metadata_inventory_move = function(pos)
		local timer = minetest.get_node_timer(pos)
		timer:start(1.0)
	end,
	on_metadata_inventory_put = function(pos)
		-- start timer function, it will sort out whether freezer will work or not.
		local timer = minetest.get_node_timer(pos)
		timer:start(1.0)
	end,
	on_blast = function(pos)
		local drops = {}
		default.get_inventory_drops(pos, "src", drops)
		default.get_inventory_drops(pos, "dst", drops)
		drops[#drops+1] = "ma_pops_furniture:freezer"
		minetest.remove_node(pos)
		return drops
	end,

	allow_metadata_inventory_put = allow_metadata_inventory_put,
	allow_metadata_inventory_move = allow_metadata_inventory_move,
	allow_metadata_inventory_take = allow_metadata_inventory_take,
})

minetest.register_craft({
      output = "default:snowblock 3",
      type = "shapeless",
      recipe = {
	 "default:ice"
      }
})


code:
function ma_pops_furniture.sit(pos, node, clicker)
	local meta = minetest.get_meta(pos)
	local param2 = node.param2
	local name = clicker:get_player_name()

	if name == meta:get_string("is_sit") then
		print 'player should be standing.'
		meta:set_string("is_sit", "")
		pos.y = pos.y-0.5
		clicker:setpos(pos)
		clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
		clicker:set_physics_override(1, 1, 1)
		default.player_attached[name] = false
		default.player_set_animation(clicker, "stand", 30)
	else
		meta:set_string("is_sit", clicker:get_player_name())
		print 'player should be sitting.'
		clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
		clicker:set_physics_override(0, 0, 0)
		clicker:setpos(pos)
		default.player_attached[name] = true
		default.player_set_animation(clicker, "sit", 30)
		if param2 == 0 then
			clicker:set_look_yaw(3.15)
		elseif param2 == 1 then
			clicker:set_look_yaw(7.9)
		elseif param2 == 2 then
			clicker:set_look_yaw(6.28)
		elseif param2 == 3 then
			clicker:set_look_yaw(4.75)
		else return end
	end
end

ma_pops_furniture.window_operate = function( pos, old_node_state_name, new_node_state_name )

   local offsets   = {-1,1,-2,2,-3,3};
   local stop_up   = 0;
   local stop_down = 0;

   for i,v in ipairs(offsets) do

      local node = minetest.env:get_node_or_nil( {x=pos.x, y=(pos.y+v), z=pos.z } );
      if( node and node.name and node.name==old_node_state_name
        and ( (v > 0 and stop_up   == 0 )
           or (v < 0 and stop_down == 0 ))) then

         minetest.env:add_node({x=pos.x, y=(pos.y+v), z=pos.z }, {name = new_node_state_name, param2 = node.param2})

      -- found a diffrent node - no need to search further up
      elseif( v > 0 and stop_up   == 0 ) then
         stop_up   = 1;

      elseif( v < 0 and stop_down == 0 ) then
         stop_down = 1;
      end
   end
end


code:
ma_pops_furniture = {}

dofile(minetest.get_modpath('ma_pops_furniture')..'/sit.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/functions.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/formspecs.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/crafts.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/nodes.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/freezer.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/microwave.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/oven.lua')

--GreenDimond's code from waffle mod
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")

ma_pops_furniture.intllib = S
dofile(minetest.get_modpath('ma_pops_furniture')..'/toaster.lua')
dofile(minetest.get_modpath('ma_pops_furniture')..'/intllib.lua')

minetest.register_alias("furniture_mod:toilet_closed", "ma_pops_furniture:toilet_closed")
minetest.register_alias("furniture_mod:toilet_open", "ma_pops_furniture:toilet_open")
minetest.register_alias("furniture_mod:tv", "ma_pops_furniture:tv")
minetest.register_alias("furniture_mod:lamp", "ma_pops_furniture:lamp")
minetest.register_alias("furniture_mod:lamp_off", "ma_pops_furniture:lamp_off")
minetest.register_alias("furniture_mod:ceiling_light", "ma_pops_furniture:ceiling_lamp")
minetest.register_alias("furniture_mod:ceiling_light_off", "ma_pops_furniture:ceiling_lamp_off")


code:
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.

-- Get the latest version of this file at:
--   https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua

local function format(str, ...)
	local args = { ... }
	local function repl(escape, open, num, close)
		if escape == "" then
			local replacement = tostring(args[tonumber(num)])
			if open == "" then
				replacement = replacement..close
			end
			return replacement
		else
			return "@"..open..num..close
		end
	end
	return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end

local gettext, ngettext
if minetest.get_modpath("intllib") then
	if intllib.make_gettext_pair then
		-- New method using gettext.
		gettext, ngettext = intllib.make_gettext_pair()
	else
		-- Old method using text files.
		gettext = intllib.Getter()
	end
end

-- Fill in missing functions.

gettext = gettext or function(msgid, ...)
	return format(msgid, ...)
end

ngettext = ngettext or function(msgid, msgid_plural, n, ...)
	return format(n==1 and msgid or msgid_plural, ...)
end

return gettext, ngettext


code:
--microwave code by Wizzerine
--item_percent code by Noodlemire

local microwave_fs =
	"size[8,7]"
	.."button[6.5,1.5;1.5,2;btn_start;START]"
    .."image[6.5,.2;1.5,.5;mp_mw_bar.png^[transformR270]"
	.."list[current_player;main;0,3;8,1;]"
    .."list[current_player;main;0,4.25;8,3;8]"
	.."list[context;cook_slot;3.5,1.25;1,1;]"
	.."label[3,0.5;Microwave]"
 -- possibly add "fire" image?

local function get_active_microwave_fs(item_percent)
    return "size[8,7]"
	    .."button[6.5,1.5;1.5,2;button_start;START]"
	    .."image[6.5,.2;1.5,.5;mp_mw_bar.png^[lowpart:"
	    ..(item_percent)..":mp_mw_bar_on.png^[transformR270]"
	    .."list[current_player;main;0,3;8,1;]"
        .."list[current_player;main;0,4.25;8,3;8]"
	    .."list[context;cook_slot;3.5,1.25;1,1;]"
        .."label[3,0.5;Microwave]"
        -- possibly add "fire" image?
end

--x,y;w,h

-- Adding recipe API so we don't end up hardcoding items
ma_pops_furniture.microwave = {}
local microwave = ma_pops_furniture.microwave
microwave.recipes = {}
function microwave.register_recipe(input, output) microwave.recipes[input] = output end

local function update_formspec(progress, goal, meta)
    local formspec

    if progress > 0 and progress <= goal then
        local item_percent = math.floor(progress / goal * 100)
        formspec = get_active_microwave_fs(item_percent)
    else
        formspec = microwave_fs
    end

    meta:set_string("formspec", formspec)
end

local function recalculate(pos)
	local meta, timer = minetest.get_meta(pos), minetest.get_node_timer(pos)
	local inv = meta:get_inventory()
	local stack = inv:get_stack("cook_slot", 1)
    local goal = 3 * stack:get_count()

	local k = microwave.recipes[stack:get_name()]
	if not k then return end

	timer:stop()
    update_formspec(0, goal, meta)
    timer:start(1)
end

local function do_cook_all(pos)
    local meta = minetest.get_meta(pos)
	local inv = meta:get_inventory()
	local stack = meta:get_inventory():get_stack("cook_slot", 1)
	local food_uncooked = inv:remove_item("cook_slot", inv:get_stack("cook_slot", 1)) -- Clear the slot
	local food_cooked = microwave.recipes[food_uncooked:get_name()] .. " " .. tostring(food_uncooked:get_count()) -- Get the cooked food
	inv:add_item("cook_slot", food_cooked) -- Put the cooked food in the slot
end

minetest.register_node("ma_pops_furniture:microwave", {
	description = "Microwave",
	tiles = {"mp_mw_top.png", "mp_mw_bottom.png", "mp_mw_right.png", "mp_mw_left.png", "mp_mw_back.png", "mp_mw_front.png"},
	paramtype2 = "facedir",
	groups = {cracky = 2}, -- currently no pipeworks compat as I don't know how it works
	sounds = default.node_sound_stone_defaults(),
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {
	    	{-0.4375, -0.4375, -0.3125, 0.4375, 0.0625, 0.3125},
			{-0.375, -0.5, -0.25, 0.375, -0.4375, 0.25},
		},
	},
	can_dig = function(pos, player)
		local meta = minetest.get_meta(pos)
		local inv = meta:get_inventory()
		return inv:is_empty("cook_slot")
	end,

	on_timer = function(pos, elapsed)
		local meta = minetest.get_meta(pos)
        local stack = meta:get_inventory():get_stack("cook_slot", 1)
        local goal = 3 * stack:get_count()
        local cooking_time = meta:get_int("cooking_time") or 0
        cooking_time = cooking_time + 1

        update_formspec(cooking_time, goal, meta)
        meta:set_int("cooking_time", cooking_time)

        --Keep cooking until there is nothing left to cook.
        if cooking_time <= goal then
            return true
        else
            do_cook_all(pos)
            meta:set_int("cooking_time", 0)
            update_formspec(0, goal, meta)
            return false
        end
	end,

	--on_metadata_inventory_put = recalculate,
	--on_metadata_inventory_take = recalculate,

	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		meta:set_string("formspec", microwave_fs)
		local inv = meta:get_inventory()
		inv:set_size("cook_slot", 1)
	end,
    on_receive_fields = function(pos, _, fields)
        if fields.quit then return end
        if fields.btn_start then
            recalculate(pos)
        end
    end,

	on_blast = function(pos)
		local drops = {}
		default.get_inventory_drops(pos, "cook_slot", drops)
		table.insert(drops, "ma_pops_furniture:microwave")
		minetest.remove_node(pos)
		return drops
	end,

	allow_metadata_inventory_put = function(pos, list, index, stack, player)
		return microwave.recipes[stack:get_name()] and stack:get_count() or 0
	end,

    --Only allow items to be taken if the microwave hasn't started yet
    allow_metadata_inventory_take = function(pos, listname, index, stack, player)
        if not minetest.get_node_timer(pos):is_started() then
            return stack:get_count()
        else
            return 0
        end
    end
})

minetest.register_craft({
	output = "ma_pops_furniture:microwave",
	recipe = {
		{"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"},
		{"default:steel_ingot", "", "default:steel_ingot"},
		{"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}
	}
})

-- Recipe Registration
microwave.register_recipe("default:ice", "default:water_source")
-- No milk bucket as this doesn't support substitutes for now
microwave.register_recipe("mobs_mc:chicken_raw", "test:chicken_cooked")
--[[ We don't need to check mod existance when registering recipe
Recipe won't even be executed if there is no raw chicken in input ]]--
microwave.register_recipe("mobs_mc:beef_raw", "test:beef_cooked")
microwave.register_recipe("farming:coffee_cup", "farming:coffee_cup_hot") -- What a crutch there was...
-- Add needed recipes as you go, note that other mods can add more recipes too


code:
name = ma_pops_furniture
author = Mihobre
description = Adds some furniture.
depends = default, fire, wool
optional_depends = ethereal, mobs_mc, farming, unifieddyes


code:
--Bathroom--
minetest.register_node("ma_pops_furniture:bath_faucet", {
   description = "Bathroom Faucet",
   tiles = {
		"mp_knob_top.png",
		"mp_knob_bottom.png",
		"mp_knob_right.png",
		"mp_knob_left.png",
		"mp_knob_back.png",
		"mp_knob_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   node_box = {
       type = "fixed",
       fixed = {
			{-0.0625, -0.5, 0.3125, 0.0625, -0.1875, 0.4375},
			{-0.0625, -0.1875, 0.125, 0.0625, -0.125, 0.4375},
			{0.125, -0.25, 0.25, 0.25, -0.0625, 0.4375},
			{-0.25, -0.25, 0.25, -0.125, -0.0625, 0.4375},
			{-0.0625, -0.25, 0.125, 0.0625, -0.125, 0.1875},
			{-0.125, -0.1875, 0.3125, 0.125, -0.125, 0.375},
       },
   }
})

minetest.register_node("ma_pops_furniture:toilet_paper_roll_dispenser", {
   description = "Toilet Paper Roll Dispenser",
   tiles = {
		"mp_tp_top.png",
		"mp_tp_bottom.png",
		"mp_tp_right.png",
		"mp_tp_left.png",
		"mp_tp_back.png",
		"mp_tp_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   node_box = {
       type = "fixed",
       fixed = {
          {-0.3125, -0.1875, 0.4375, 0.3125, 0.125, 0.5},
		  {-0.1875, -0.125, 0.25, 0.1875, 0.0625, 0.4375},
		  {-0.25, -0.0625, 0.3125, 0.25, 0, 0.5},
       },
   }
})

minetest.register_node('ma_pops_furniture:toilet_open', {
	description = 'Toilet',
	drawtype = 'mesh',
	mesh = 'FM_toilet_open.obj',
	tiles = {{name='default_coral_skeleton.png'},{name='default_wood.png'}},
	groups = {choppy=2, oddly_breakably_by_hand=2, furniture=1, not_in_creative_inventory=1},
	--inventory_image = 'fm_chair_stone.png',
	paramtype = 'light',
	paramtype2 = 'facedir',
	sounds = default.node_sound_wood_defaults(),
	selection_box = {
		type = 'fixed',
		fixed = {
			{-.35, -.5, -.35, .35, 0, .5}, -- Right, Bottom, Back, Left, Top, Front
			{-.35, 0, .2, .35, .5, .5},
			}
		},
	collision_box = {
		fixed = {
			{-.35, -.5, -.35, .35, 0, .5}, -- Right, Bottom, Back, Left, Top, Front
			{-.35, 0, .2, .35, .5, .5},
			}
		},
	on_rightclick = function(pos, node, clicker)
		ma_pops_furniture.sit(pos, node, clicker)
		end,
	on_punch = function (pos, node, puncher)
		node.name = "ma_pops_furniture:toilet_close"
		minetest.set_node(pos, node)
	end,
})

minetest.register_node('ma_pops_furniture:toilet_close', {
	description = 'Toilet',
	drawtype = 'mesh',
	mesh = 'FM_toilet_close.obj',
	tiles = {{name='default_coral_skeleton.png'},{name='default_wood.png'}},
	groups = {choppy=2, oddly_breakably_by_hand=2, furniture=1},
	paramtype = 'light',
	paramtype2 = 'facedir',
	sounds = default.node_sound_wood_defaults(),
	selection_box = {
		type = 'fixed',
		fixed = {
			{-.35, -.5, -.35, .35, 0, .5}, -- Right, Bottom, Back, Left, Top, Front
			{-.35, 0, .2, .35, .5, .5},
			}
		},
	collision_box = {
		fixed = {
			{-.35, -.5, -.35, .35, 0, .5}, -- Right, Bottom, Back, Left, Top, Front
			{-.35, 0, .2, .35, .5, .5},
			}
		},
	on_rightclick = function(pos, node, clicker)
		ma_pops_furniture.sit(pos, node, clicker)
		end,
	on_punch = function (pos, node, puncher)
		node.name = "ma_pops_furniture:toilet_open"
		minetest.set_node(pos, node)
	end,
})

minetest.register_node("ma_pops_furniture:br_sink", {
   description = "Sink (Bathroom)",
   tiles = {
		"mp_hw_top.png",
		"mp_hw_bottom.png",
		"mp_hw_right.png",
		"mp_hw_left.png",
		"mp_hw_back.png",
		"mp_hw_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   node_box = {
       type = "fixed",
       fixed = {
         {-0.4375, 0.25, -0.3125, 0.4375, 0.5, 0.5},
		 {-0.125, -0.5, 0.125, 0.125, 0.25, 0.4375},
       },
   }
})

minetest.register_node("ma_pops_furniture:mirror_closed", {
   description = "Mirror",
   tiles = {
		"mp_mirror_top.png",
		"mp_mirror_bottom.png",
		"mp_mirror_right.png",
		"mp_mirror_left.png",
		"default_wood.png",
		"mp_mirror_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   on_punch = function(pos, node, puncher)
		minetest.env:add_node(pos, {name = "ma_pops_furniture:mirror", param2 = node.param2})
		ma_pops_furniture.window_operate( pos, "ma_pops_furniture:mirror_closed", "ma_pops_furniture:mirror" );
		end,
   node_box = {
       type = "fixed",
       fixed = {
			{-0.4375, -0.375, 0.3125, 0.4375, 0.5, 0.5},
			{0, -0.375, 0.25, 0.4375, 0.5, 0.3125},
			{-0.4375, -0.375, 0.25, 2.98023e-008, 0.5, 0.3125},
       },
   }
})

minetest.register_node("ma_pops_furniture:mirror", {
   description = "Mirror (Open)",
   tiles = {
		"mp_mirror_open_top.png",
		"mp_mirror_open_bottom.png",
		"mp_mirror_open_right.png",
		"mp_mirror_open_left.png",
		"mp_mirror_front.png",
		"mp_mirror_open_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   drop = "ma_pops_furniture:mirror_closed",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, not_in_creative_inventory = 1},
   on_punch = function(pos, node, puncher)
		minetest.env:add_node(pos, {name = "ma_pops_furniture:mirror_closed", param2 = node.param2})
		ma_pops_furniture.window_operate( pos, "ma_pops_furniture:mirror", "ma_pops_furniture:mirror_closed" );
		end,
		on_construct = function(pos)
		local meta = minetest.env:get_meta(pos)
		local inv = meta:get_inventory()
		inv:set_size('main', 8*4)
		inv:set_size('storage', 4*4)
		meta:set_string('formspec',
			'size [9,10]'..
			'bgcolor[#080808BB;true]'..
			'list[current_name;storage;3,1.5;3,3;]'..
			'list[current_player;main;0.5,6.5;8,4;]')
	end,
	can_dig = function(pos,player)
		local meta = minetest.get_meta(pos);
		local inv = meta:get_inventory()
		return inv:is_empty('storage') and inv:is_empty('storage1')
	end,
   node_box = {
       type = "fixed",
       fixed = {
			{-0.4375, -0.375, 0.3125, 0.4375, 0.5, 0.5},
			{0.4375, -0.375, -0.125, 0.5, 0.5, 0.3125},
			{-0.5, -0.375, -0.125, -0.4375, 0.5, 0.3125},
       },
   }
})

minetest.register_node("ma_pops_furniture:shower_base", {
   description = "Shower Base",
   tiles = {
		"mp_showbas_top.png",
		"mp_showbas_top.png",
		"mp_showbas_sides.png",
		"mp_showbas_sides.png",
		"mp_showbas_sides.png",
		"mp_showbas_sides.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   node_box = {
       type = "fixed",
       fixed = {
          {-0.4375, -0.5, -0.4375, 0.4375, -0.4375, 0.4375},
		  {0.4375, -0.5, -0.5, 0.5, -0.3125, 0.5},
		  {-0.5, -0.5, 0.4375, 0.5, -0.3125, 0.5},
		  {-0.5, -0.5, -0.5, -0.4375, -0.3125, 0.5},
		  {-0.5, -0.5, -0.5, 0.5, -0.3125, -0.4375},
		  {-0.125, -0.5, 0.125, 0.125, -0.375, 0.375},
       }
    },
})

minetest.register_node("ma_pops_furniture:shower_top", {
   description = "Shower Head",
   tiles = {
		"mp_shk_top.png",
		"mp_shk_bottom.png",
		"mp_shk_right.png",
		"mp_shk_left.png",
		"mp_shk_back.png",
		"mp_shk_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   node_box = {
       type = "fixed",
       fixed = {
          {-0.25, -0.5, 0.4375, 0.25, 0.5, 0.5},
		  {-0.125, 0.3125, -0.1875, 0.125, 0.4375, 0.25},
		  {-0.1875, -0.25, 0.375, -0.125, -0.1875, 0.4375},
		  {0.125, -0.25, 0.375, 0.1875, -0.1875, 0.4375},
		  {-0.1875, -0.25, 0.3125, -0.125, -0.0625, 0.375},
		  {0.125, -0.25, 0.3125, 0.1875, -0.0625, 0.375},
		  {-0.0625, 0.375, 0.25, 0.0625, 0.4375, 0.4375},
        },
    }
})

--Kitchen/Dining Room--
minetest.register_node("ma_pops_furniture:dw", {
	description= "Dishwasher",
	tiles = {
		"mp_dw_top.png",
		"mp_dw_bottom.png",
		"mp_dw_left.png",
		"mp_dw_right.png",
		"mp_dw_back.png",
		"mp_dw_front.png"
	},
	drawtype = "nodebox",
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {choppy = 2, oddly_breakable_by_hand = 2, furniture = 1},
	node_box = {
		type = "fixed",
		fixed = {
			{-0.4375, -0.5, -0.4375, 0.4375, -0.4375, 0.4375},
			{-0.5, -0.4375, -0.4375, 0.5, 0.5, 0.5},
			{-0.5, 0.3125, -0.5, 0.5, 0.5, -0.4375},
			{-0.4375, -0.4375, -0.5, 0.4375, 0.25, 0.5},
		}
	}
})

minetest.register_node("ma_pops_furniture:oven_overhead", {
	description= "Oven Overhead",
	tiles = {
		"mp_camp_top.png",
		"mp_camp_bottom.png",
		"mp_camp_left.png",
		"mp_camp_right.png",
		"mp_camp_back.png",
		"mp_camp_front.png"
	},
	drawtype = "nodebox",
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {choppy = 2, oddly_breakable_by_hand = 2, furniture = 1},
	node_box = {
		type = "fixed",
		fixed = {
			{-0.4375, 0.4375, -0.4375, 0.4375, 0.5, 0.4375},
			{-0.5, 0.25, -0.5, 0.5, 0.4375, 0.5},
		}
	}
})

minetest.register_node("ma_pops_furniture:microwave", {
   description = "Microwave",
   tiles = {
		"mp_mw_top.png",
		"mp_mw_bottom.png",
		"mp_mw_right.png",
		"mp_mw_left.png",
		"mp_mw_back.png",
		"mp_mw_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, furniture = 1},
   node_box = {
       type = "fixed",
       fixed = {
           {-0.4375, -0.4375, -0.3125, 0.4375, 0.0625, 0.3125},
			{-0.375, -0.5, -0.25, 0.375, -0.4375, 0.25},
       },
   }
})

minetest.register_node("ma_pops_furniture:coffee_maker", {
	description = "Coffee Maker",
	tiles = {
		"mp_cof_top.png",
		"mp_cof_bottom.png",
		"mp_cof_right.png",
		"mp_cof_left.png",
		"mp_cof_back.png",
		"mp_cof_front.png"
	},
	drawtype = "nodebox",
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {choppy = 2, oddly_breakable_by_hand = 2, furniture = 1},
	node_box = {
		type = "fixed",
		fixed = {
			{-0.4375, -0.5, -0.0625, 0, -0.4375, 0.4375},
			{-0.4375, -0.5, 0.3125, 0, 0.1875, 0.4375},
			{-0.4375, -0.0625, 0, 0, 0.25, 0.4375},
			{-0.375, -0.4375, 0, -0.0625, -0.125, 0.25},
			{-0.25, -0.375, -0.125, -0.1875, -0.1875, 0.0625},
		}
	}
})

minetest.register_node("ma_pops_furniture:toaster", {
   description = "Toaster",
   tiles = {
		"mp_toas_top.png",
		"mp_toas_bottom.png",
		"mp_toas_right.png",
		"mp_toas_left.png",
		"mp_toas_back.png",
		"mp_toas_front.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, furniture = 1},
   node_box = {
       type = "fixed",
       fixed = {
           {-0.375, -0.5, 0, 0.375, -0.0625, 0.3125},
		   {-0.4375, -0.1875, 0.0625, -0.375, -0.125, 0.25},
       },
   }
})

minetest.register_node("ma_pops_furniture:kitchen_faucet", {
   description = "Kitchen Faucet",
   tiles = {
		"mp_grif_top.png",
		"mp_grif_sides.png",
		"mp_grif_sides.png",
		"mp_grif_sides.png",
		"mp_grif_sides.png",
		"mp_grif_sides.png"
	},
   drawtype = "nodebox",
   paramtype = "light",
   paramtype2 = "facedir",
   groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
   node_box = {
       type = "fixed",
       fixed = {
			{-0.0625, -0.5, 0.375, 0.0625, -0.1875, 0.4375},
			{-0.0625, -0.1875, 0.0625, 0.0625, -0.125, 0.4375},
			{-0.0625, -0.25, 0.0625, 0.0625, -0.1875, 0.125},
			{0.125, -0.5, 0.3125, 0.25, -0.375, 0.4375},
			{-0.25, -0.5, 0.3125, -0.125, -0.375, 0.4375},
       },
   }
})

minetest.register_node("ma_pops_furniture:fridge", {
	description= "Fridge",
	tiles = {
		"mp_fridge_top.png",
		"mp_fridge_bottom.png",
		"mp_fridge_right.png",
		"mp_fridge_left.png",
		"mp_fridge_back.png",
		"mp_fridge_front.png"
	},
	drawtype = "nodebox",
	paramtype = "light",
	paramtype2 = "facedir",
	groups = {choppy = 2, oddly_breakable_by_hand = 2, furniture = 1},
		on_construct = function(pos)
		local meta = minetest.env:get_meta(pos)
		local inv = meta:get_inventory()
		inv:set_size('main', 8*4)
		inv:set_size('storage', 6*4)
		meta:set_string('formspec',
			'size [9,10]'..
			default.gui_bg..
			default.gui_bg_img..
			default.gui_slots..
			'bgcolor[#080808BB;true]'..
			'list[current_name;storage;1.5,1;6,4;]'..
			'list[current_player;main;0.5,6;8,4;]')
	end,
	can_dig = function(pos,player)
		local meta = minetest.get_meta(pos);
		local inv = meta:get_inventory()
		return inv:is_empty('storage') and inv:is_empty('storage1')
	end,
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, -0.5, -0.3125, 0.5, 0.5, 0.5}, -- NodeBox1
			{-0.5, -0.4375, -0.375, 0.4375, 0.5, -0.3125}, -- NodeBox2
			{0.3125, -0.25, -0.5, 0.375, 0.25, -0.4375}, -- NodeBox6
			{0.3125, -0.25, -0.4375, 0.375, -0.1875, -0.375}, -- NodeBox7
			{0.3125, 0.1875, -0.4375, 0.375, 0.25, -0.375}, -- NodeBox8
		}
	}
})

--Living Room--
local chair2_table = { --name, color, colorize(hex or color name:intensity(1-255))
{'Black', 'black', 'black:225'},
{'Blue', 'blue', 'blue:225'},
{'Brown', 'brown', 'brown:225'},
{'Cyan', 'cyan', 'cyan:200'},
{'Dark Green', 'dark_green', 'green:225'},
{'Dark Grey', 'dark_grey', 'black:200'},
{'Green', 'green', '#32cd32:150'},
{'Grey', 'grey', 'black:100'},
{'Magenta', 'magenta', 'magenta:200'},
{'Orange', 'orange', 'orange:225'},
{'Pink', 'pink', 'pink:225'},
{'Red', 'red', 'red:225'},
{'Violet', 'violet', 'violet:225'},
{'White', 'white', 'white:1'},
{'Yellow', 'yellow', 'yellow:225'},
}

for i in ipairs (chair2_table) do
    local name = chair2_table[i][1]
    local color = chair2_table[i][2]
    local hex = chair2_table[i][3]

local cb = "^([combine:16x16:0,0=mp_cb.png^[mask:mp_mask.png)"
local cf = "^([combine:16x16:0,0=mp_cf.png^[mask:mp_mask.png)"

minetest.register_node("ma_pops_furniture:chair2_"..color, {
    description = name.." Arm Chair",
    tiles = {"wool_"..color..".png","wool_"..color..".png"..cb,"wool_"..color..".png"..cf,"wool_"..color..".png"..cf,"wool_"..color..".png"..cf,"wool_"..color..".png"..cf,},
    drawtype = "nodebox",
    paramtype = "light",
    paramtype2 = "facedir",
    groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, furniture = 1, fall_damage_add_percent=-80, bouncy=80},
	sounds = {wood = {name="furn_bouncy", gain=0.8}},
    on_rightclick = function(pos, node, clicker)
        ma_pops_furniture.sit(pos, node, clicker)
        end,
    node_box = {
        type = "fixed",
        fixed = {
            {-0.4, -0.5, -0.4, -0.3, -0.4, -0.3},
            {-0.4, -0.5, 0.4, -0.3, -0.4, 0.3},
            {0.4, -0.5, 0.4, 0.3, -0.4, 0.3},
            {0.4, -0.5, -0.4, 0.3, -0.4, -0.3},
            -----------------------------------
            {-0.450, -0.4, -0.450, 0.450, 0.1, 0.450},
            {-0.5, 0.1, -0.5, -0.3, 0.3, 0.0},
            {0.5, 0.1, -0.5, 0.3, 0.3, 0.0},
            {0.450, 0.1, -0.0, -0.450, 0.5, 0.450},
        },
    }
})
end

--Outside--
minetest.register_node('ma_pops_furniture:birdbath', {
	description = 'Birdbath',
	drawtype = 'mesh',
	mesh = 'FM_birdbath.obj',
	tiles = {{name='default_stone.png'},{name='default_water_source_animated.png', animation={type='vertical_frames', aspect_w=16, aspect_h=16, length=2.0}}},
	groups = {cracky=2, oddly_breakable_by_hand=5, furniture=1},
	paramtype = 'light',
	paramtype2 = 'facedir',
	sounds = default.node_sound_stone_defaults(),
})


code:
local oven_fs = "size[8,7]"
    .."image[3.5,1.5;1,1;default_furnace_fire_bg.png]"
    .."list[current_player;main;0,3;8,4;]"
    .."list[context;input;2,1.5;1,1;]"
    .."list[context;output;5,1.5;1,1;]"
    .."label[3,0.5;Oven]"
    .."label[1.5,1;Uncooked Food]"
    .."label[4.5,1;Cooked Food]"
    -- possibly add "fire" image?

local function get_active_oven_fs(item_percent)
    return "size[8,7]"
	    .."image[3.5,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"
	    ..(item_percent)..":default_furnace_fire_fg.png]"
        .."list[current_player;main;0,3;8,4;]"
        .."list[context;input;2,1.5;1,1;]"
        .."list[context;output;5,1.5;1,1;]"
        .."label[3,0.5;Oven]"
        .."label[1.5,1;Uncooked Food]"
        .."label[4.5,1;Cooked Food]"
        -- possibly add "fire" image?
end

--x,y;w,h

-- Adding recipe API so we don't end up hardcoding items
ma_pops_furniture.oven = {}
local oven = ma_pops_furniture.oven
oven.recipes = {}
function oven.register_recipe(input, output) oven.recipes[input] = output end

local function update_formspec(progress, goal, meta)
    local formspec

    if progress > 0 and progress <= goal then
        local item_percent = math.floor(progress / goal * 100)
        formspec = get_active_oven_fs(item_percent)
    else
        formspec = oven_fs
    end

    meta:set_string("formspec", formspec)
end

local function recalculate(pos)
	local meta, timer = minetest.get_meta(pos), minetest.get_node_timer(pos)
	local inv = meta:get_inventory()
	local stack = inv:get_stack("input", 1)

	local k = oven.recipes[stack:get_name()]
	if not k then return end

	timer:stop()
    update_formspec(0, 3, meta)
    timer:start(1)
end

local function do_cook_single(pos)
    local meta = minetest.get_meta(pos)
	local inv = meta:get_inventory()
	local food_uncooked = inv:get_stack("input", 1)
    food_uncooked:set_count(1)

    --If the uncooked food wasn't removed mid-cooking, then cook it.
    if not oven.recipes[food_uncooked:get_name()] then
        minetest.chat_send_all("Oven cooked nothing because there was nothing to cook.")
        minetest.get_node_timer(pos):stop()
        update_formspec(0, 3, meta)
    else
        inv:remove_item("input", food_uncooked) -- Clear the slot
	    local food_cooked = oven.recipes[food_uncooked:get_name()] -- Get the cooked food
	    inv:add_item("output", food_cooked) -- Put the cooked food in the slot
    end
end

minetest.register_node("ma_pops_furniture:oven", {
	description = "Oven",
	tiles = {
		"mp_oven_top.png",
		"mp_oven_bottom.png",
		"mp_oven_right.png",
		"mp_oven_left.png",
		"mp_oven_back.png",
		"mp_oven_front.png"
	},
	paramtype2 = "facedir",
	groups = {cracky = 2, tubedevice = 1, tubedevice_receiver = 1},
	legacy_facedir_simple = true,
	is_ground_content = false,
	sounds = default.node_sound_stone_defaults(),
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {
			{-0.5, 0.3125, -0.5, 0.5, 0.5, 0.5},
			{-0.5, -0.5, -0.375, 0.5, 0.3125, 0.5},
			{-0.4375, -0.4375, -0.4375, 0.4375, 0.25, -0.375},
			{-0.375, 0.125, -0.5, 0.375, 0.1875, -0.375},
		},
	},
	can_dig = function(pos, player)
		local meta = minetest.get_meta(pos)
		local inv = meta:get_inventory()
		return inv:is_empty("input") and inv:is_empty("output")
	end,

	on_timer = function(pos, elapsed)
        local meta = minetest.get_meta(pos)
        local stack = meta:get_inventory():get_stack("input", 1)
        local cooking_time = meta:get_int("cooking_time") or 0
        cooking_time = cooking_time + 1

        if cooking_time % 3 == 0 then
            do_cook_single(pos)
        end

        update_formspec(cooking_time % 3, 3, meta)
        meta:set_int("cooking_time", cooking_time)

        --Keep cooking until there is nothing left to cook.
        if not stack:is_empty() then
            return true
        else
            meta:set_int("cooking_time", 0)
            update_formspec(0, 3, meta)
            return false
        end
	end,

	on_metadata_inventory_put = recalculate,
    on_metadata_inventory_take = recalculate,

	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		meta:set_string("formspec", oven_fs)
		local inv = meta:get_inventory()
		inv:set_size("input", 1)
        inv:set_size("output", 1)
	end,

	on_blast = function(pos)
		local drops = {}
		default.get_inventory_drops(pos, "input", drops)
        default.get_inventory_drops(pos, "output", drops)
		table.insert(drops, "ma_pops_furniture:oven")
		minetest.remove_node(pos)
		return drops
	end,

	allow_metadata_inventory_put = function(pos, list, index, stack, player)
		return oven.recipes[stack:get_name()] and stack:get_count() or 0
	end,
})

-- Recipe Registration
oven.register_recipe("default:ice", "default:water_source")
-- No milk bucket as this doesn't support substitutes for now
oven.register_recipe("mobs_mc:chicken_raw", "test:chicken_cooked")
--[[ We don't need to check mod existance when registering recipe
Recipe won't even be executed if there is no raw chicken in input ]]--
oven.register_recipe("mobs_mc:beef_raw", "test:beef_cooked")
oven.register_recipe("farming:coffee_cup", "farming:coffee_cup_hot") -- What a crutch there was...
-- Add needed recipes as you go, note that other mods can add more recipes too


code:
function ma_pops_furniture.sit(pos, node, clicker)
	do return end -- delete it when the engine is stabler for the player's physics
	local meta = minetest.get_meta(pos)
	local param2 = node.param2
	local name = clicker:get_player_name()

	if name == meta:get_string("is_sit") then
		meta:set_string("is_sit", "")
		pos.y = pos.y-0.5
		clicker:setpos(pos)
		clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
		clicker:set_physics_override(1, 1, 1)
		default.player_attached[name] = false
		default.player_set_animation(clicker, "stand", 30)
	else
		meta:set_string("is_sit", clicker:get_player_name())
		clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
		clicker:set_physics_override(0, 0, 0)
		clicker:setpos(pos)
		default.player_attached[name] = true
		default.player_set_animation(clicker, "sit", 30)
		if param2 == 0 then
			clicker:set_look_yaw(3.15)
		elseif param2 == 1 then
			clicker:set_look_yaw(7.9)
		elseif param2 == 2 then
			clicker:set_look_yaw(6.28)
		elseif param2 == 3 then
			clicker:set_look_yaw(4.75)
		else return end
	end
end


code:
local S = ma_pops_furniture.intllib

--Toaster and Toast--
minetest.register_node("ma_pops_furniture:toaster", {
	description = S("Toaster"),
	tiles = {
		"mp_toas_top.png",
		"mp_toas_bottom.png",
		"mp_toas_right.png",
		"mp_toas_left.png",
		"mp_toas_back.png",
		"mp_toas_front.png"
	},
	walkable = false,
	groups = { snappy=3 },
	paramtype = "light",
	paramtype2 = "facedir",
	is_ground_content = false,
	drawtype = "nodebox",
	node_box = {
       type = "fixed",
       fixed = {
           {-0.375, -0.5, 0, 0.375, -0.0625, 0.3125},
		   {-0.4375, -0.1875, 0.0625, -0.375, -0.125, 0.25},
       },
   },
})

minetest.override_item("farming:bread", {
	description = S("Bread"),
})

local function breadslice_on_use(itemstack, user, pointed_thing)
	local node, pos
	if pointed_thing.under then
		pos = pointed_thing.under
		node = minetest.get_node(pos)
	end

	local pname = user:get_player_name()

	if node and pos and (node.name == "ma_pops_furniture:toaster") then
		if minetest.is_protected(pos, pname) then
			minetest.record_protection_violation(pos, pname)
			else
				if itemstack:get_count() >= 2 then
					itemstack:take_item(2)
					minetest.set_node(pos, {name = "ma_pops_furniture:toaster_with_breadslice", param2 = node.param2})
				return itemstack
			end
		end
	else
		return minetest.do_item_eat(2, nil, itemstack, user, pointed_thing)
	end
end

if minetest.registered_items["farming:bread_slice"] then
	minetest.override_item("farming:bread_slice", {on_use = breadslice_on_use })
	minetest.register_alias("ma_pops_furniture:breadslice", "farming:bread_slice")
else
	minetest.register_craftitem("ma_pops_furniture:breadslice", {
		description = S("Slice of Bread"),
		inventory_image = "mp_breadslice.png",
		groups = {flammable = 2},
		on_use = breadslice_on_use,
	})
end

if minetest.registered_items["farming:toast"] then
	minetest.register_alias("ma_pops_furniture:toast", "farming:toast")
else
	minetest.register_craftitem("ma_pops_furniture:toast", {
		description = S("Toast"),
		inventory_image = "mp_toast.png",
		on_use = minetest.item_eat(3),
		groups = {flammable = 2},
	})
end

minetest.register_node("ma_pops_furniture:toaster_with_breadslice", {
	description = S("Toaster with Breadslice"),
	tiles = {
		"mp_toas_top_bread.png",
		"mp_toas_bottom.png",
		"mp_toas_right_bread.png",
		"mp_toas_left_bread.png",
		"mp_toas_back_bread.png",
		"mp_toas_front_bread.png"
	},
	walkable = false,
	groups = {not_in_creative_inventory=1},
	paramtype = "light",
	paramtype2 = "facedir",
	is_ground_content = false,
	diggable = false,
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {
			{-0.375, -0.5, 0, 0.375, -0.0625, 0.3125}, -- NodeBox1
			{-0.25, -0.0625, 0.0625, 0.25, 0.0625, 0.125}, -- NodeBox2
			{-0.25, -0.0625, 0.1875, 0.25, 0.0625, 0.25}, -- NodeBox3
			{-0.4375, -0.1875, 0.0625, -0.375, -0.125, 0.25}, -- NodeBox4
		},
	},
	on_punch = function(pos, node, clicker, itemstack, pointed_thing)
		local fdir = node.param2
		minetest.set_node(pos, { name = "ma_pops_furniture:toaster_toasting_breadslice", param2 = fdir })
		minetest.after(6, minetest.set_node, pos, { name = "ma_pops_furniture:toaster_with_toast", param2 = fdir })
		minetest.sound_play("toaster", {
			pos = pos,
			gain = 1.0,
			max_hear_distance = 5
		})
		return itemstack
	end
})

minetest.register_node("ma_pops_furniture:toaster_toasting_breadslice", {
	description = S("Toaster Toasting Slice of Bread"),
	tiles = {
		"mp_toas_top_bread_on.png",
		"mp_toas_bottom.png",
		"mp_toas_right_bread.png",
		"mp_toas_left_toast_side.png",
		"mp_toas_back_side.png",
		"mp_toas_front_side.png"
	},
	walkable = false,
	groups = {not_in_creative_inventory = 1 },
	paramtype = "light",
	paramtype2 = "facedir",
	is_ground_content = false,
	diggable = false,
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {
			{-0.375, -0.5, 0, 0.375, -0.0625, 0.3125}, -- NodeBox1
			{-0.4375, -0.375, 0.0625, -0.375, -0.3125, 0.25}, -- NodeBox4
		},
	},
})

minetest.register_node("ma_pops_furniture:toaster_with_toast", {
	description = S("Toaster with Toast"),
		tiles = {
		"mp_toas_top_toast.png",
		"mp_toas_bottom.png",
		"mp_toas_right_toast.png",
		"mp_toas_left_toast.png",
		"mp_toas_back_toast.png",
		"mp_toas_front_toast.png"
	},
	walkable = false,
	groups = { snappy=3, not_in_creative_inventory=1 },
	paramtype = "light",
	paramtype2 = "facedir",
	is_ground_content = false,
	drawtype = "nodebox",
	node_box = {
		type = "fixed",
		fixed = {
			{-0.375, -0.5, 0, 0.375, -0.0625, 0.3125}, -- NodeBox1
			{-0.25, -0.0625, 0.0625, 0.25, 0.0625, 0.125}, -- NodeBox2
			{-0.25, -0.0625, 0.1875, 0.25, 0.0625, 0.25}, -- NodeBox3
			{-0.4375, -0.1875, 0.0625, -0.375, -0.125, 0.25}, -- NodeBox4
		},
	},
	on_punch = function (pos, node, player, pointed_thing)
		local inv = player:get_inventory()
		local left = inv:add_item("main", "ma_pops_furniture:toast 2")
		if left:is_empty() then
			minetest.set_node(pos, {name = "ma_pops_furniture:toaster", param2 = node.param2})
		end
	end
})

minetest.register_craft({
	output = 'ma_pops_furniture:toaster',
	recipe = {
	{'','','',},
	{'default:steel_ingot','default:mese_crystal','default:steel_ingot',},
	{'default:steel_ingot','mesecraft_bucket:bucket_lava','default:steel_ingot',},
	}
})

--Slice of Bread (only if not farming one used)
if not minetest.registered_items["farming:bread_slice"] then
	minetest.register_craft({
		output = 'ma_pops_furniture:breadslice 2',
		type = "shapeless",
		recipe = {"farming:bread"}
	})
end


code:
# Magic_materials
A mod providing shared resources for my other mods: [bweapons_modpack ](https://github.com/ClockGen/bweapons_modpack), [gadgets_modpack](https://github.com/ClockGen/gadgets_modpack) and possibly others.

This mod is not very useful when used by itself, as it only provides a new set of tools, 2 new ores, some decorations and various craftitems (useless without mods mentioned above).

## Recommended mods:
- [bweapons_modpack ](https://github.com/ClockGen/bweapons_modpack)
- [gadgets_modpack](https://github.com/ClockGen/gadgets_modpack)
- [farming_redo](https://notabug.org/TenPlus1/farming) (registers a new hoe if farming is present)
- [technic](https://github.com/minetest-mods/technic) (integrates new ores with alloying/grinding system in technic)
- [craftguide](https://github.com/minetest-mods/craftguide) (to see available crafts)

## License
All code is licensed under GPLv3 [link to the license](https://www.gnu.org/licenses/gpl-3.0.en.html)
All resources are licensed under CC BY 4.0 [link to the license](https://creativecommons.org/licenses/by/4.0/legalcode)


code:
minetest.register_craftitem("magic_materials:arcanite_crystal", {
    description = "Arcanite Crystal",
    inventory_image = "magic_materials_arcanite_crystal.png",
})

minetest.register_craftitem("magic_materials:arcanite_fragments", {
    description = "Arcanite Fragments",
    inventory_image = "magic_materials_arcanite_fragments.png",
})

minetest.register_craftitem("magic_materials:egerum_crystal", {
    description = "Egerum Crystal",
    inventory_image = "magic_materials_egerum_crystal.png",
})

minetest.register_craftitem("magic_materials:februm_crystal", {
    description = "Februm Crystal",
    inventory_image = "magic_materials_februm_crystal.png",
})

minetest.register_craftitem("magic_materials:enchanted_book", {
    description = "Blank Enchanted Book",
    inventory_image = "magic_materials_enchanted_book.png",
})

minetest.register_craftitem("magic_materials:enchanted_page", {
    description = "Enchanted Page",
    inventory_image = "magic_materials_enchanted_page.png",
})

minetest.register_craftitem("magic_materials:enchanted_rune", {
    description = "Enchanted Rune",
    inventory_image = "magic_materials_enchanted_rune.png",
})

minetest.register_craftitem("magic_materials:enchanted_staff", {
    description = "Blank Enchanted Staff",
    inventory_image = "magic_materials_enchanted_staff.png",
})

minetest.register_craftitem("magic_materials:magic_root", {
    description = "Magic Root",
    inventory_image = "magic_materials_magic_root.png",
})

minetest.register_craftitem("magic_materials:magic_flower", {
    description = "Magic Flower",
    inventory_image = "magic_materials_magic_flower.png",
})

minetest.register_craftitem("magic_materials:magic_mushroom", {
    description = "Magic Mushroom",
    inventory_image = "magic_materials_magic_mushroom.png",
})

minetest.register_craftitem("magic_materials:fire_rune", {
    description = "Fire Rune",
    inventory_image = "magic_materials_fire_rune.png",
})

minetest.register_craftitem("magic_materials:ice_rune", {
    description = "Ice Rune",
    inventory_image = "magic_materials_ice_rune.png",
})

minetest.register_craftitem("magic_materials:storm_rune", {
    description = "Storm Rune",
    inventory_image = "magic_materials_storm_rune.png",
})

minetest.register_craftitem("magic_materials:void_rune", {
    description = "Void Rune",
    inventory_image = "magic_materials_void_rune.png",
})

minetest.register_craftitem("magic_materials:light_rune", {
    description = "Light Rune",
    inventory_image = "magic_materials_light_rune.png",
})

minetest.register_craftitem("magic_materials:energy_rune", {
    description = "Energy Rune",
    inventory_image = "magic_materials_energy_rune.png",
})

minetest.register_craftitem("magic_materials:earth_rune", {
    description = "Earth Rune",
    inventory_image = "magic_materials_earth_rune.png",
})


code:
--Blocks
for _,v in pairs({"februm", "egerum", "arcanite"}) do
    minetest.register_craft({
        output = 'magic_materials:' .. v .. '_block',
        recipe = {
                {'magic_materials:' .. v .. '_crystal', 'magic_materials:' .. v .. '_crystal', 'magic_materials:' .. v .. '_crystal'},
                {'magic_materials:' .. v .. '_crystal', 'magic_materials:' .. v .. '_crystal', 'magic_materials:' .. v .. '_crystal'},
                {'magic_materials:' .. v .. '_crystal', 'magic_materials:' .. v .. '_crystal', 'magic_materials:' .. v .. '_crystal'},
            },
    })

    minetest.register_craft({
        type = "shapeless",
        output = 'magic_materials:' .. v .. '_crystal 9',
        recipe = {
            "magic_materials:" .. v .. "_block",
        },
    })
end

--Craft items
minetest.register_craft({
    type = "cooking",
    output = "magic_materials:arcanite_crystal",
    recipe = "magic_materials:arcanite_fragments",
    cooktime = 3,
})

minetest.register_craft({
    type = "shapeless",
    output = 'magic_materials:arcanite_fragments',
    recipe = {
            "magic_materials:februm_crystal",
            "magic_materials:egerum_crystal",
    },
})

minetest.register_craft({
    output = "magic_materials:enchanted_page",
    recipe = {
        {"magic_materials:egerum_crystal", "magic_materials:arcanite_crystal", "magic_materials:egerum_crystal"},
        {"magic_materials:arcanite_crystal", "default:paper", "magic_materials:arcanite_crystal"},
        {"magic_materials:egerum_crystal", "magic_materials:arcanite_crystal", "magic_materials:egerum_crystal"},
    },
})

minetest.register_craft({
    output = "magic_materials:enchanted_book",
    recipe = {
        {"", "magic_materials:enchanted_page", ""},
        {"", "magic_materials:enchanted_page", ""},
        {"", "magic_materials:enchanted_page", ""},
    },
})

minetest.register_craft({
    output = "magic_materials:enchanted_rune",
    recipe = {
        {"magic_materials:arcanite_crystal", "magic_materials:egerum_crystal", "magic_materials:arcanite_crystal"},
        {"magic_materials:egerum_crystal", "default:stone", "magic_materials:egerum_crystal"},
        {"magic_materials:arcanite_crystal", "magic_materials:egerum_crystal", "magic_materials:arcanite_crystal"},
    },
})

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

--Tools
minetest.register_craft({
    output = "magic_materials:pickaxe_arcanite",
    recipe = {
        {"magic_materials:arcanite_crystal", "magic_materials:arcanite_crystal", "magic_materials:arcanite_crystal"},
        {"", "group:stick", ""},
        {"", "group:stick", ""},
    },
})

minetest.register_craft({
    output = "magic_materials:axe_arcanite",
    recipe = {
        {"magic_materials:arcanite_crystal", "magic_materials:arcanite_crystal", ""},
        {"magic_materials:arcanite_crystal", "group:stick", ""},
        {"", "group:stick", ""},
    },
})

minetest.register_craft({
    output = "magic_materials:sword_arcanite",
    recipe = {
        {"", "magic_materials:arcanite_crystal", ""},
        {"", "magic_materials:arcanite_crystal", ""},
        {"", "group:stick", ""},
    },
})

minetest.register_craft({
    output = "magic_materials:shovel_arcanite",
    recipe = {
        {"", "magic_materials:arcanite_crystal", ""},
        {"", "group:stick", ""},
        {"", "group:stick", ""},
    },
})

if minetest.get_modpath("farming") then
    minetest.register_craft({
        output = "magic_materials:hoe_arcanite",
        recipe = {
            {"magic_materials:arcanite_crystal", "magic_materials:arcanite_crystal", ""},
            {"", "group:stick", ""},
            {"", "group:stick", ""},
        },
    })
end

minetest.register_craft({
    type = "shapeless",
    output = 'magic_materials:magic_root',
    recipe = {
            "group:tree",
            "magic_materials:egerum_crystal",
    },
})

minetest.register_craft({
    type = "shapeless",
    output = 'magic_materials:magic_flower',
    recipe = {
            "group:flower",
            "magic_materials:egerum_crystal",
    },
})

minetest.register_craft({
    type = "shapeless",
    output = 'magic_materials:magic_mushroom',
    recipe = {
            "flowers:mushroom_red",
            "magic_materials:egerum_crystal",
    },
})

minetest.register_craft({
    type = "shapeless",
    output = 'magic_materials:magic_mushroom',
    recipe = {
            "flowers:mushroom_brown",
            "magic_materials:egerum_crystal",
    },
})

minetest.register_craft({
    output = "magic_materials:fire_rune",
    recipe = {
        {"default:mese_crystal", "mesecraft_bucket:bucket_lava", "default:mese_crystal"},
        {"mesecraft_bucket:bucket_lava", "magic_materials:enchanted_rune", "mesecraft_bucket:bucket_lava"},
        {"default:mese_crystal", "mesecraft_bucket:bucket_lava", "default:mese_crystal"},
    },
    replacements = {{ "mesecraft_bucket:bucket_lava", "mesecraft_bucket:bucket_empty"}}
})

minetest.register_craft({
    output = "magic_materials:ice_rune",
    recipe = {
        {"default:diamond", "default:ice", "default:diamond"},
        {"default:ice", "magic_materials:enchanted_rune", "default:ice"},
        {"default:diamond", "default:ice", "default:diamond"},
    },
})

minetest.register_craft({
    output = "magic_materials:storm_rune",
    recipe = {
        {"default:diamond", "default:obsidian", "default:diamond"},
        {"default:obsidian", "magic_materials:enchanted_rune", "default:obsidian"},
        {"default:diamond", "default:obsidian", "default:diamond"},
    },
})

minetest.register_craft({
    output = "magic_materials:light_rune",
    recipe = {
        {"default:mese_crystal", "default:gold_ingot", "default:mese_crystal"},
        {"default:gold_ingot", "magic_materials:enchanted_rune", "default:gold_ingot"},
        {"default:mese_crystal", "default:gold_ingot", "default:mese_crystal"},
    },
})

minetest.register_craft({
    output = "magic_materials:void_rune",
    recipe = {
        {"magic_materials:arcanite_crystal", "default:obsidian", "magic_materials:arcanite_crystal"},
        {"default:obsidian", "magic_materials:enchanted_rune", "default:obsidian"},
        {"magic_materials:arcanite_crystal", "default:obsidian", "magic_materials:arcanite_crystal"},
    },
})

minetest.register_craft({
    output = "magic_materials:energy_rune",
    recipe = {
        {"default:diamond", "magic_materials:egerum_crystal", "default:diamond"},
        {"magic_materials:egerum_crystal", "magic_materials:enchanted_rune", "magic_materials:egerum_crystal"},
        {"default:diamond", "magic_materials:egerum_crystal", "default:diamond"},
    },
})

minetest.register_craft({
    output = "magic_materials:earth_rune",
    recipe = {
        {"default:coal_lump", "default:tin_lump", "default:copper_lump"},
        {"default:clay_lump", "magic_materials:enchanted_rune", "default:iron_lump"},
        {"default:gold_lump", "default:mese_crystal", "default:diamond"},
    },
})


code:
local path = minetest.get_modpath("magic_materials")
dofile(path .. "/nodes.lua")
dofile(path .. "/craftitems.lua")
dofile(path .. "/crafts.lua")
dofile(path .. "/mapgen.lua")
dofile(path .. "/tools.lua")

if minetest.get_modpath("technic") then
    dofile(path .. "/technic.lua")
end


code:
minetest.register_ore({
    ore_type = "scatter",
    ore = "magic_materials:stone_with_egerum",
    wherein = "default:stone",
    clust_scarcity = 14 * 14 * 14,
    clust_num_ores = 5,
    clust_size = 3,
    y_max = -256,
    y_min = -31000,
})

minetest.register_ore({
    ore_type = "scatter",
    ore = "magic_materials:stone_with_februm",
    wherein = "default:stone",
    clust_scarcity = 13 * 13 * 13,
    clust_num_ores = 6,
    clust_size = 3,
    y_max = -256,
    y_min = -31000,
})


code:
name = magic_materials
description = A mod providing common resources and shared magic system for modpacks like gadgets_modpack, bweapons_modpack, and possibly others
depends = default, mesecraft_bucket, farming
optional_depends = technic, stairs
author = ClockGen
title = Magic Materials


code:
minetest.register_node("magic_materials:stone_with_februm", {
    description = "Februm Ore",
    tiles = {"default_stone.png^magic_materials_mineral_februm.png"},
    groups = {cracky = 1},
    drop = "magic_materials:februm_crystal",
    sounds = default.node_sound_stone_defaults(),
})

minetest.register_node("magic_materials:stone_with_egerum", {
    description = "Egerum Ore",
    tiles = {"default_stone.png^magic_materials_mineral_egerum.png"},
    groups = {cracky = 1},
    drop = "magic_materials:egerum_crystal",
    sounds = default.node_sound_stone_defaults(),
})

minetest.register_node("magic_materials:arcanite_block", {
    description = "Arcanite Block",
    tiles = {"magic_materials_arcanite_block.png"},
    is_ground_content = false,
    groups = {cracky = 1, level = 2},
    sounds = default.node_sound_stone_defaults(),
})

minetest.register_node("magic_materials:februm_block", {
    description = "Februm Block",
    tiles = {"magic_materials_februm_block.png"},
    is_ground_content = false,
    groups = {cracky = 1, level = 2},
    sounds = default.node_sound_stone_defaults(),
})

minetest.register_node("magic_materials:egerum_block", {
    description = "Egerum Block",
    tiles = {"magic_materials_egerum_block.png"},
    is_ground_content = false,
    groups = {cracky = 1, level = 2},
    sounds = default.node_sound_stone_defaults(),
})

if minetest.get_modpath("stairs") then
    for k,v in pairs({Arcanite="arcanite", Februm="februm", Egerum="egerum"}) do
        stairs.register_stair_and_slab(
        v,
        "magic_materials:" .. v .. "_block",
        {cracky=1, level=2},
        {"magic_materials_" .. v .. "_block.png"},
        k .. " Stair",
        k .. " Slab",
        default.node_sound_stone_defaults(),
        false
        )
    end
end


code:
--Dusts
minetest.register_craftitem("magic_materials:arcanite_dust", {
    description = "Arcanite Dust",
    inventory_image = "magic_materials_arcanite_dust.png",
})

minetest.register_craftitem("magic_materials:februm_dust", {
    description = "Februm Dust",
    inventory_image = "magic_materials_februm_dust.png",
})

minetest.register_craftitem("magic_materials:egerum_dust", {
    description = "Egerum Dust",
    inventory_image = "magic_materials_egerum_dust.png",
})

--Machine-specific recipies
technic.register_separating_recipe({
    input = {"magic_materials:arcanite_dust" .. " 2"},
    output = {"magic_materials:februm_dust", "magic_materials:egerum_dust"},
})

technic.register_grinder_recipe({
    input = {"magic_materials:februm_crystal"},
    output = "magic_materials:februm_dust",
})

technic.register_grinder_recipe({
    input = {"magic_materials:egerum_crystal"},
    output = "magic_materials:egerum_dust",
})

technic.register_grinder_recipe({
    input = {"magic_materials:arcanite_crystal"},
    output = "magic_materials:arcanite_dust",
})

technic.register_grinder_recipe({
    input = {"magic_materials:arcanite_fragments"},
    output = "magic_materials:arcanite_dust",
})

technic.register_alloy_recipe({
    input = {"magic_materials:februm_crystal", "magic_materials:egerum_crystal"},
    output = "magic_materials:arcanite_crystal 2",
    time = 3
})

technic.register_alloy_recipe({
    input = {"magic_materials:februm_dust", "magic_materials:egerum_dust"},
    output = "magic_materials:arcanite_crystal 2",
    time = 3
})

--Smelting dusts
minetest.register_craft({
    type = "cooking",
    output = "magic_materials:februm_crystal",
    recipe = "magic_materials:februm_dust",
    cooktime = 3,
})

minetest.register_craft({
    type = "cooking",
    output = "magic_materials:egerum_crystal",
    recipe = "magic_materials:egerum_dust",
    cooktime = 3,
})

minetest.register_craft({
    type = "cooking",
    output = "magic_materials:arcanite_crystal",
    recipe = "magic_materials:arcanite_dust",
    cooktime = 3,
})


code:
minetest.register_tool("magic_materials:pickaxe_arcanite", {
    description = "Arcanite Pickaxe",
    inventory_image = "magic_materials_tool_pickaxe_arcanite.png",
    tool_capabilities = {
    full_punch_interval = 0.9,
        max_drop_level=3,
        groupcaps={
            cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=20, maxlevel=3},
        },
        damage_groups = {fleshy=5},
    },
    sound = {breaks = "default_tool_breaks"},
    groups = {pickaxe = 1}
})

minetest.register_tool("magic_materials:shovel_arcanite", {
    description = "Arcanite Shovel",
    inventory_image = "magic_materials_tool_shovel_arcanite.png",
    wield_image = "magic_materials_tool_shovel_arcanite.png^[transformR90",
    tool_capabilities = {
        full_punch_interval = 1.0,
        max_drop_level=1,
        groupcaps={
            crumbly = {times={[1]=1.10, [2]=0.50, [3]=0.30}, uses=20, maxlevel=3},
        },
        damage_groups = {fleshy=4},
    },
    sound = {breaks = "default_tool_breaks"},
    groups = {shovel = 1}
})

minetest.register_tool("magic_materials:axe_arcanite", {
    description = "Arcanite Axe",
    inventory_image = "magic_materials_tool_axe_arcanite.png",
    tool_capabilities = {
        full_punch_interval = 0.9,
        max_drop_level=1,
        groupcaps={
            choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=20, maxlevel=3},
        },
        damage_groups = {fleshy=7},
    },
    sound = {breaks = "default_tool_breaks"},
    groups = {axe = 1}
})

minetest.register_tool("magic_materials:sword_arcanite", {
    description = "Arcanite Sword",
    inventory_image = "magic_materials_tool_sword_arcanite.png",
    tool_capabilities = {
        full_punch_interval = 0.7,
        max_drop_level=1,
        groupcaps={
            snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=30, maxlevel=3},
        },
        damage_groups = {fleshy=8},
    },
    sound = {breaks = "default_tool_breaks"},
    groups = {sword = 1}
})

if minetest.get_modpath("farming") then
    farming.register_hoe("magic_materials:hoe_arcanite", {
        description = ("Arcanite Hoe"),
        inventory_image = "magic_materials_tool_hoe_arcanite.png",
        max_uses = 200,
        material = "magic_materials:arcanite_crystal"
    })
end


code:
-- MAGIC MIRROR
-- by FreeGamers.org
-- Based off of "Mirror of Returning" by Wuzzy and "Recall Mirror" by davidthecreator. Thank you!

local magicmirror = {}

-- Sets the fallback position for users with no bed spawn.
-- Pull static spawn point from minetest.conf or settings.
magicmirror.placeholder_pos  = minetest.setting_get_pos("static_spawnpoint") or {x=0,y=0,z=0}

-- Set the mana cost for teleporting
magicmirror.cost_teleport = 200

-- Check settings for mana cost overrides.
if tonumber(minetest.settings:get("magicmirror_cost_teleport")) ~= nil then
	magicmirror.cost_teleport = tonumber(minetest.settings:get("magicmirror_cost_teleport"))
end

-- Set the magic mirror crafting recipes (Disabled here since its a drop-only item in Sara's Survival Server).
--minetest.register_craft({
--      output = "magic_mirror:magic_mirror",
--      recipe = {
--              {"default:gold_ingot", "default:diamond", "default:gold_ingot"},
--              {"default:mese", "default:glass", "default:mese"},
--              {"default:gold_ingot", "default:diamond", "default:gold_ingot"},
--      }
--})

-- Check to see if the user has mana or not
magicmirror.mana_check = function(player, cost)
	local allowed
	         -- Mana subtract function.
                 if mana.subtract(player:get_player_name(), cost) then
                        allowed = true
                 else
        	        allowed = false
                 end
		 return allowed
                 end -- end function

-- REGISTER THE MIRROR TOOL
minetest.register_tool("magic_mirror:magic_mirror", {
	description = "" ..core.colorize("#35cdff","Magic Mirror\n") ..core.colorize("#FFFFFF", "Gaze deeply into the mirror to return home."),
	range = 0,
	stack_max = 1,
	inventory_image = "magic_mirror.png",
	on_use = function(itemstack,user)

		-- If user has the mana cost he/she can teleport.
		if magicmirror.mana_check(user, magicmirror.cost_teleport) then --allowed == true then

			-- Get the player name, current position, and bed position.
			local name = user:get_player_name()
			local firstpos = user:getpos()
                        local rec_pos = beds.spawn[name]

			-- Teleporting departure effect.
                        minetest.sound_play("magic_mirror_teleport", {pos = firstpos, gain = 0.8})
                        for i=1,50 do
	                        minetest.add_particle({
	                                pos = firstpos,
	                                acceleration = 0,
	                                velocity = {x=math.random(-20, 20)/10, y=math.random(-20, 20)/10, z=math.random(-20, 20)/10},
	                                size = math.random(2,6),
	                                expirationtime = 3.0,
	                                collisiondetection = false,
	                                vertical = false,
	                                texture = "magic_mirror_particle.png",
	                                animation = {type="vertical_frames", aspect_w=8, aspect_h=8, length = 0.50,},
	                                glow = 30,
	                        })
                        end

                        -- Move the player to their bed position, else fallback to the spawn point.
                        if rec_pos then
                                user:set_pos(rec_pos)
                        else
                                user:set_pos(magicmirror.placeholder_pos)
                        end

                        -- Teleportation effects on arrival location.
                        local nextpos = user:getpos()
                        minetest.sound_play("magic_mirror_teleport", {pos = nextpos, gain = 1.0})
                        for i=1,50 do
                                minetest.add_particle({
                                        pos = nextpos,
                                        acceleration = 0,
                                        velocity = {x=math.random(-20, 20)/10, y=math.random(-20, 20)/10, z=math.random(-20, 20)/10},
                                        size = math.random(2,6),
                                        expirationtime = 3.0,
                                        collisiondetection = false,
                                        vertical = false,
                                        texture = "magic_mirror_particle.png",
                                        animation = {type="vertical_frames", aspect_w=8, aspect_h=8, length = 0.2,},
                                        glow = 30,
                                })
                        end

		-- User does not have enough mana, play sound effect
		else
			local firstpos = user:getpos()
			minetest.sound_play("bweapons_magic_pack_reload", {pos = firstpos, gain = 0.25})
		end -- end of "mana_check false" section.
end}) -- end register tool function


code:
name = magic_mirror
description = Gaze into the mirror to return to your bed.
author = MeseCraft
depends = mana, mesecraft_beds