Merge pull request 'Fix Blast Furnaces and Smokers' (#336) from PrairieAstronomer/MineClone5:blast_furnace_fixes into master

Reviewed-on: MineClone5/MineClone5#336
This commit is contained in:
PrairieWind 2022-06-12 02:33:29 +00:00
commit 615eae97ee
31 changed files with 660 additions and 658 deletions

View File

@ -201,6 +201,8 @@ These groups are used mostly for informational purposes
* `building_block=1`: Block is a building block * `building_block=1`: Block is a building block
* `deco_block=1`: Block is a decorational block * `deco_block=1`: Block is a decorational block
* `blast_furnace_smeltable=1` : Item or node is smeltable by a blast furnace
* `smoker_cookable=1` : Food is cookable by a smoker.
## Fake item groups ## Fake item groups
These groups put similar items together which should all be treated by the gameplay or the GUI as a single item. These groups put similar items together which should all be treated by the gameplay or the GUI as a single item.

View File

@ -0,0 +1,13 @@
Blast Furnaces for MineClone 5.
Heavily based on Minetest Game (default/furnace.lua) and the MineClone 5 Furnaces.
License of source code
----------------------
LGPLv2.1
Based on code from Minetest Game.
Modified by Wuzzy.
MCl 2 Furances modified by PrairieWind.
License of media
----------------
See the main MineClone 5 README.md file.

View File

@ -198,7 +198,7 @@ local function swap_node(pos, name)
end end
node.name = name node.name = name
minetest.swap_node(pos, node) minetest.swap_node(pos, node)
if name == "mcl_furnaces:blast_furnace_active" then if name == "mcl_blast_furnace:blast_furnace_active" then
spawn_flames(pos, node.param2) spawn_flames(pos, node.param2)
else else
mcl_particles.delete_node_particlespawners(pos) mcl_particles.delete_node_particlespawners(pos)
@ -244,16 +244,7 @@ local function furnace_node_timer(pos, elapsed)
-- Check if we have cookable content: cookable -- Check if we have cookable content: cookable
local aftercooked local aftercooked
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
cookable = false cookable = minetest.get_item_group(inv:get_stack("src", 1):get_name(), "blast_furnace_smeltable") == 1
cookableItems = {"mcl_raw_ores:raw_iron", "mcl_raw_ores:raw_gold", "mcl_copper:raw_copper", "mcl_nether:ancient_debris"}
cookable = false
--for _, item in ipairs(cookableItems) do
for _,item in ipairs(cookableItems) do
local stack = inv:get_stack("src",1)
if stack:get_name() == item then
cookable = true
end
end
if cookable then if cookable then
-- Successful cooking requires space in dst slot and time -- Successful cooking requires space in dst slot and time
if not inv:room_for_item("dst", cooked.item) then if not inv:room_for_item("dst", cooked.item) then
@ -289,13 +280,13 @@ local function furnace_node_timer(pos, elapsed)
elseif active then elseif active then
el = math.min(el, fuel_totaltime - fuel_time) el = math.min(el, fuel_totaltime - fuel_time)
-- The furnace is currently active and has enough fuel -- The furnace is currently active and has enough fuel
fuel_time = fuel_time + el fuel_time = (fuel_time + el)*2
end end
-- If there is a cookable item then check if it is ready yet -- If there is a cookable item then check if it is ready yet
if cookable and active then if cookable and active then
-- in the src_time variable, the *1.5 is the multiplication that makes the blast furnace work faster than a normal furnace. I (PrairieWind) have it at 1.5 times faster, but it can be OP and 2 times faster, or 1.2 times faster. All are good numbers. -- in the src_time variable, the *2 is the multiplication that makes the blast furnace work faster than a normal furnace.
src_time = (src_time + el)*1.5 src_time = (src_time + el)*2
-- Place result in dst list if done -- Place result in dst list if done
if src_time >= cooked.time then if src_time >= cooked.time then
inv:add_item("dst", cooked.item) inv:add_item("dst", cooked.item)
@ -335,11 +326,11 @@ local function furnace_node_timer(pos, elapsed)
fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
end end
formspec = active_formspec(fuel_percent, item_percent) formspec = active_formspec(fuel_percent, item_percent)
swap_node(pos, "mcl_furnaces:blast_furnace_active") swap_node(pos, "mcl_blast_furnace:blast_furnace_active")
-- make sure timer restarts automatically -- make sure timer restarts automatically
result = true result = true
else else
swap_node(pos, "mcl_furnaces:blast_furnace") swap_node(pos, "mcl_blast_furnace:blast_furnace")
-- stop timer on the inactive furnace -- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop() minetest.get_node_timer(pos):stop()
end end
@ -366,17 +357,17 @@ if minetest.get_modpath("screwdriver") then
after_rotate_active = function(pos) after_rotate_active = function(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
mcl_particles.delete_node_particlespawners(pos) mcl_particles.delete_node_particlespawners(pos)
if node.name == "mcl_furnaces:blast_furnace" then if node.name == "mcl_blast_furnace:blast_furnace" then
return return
end end
spawn_flames(pos, node.param2) spawn_flames(pos, node.param2)
end end
end end
minetest.register_node("mcl_furnaces:blast_furnace", { minetest.register_node("mcl_blast_furnace:blast_furnace", {
description = S("Blast Furnace"), description = S("Blast Furnace"),
_tt_help = S("Uses fuel to smelt or cook items"), _tt_help = S("Smelts ores faster than furnace"),
_doc_items_longdesc = S("Blast Furnaces cook or smelt several items, using a furnace fuel, into something else, but faster than a normal furnace."), _doc_items_longdesc = S("Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else."),
_doc_items_usagehelp = _doc_items_usagehelp =
S([[ S([[
Use the furnace to open the furnace menu. Use the furnace to open the furnace menu.
@ -456,7 +447,7 @@ minetest.register_node("mcl_furnaces:blast_furnace", {
on_rotate = on_rotate, on_rotate = on_rotate,
}) })
minetest.register_node("mcl_furnaces:blast_furnace_active", { minetest.register_node("mcl_blast_furnace:blast_furnace_active", {
description = S("Active Blast Furnace"), description = S("Active Blast Furnace"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
tiles = { tiles = {
@ -468,7 +459,7 @@ minetest.register_node("mcl_furnaces:blast_furnace_active", {
paramtype2 = "facedir", paramtype2 = "facedir",
paramtype = "light", paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE, light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_furnaces:blast_furnace", drop = "mcl_blast_furnace:blast_furnace",
groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1}, groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1},
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
@ -511,7 +502,7 @@ minetest.register_node("mcl_furnaces:blast_furnace_active", {
}) })
minetest.register_craft({ minetest.register_craft({
output = "mcl_furnaces:blast_furnace", output = "mcl_blast_furnace:blast_furnace",
recipe = { recipe = {
{ "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" },
{ "mcl_core:iron_ingot", "mcl_furnaces:furnace", "mcl_core:iron_ingot" }, { "mcl_core:iron_ingot", "mcl_furnaces:furnace", "mcl_core:iron_ingot" },
@ -519,30 +510,21 @@ minetest.register_craft({
} }
}) })
minetest.register_alias("mcl_blast_furnace:blast_furnace", "mcl_furnaces:blast_furnace")
minetest.register_alias("mcl_blast_furnace:blast_furnace_active", "mcl_furnaces:blast_furnace_active")
-- Add entry alias for the Help -- Add entry alias for the Help
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_furnaces:blast_furnace", "nodes", "mcl_furnaces:blast_furnace_active") doc.add_entry_alias("nodes", "mcl_blast_furnace:blast_furnace", "nodes", "mcl_blast_furnace:blast_furnace_active")
end end
minetest.register_lbm({ minetest.register_lbm({
label = "Active furnace flame particles", label = "Active furnace flame particles",
name = "mcl_furnaces:flames", name = "mcl_blast_furnace:flames",
nodenames = {"mcl_furnaces:blast_furnace_active"}, nodenames = {"mcl_blast_furnace:blast_furnace_active"},
run_at_every_load = true, run_at_every_load = true,
action = function(pos, node) action = function(pos, node)
spawn_flames(pos, node.param2) spawn_flames(pos, node.param2)
end, end,
}) })
-- Legacy
minetest.register_lbm({
label = "Update furnace formspecs (0.60.0)",
name = "mcl_furnaces:update_formspecs_0_60_0",
-- Only update inactive furnaces because active ones should update themselves
nodenames = { "mcl_furnaces:blast_furnace" },
run_at_every_load = false,
action = function(pos, node)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", inactive_formspec)
end,
})

View File

@ -0,0 +1,5 @@
Inventory=
Blast Furnace=
Smelts ores faster than furnace=
Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=
Active Blast Furnace=

View File

@ -0,0 +1,3 @@
name = mcl_blast_furnace
depends = mcl_init, mcl_formspec, mcl_core, mcl_furnaces, mcl_sounds, mcl_craftguide, mcl_achievements, mcl_particles
optional_depends = doc, screwdriver

View File

Before

Width:  |  Height:  |  Size: 643 B

After

Width:  |  Height:  |  Size: 643 B

View File

Before

Width:  |  Height:  |  Size: 745 B

After

Width:  |  Height:  |  Size: 745 B

View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 636 B

After

Width:  |  Height:  |  Size: 636 B

View File

Before

Width:  |  Height:  |  Size: 593 B

After

Width:  |  Height:  |  Size: 593 B

View File

@ -12,5 +12,5 @@ minetest.register_craftitem("mcl_copper:raw_copper", {
_doc_items_longdesc = S("Raw Copper. Mine a Copper Ore to get it."), _doc_items_longdesc = S("Raw Copper. Mine a Copper Ore to get it."),
inventory_image = "mcl_copper_raw.png", inventory_image = "mcl_copper_raw.png",
stack_max = 64, stack_max = 64,
groups = { craftitem=1 }, groups = { craftitem=1, blast_furnace_smeltable=1 },
}) })

View File

@ -6,7 +6,7 @@ minetest.register_node("mcl_copper:stone_with_copper", {
tiles = {"default_stone.png^mcl_copper_ore.png"}, tiles = {"default_stone.png^mcl_copper_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=3, building_block=1, material_stone=1}, groups = {pickaxey=3, building_block=1, material_stone=1, blast_furnace_smeltable=1},
drop = "mcl_copper:raw_copper", drop = "mcl_copper:raw_copper",
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 3, _mcl_blast_resistance = 3,

View File

@ -48,7 +48,7 @@ minetest.register_node("mcl_core:stone_with_coal", {
tiles = {"mcl_core_coal_ore.png"}, tiles = {"mcl_core_coal_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=1, building_block=1, material_stone=1, xp=1}, groups = {pickaxey=1, building_block=1, material_stone=1, xp=1, blast_furnace_smeltable=1},
drop = "mcl_core:coal_lump", drop = "mcl_core:coal_lump",
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 3, _mcl_blast_resistance = 3,
@ -63,7 +63,7 @@ minetest.register_node("mcl_core:stone_with_iron", {
tiles = {"mcl_core_iron_ore.png"}, tiles = {"mcl_core_iron_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=3, building_block=1, material_stone=1}, groups = {pickaxey=3, building_block=1, material_stone=1, blast_furnace_smeltable=1},
drop = "mcl_core:stone_with_iron", drop = "mcl_core:stone_with_iron",
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 3, _mcl_blast_resistance = 3,
@ -78,7 +78,7 @@ minetest.register_node("mcl_core:stone_with_gold", {
tiles = {"mcl_core_gold_ore.png"}, tiles = {"mcl_core_gold_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=4, building_block=1, material_stone=1}, groups = {pickaxey=4, building_block=1, material_stone=1, blast_furnace_smeltable=1},
drop = "mcl_core:stone_with_gold", drop = "mcl_core:stone_with_gold",
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 3, _mcl_blast_resistance = 3,
@ -98,7 +98,7 @@ minetest.register_node("mcl_core:stone_with_redstone", {
tiles = {"mcl_core_redstone_ore.png"}, tiles = {"mcl_core_redstone_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=4, building_block=1, material_stone=1, xp=7}, groups = {pickaxey=4, building_block=1, material_stone=1, xp=7, blast_furnace_smeltable=1},
drop = { drop = {
items = { items = {
max_items = 1, max_items = 1,
@ -176,7 +176,7 @@ minetest.register_node("mcl_core:stone_with_lapis", {
tiles = {"mcl_core_lapis_ore.png"}, tiles = {"mcl_core_lapis_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=3, building_block=1, material_stone=1, xp=6}, groups = {pickaxey=3, building_block=1, material_stone=1, xp=6, blast_furnace_smeltable=1},
drop = { drop = {
max_items = 1, max_items = 1,
items = { items = {
@ -200,7 +200,7 @@ minetest.register_node("mcl_core:stone_with_emerald", {
tiles = {"mcl_core_emerald_ore.png"}, tiles = {"mcl_core_emerald_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=4, building_block=1, material_stone=1, xp=6}, groups = {pickaxey=4, building_block=1, material_stone=1, xp=6, blast_furnace_smeltable=1},
drop = "mcl_core:emerald", drop = "mcl_core:emerald",
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 3, _mcl_blast_resistance = 3,
@ -215,7 +215,7 @@ minetest.register_node("mcl_core:stone_with_diamond", {
tiles = {"mcl_core_diamond_ore.png"}, tiles = {"mcl_core_diamond_ore.png"},
is_ground_content = true, is_ground_content = true,
stack_max = 64, stack_max = 64,
groups = {pickaxey=4, building_block=1, material_stone=1, xp=4}, groups = {pickaxey=4, building_block=1, material_stone=1, xp=4, blast_furnace_smeltable=1},
drop = "mcl_core:diamond", drop = "mcl_core:diamond",
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 3, _mcl_blast_resistance = 3,

View File

@ -427,7 +427,7 @@ minetest.register_craftitem("mcl_fishing:fish_raw", {
on_place = minetest.item_eat(2), on_place = minetest.item_eat(2),
on_secondary_use = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2),
stack_max = 64, stack_max = 64,
groups = { food=2, eatable = 2 }, groups = { food=2, eatable = 2, smoker_cookable = 1 },
_mcl_saturation = 0.4, _mcl_saturation = 0.4,
}) })
@ -457,7 +457,7 @@ minetest.register_craftitem("mcl_fishing:salmon_raw", {
on_place = minetest.item_eat(2), on_place = minetest.item_eat(2),
on_secondary_use = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2),
stack_max = 64, stack_max = 64,
groups = { food=2, eatable = 2 }, groups = { food=2, eatable = 2, smoker_cookable = 1 },
_mcl_saturation = 0.4, _mcl_saturation = 0.4,
}) })

View File

@ -1,558 +0,0 @@
local S = minetest.get_translator(minetest.get_current_modname())
local LIGHT_ACTIVE_FURNACE = 13
--
-- Formspecs
--
local function active_formspec(fuel_percent, item_percent)
return "size[9,8.75]"..
"label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]"..
"list[context;src;2.75,0.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,0.5,1,1)..
"list[context;fuel;2.75,2.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,2.5,1,1)..
"list[context;dst;5.75,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(5.75,1.5,1,1)..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-fuel_percent)..":default_furnace_fire_fg.png]"..
"image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:"..
(item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
-- Craft guide button temporarily removed due to Minetest bug.
-- TODO: Add it back when the Minetest bug is fixed.
--"image_button[8,0;1,1;craftguide_book.png;craftguide;]"..
--"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;fuel]"..
"listring[current_player;main]"
end
local inactive_formspec = "size[9,8.75]"..
"label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]"..
"list[context;src;2.75,0.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,0.5,1,1)..
"list[context;fuel;2.75,2.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,2.5,1,1)..
"list[context;dst;5.75,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(5.75,1.5,1,1)..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
"image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]"..
-- Craft guide button temporarily removed due to Minetest bug.
-- TODO: Add it back when the Minetest bug is fixed.
--"image_button[8,0;1,1;craftguide_book.png;craftguide;]"..
--"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;fuel]"..
"listring[current_player;main]"
local receive_fields = function(pos, formname, fields, sender)
if fields.craftguide then
mcl_craftguide.show(sender:get_player_name())
end
end
local function give_xp(pos, player)
local meta = minetest.get_meta(pos)
local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95)
local xp = meta:get_int("xp")
if xp > 0 then
if player then
mcl_experience.add_xp(player, xp)
else
mcl_experience.throw_xp(vector.add(pos, dir), xp)
end
meta:set_int("xp", 0)
end
end
--
-- Node callback functions that are the same for active and inactive furnace
--
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
-- Special case: empty bucket (not a fuel, but used for sponge drying)
if stack:get_name() == "mcl_buckets:bucket_empty" then
if inv:get_stack(listname, index):get_count() == 0 then
return 1
else
return 0
end
end
-- Test stack with size 1 because we burn one fuel at a time
local teststack = ItemStack(stack)
teststack:set_count(1)
local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}})
if output.time ~= 0 then
-- Only allow to place 1 item if fuel get replaced by recipe.
-- This is the case for lava buckets.
local replace_item = decremented_input.items[1]
if replace_item:is_empty() then
-- For most fuels, just allow to place everything
return stack:get_count()
else
if inv:get_stack(listname, index):get_count() == 0 then
return 1
else
return 0
end
end
else
return 0
end
elseif 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)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
end
return stack:get_count()
end
local function on_metadata_inventory_take(pos, listname, index, stack, player)
-- Award smelting achievements
if listname == "dst" then
if stack:get_name() == "mcl_core:iron_ingot" then
awards.unlock(player:get_player_name(), "mcl:acquireIron")
elseif stack:get_name() == "mcl_fishing:fish_cooked" then
awards.unlock(player:get_player_name(), "mcl:cookFish")
end
give_xp(pos, player)
end
end
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
if from_list == "dst" then
give_xp(pos, player)
end
end
local function spawn_flames(pos, param2)
local minrelpos, maxrelpos
local dir = minetest.facedir_to_dir(param2)
if dir.x > 0 then
minrelpos = { x = -0.6, y = -0.05, z = -0.25 }
maxrelpos = { x = -0.55, y = -0.45, z = 0.25 }
elseif dir.x < 0 then
minrelpos = { x = 0.55, y = -0.05, z = -0.25 }
maxrelpos = { x = 0.6, y = -0.45, z = 0.25 }
elseif dir.z > 0 then
minrelpos = { x = -0.25, y = -0.05, z = -0.6 }
maxrelpos = { x = 0.25, y = -0.45, z = -0.55 }
elseif dir.z < 0 then
minrelpos = { x = -0.25, y = -0.05, z = 0.55 }
maxrelpos = { x = 0.25, y = -0.45, z = 0.6 }
else
return
end
mcl_particles.add_node_particlespawner(pos, {
amount = 4,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.4,
maxsize = 0.8,
texture = "mcl_particles_flame.png",
glow = LIGHT_ACTIVE_FURNACE,
}, "low")
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)
if name == "mcl_furnaces:furnace_active" then
spawn_flames(pos, node.param2)
else
mcl_particles.delete_node_particlespawners(pos)
end
end
local function furnace_node_timer(pos, elapsed)
--
-- Inizialize metadata
--
local meta = minetest.get_meta(pos)
local fuel_time = meta:get_float("fuel_time") or 0
local src_time = meta:get_float("src_time") or 0
local src_item = meta:get_string("src_item") or ""
local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
local inv = meta:get_inventory()
local srclist, fuellist
local cookable, cooked
local active = true
local fuel
srclist = inv:get_list("src")
fuellist = inv:get_list("fuel")
-- Check if src item has been changed
if srclist[1]:get_name() ~= src_item then
-- Reset cooking progress in this case
src_time = 0
src_item = srclist[1]:get_name()
end
local update = true
local elapsed_game_time = mcl_time.get_irl_seconds_passed_at_pos_or_nil(pos) or elapsed
while elapsed_game_time > 0.00001 and update do
--
-- Cooking
--
local el = elapsed_game_time
-- Check if we have cookable content: cookable
local aftercooked
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
cookable = cooked.time ~= 0
if cookable then
-- Successful cooking requires space in dst slot and time
if not inv:room_for_item("dst", cooked.item) then
cookable = false
end
end
if cookable then -- fuel lasts long enough, adjust el to cooking duration
el = math.min(el, cooked.time - src_time)
end
-- Check if we have enough fuel to burn
active = fuel_time < fuel_totaltime
if cookable and not active then
-- We need to get new fuel
local afterfuel
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
if fuel.time == 0 then
-- No valid fuel in fuel list -- stop
fuel_totaltime = 0
src_time = 0
update = false
else
-- Take fuel from fuel list
inv:set_stack("fuel", 1, afterfuel.items[1])
fuel_time = 0
fuel_totaltime = fuel.time
el = math.min(el, fuel_totaltime)
active = true
fuellist = inv:get_list("fuel")
end
elseif active then
el = math.min(el, fuel_totaltime - fuel_time)
-- The furnace is currently active and has enough fuel
fuel_time = fuel_time + el
end
-- If there is a cookable item then check if it is ready yet
if cookable and active then
src_time = src_time + el
-- Place result in dst list if done
if src_time >= cooked.time then
inv:add_item("dst", cooked.item)
inv:set_stack("src", 1, aftercooked.items[1])
-- Unique recipe: Pour water into empty bucket after cooking wet sponge successfully
if inv:get_stack("fuel", 1):get_name() == "mcl_buckets:bucket_empty" then
if srclist[1]:get_name() == "mcl_sponges:sponge_wet" then
inv:set_stack("fuel", 1, "mcl_buckets:bucket_water")
fuellist = inv:get_list("fuel")
-- Also for river water
elseif srclist[1]:get_name() == "mcl_sponges:sponge_wet_river_water" then
inv:set_stack("fuel", 1, "mcl_buckets:bucket_river_water")
fuellist = inv:get_list("fuel")
end
end
srclist = inv:get_list("src")
src_time = 0
meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count
end
end
elapsed_game_time = elapsed_game_time - el
end
if fuel and fuel_totaltime > fuel.time then
fuel_totaltime = fuel.time
end
if srclist and srclist[1]:is_empty() then
src_time = 0
end
--
-- Update formspec and node
--
local formspec = inactive_formspec
local item_percent = 0
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
end
local result = false
if active then
local fuel_percent = 0
if fuel_totaltime > 0 then
fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
end
formspec = active_formspec(fuel_percent, item_percent)
swap_node(pos, "mcl_furnaces:furnace_active")
-- make sure timer restarts automatically
result = true
else
swap_node(pos, "mcl_furnaces:furnace")
-- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop()
end
--
-- Set meta values
--
meta:set_float("fuel_totaltime", fuel_totaltime)
meta:set_float("fuel_time", fuel_time)
meta:set_float("src_time", src_time)
if srclist then
meta:set_string("src_item", src_item)
else
meta:set_string("src_item", "")
end
meta:set_string("formspec", formspec)
return result
end
local on_rotate, after_rotate_active
if minetest.get_modpath("screwdriver") then
on_rotate = screwdriver.rotate_simple
after_rotate_active = function(pos)
local node = minetest.get_node(pos)
mcl_particles.delete_node_particlespawners(pos)
if node.name == "mcl_furnaces:furnace" then
return
end
spawn_flames(pos, node.param2)
end
end
minetest.register_node("mcl_furnaces:furnace", {
description = S("Furnace"),
_tt_help = S("Uses fuel to smelt or cook items"),
_doc_items_longdesc = S("Furnaces cook or smelt several items, using a furnace fuel, into something else."),
_doc_items_usagehelp =
S([[
Use the furnace to open the furnace menu.
Place a furnace fuel in the lower slot and the source material in the upper slot.
The furnace will slowly use its fuel to smelt the item.
The result will be placed into the output slot at the right side.
]]).."\n"..
S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."),
_doc_items_hidden = false,
tiles = {
"default_furnace_top.png", "default_furnace_bottom.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front.png"
},
paramtype2 = "facedir",
groups = {pickaxey=1, container=4, deco_block=1, material_stone=1},
is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = furnace_node_timer,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta:to_table()
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst", "fuel"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2)
end,
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("fuel", 1)
inv:set_size("dst", 1)
end,
on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos)
give_xp(pos)
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
-- Reset accumulated game time when player works with furnace:
mcl_time.touch(pos)
minetest.get_node_timer(pos):start(1.0)
on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_put = function(pos)
-- Reset accumulated game time when player works with furnace:
mcl_time.touch(pos)
-- start timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
-- Reset accumulated game time when player works with furnace:
mcl_time.touch(pos)
-- start timer function, it will helpful if player clears dst slot
minetest.get_node_timer(pos):start(1.0)
on_metadata_inventory_take(pos, listname, index, stack, player)
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,
on_receive_fields = receive_fields,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
on_rotate = on_rotate,
})
minetest.register_node("mcl_furnaces:furnace_active", {
description = S("Burning Furnace"),
_doc_items_create_entry = false,
tiles = {
"default_furnace_top.png", "default_furnace_bottom.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front_active.png",
},
paramtype2 = "facedir",
paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_furnaces:furnace",
groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1},
is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = furnace_node_timer,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst", "fuel"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2:to_table())
end,
on_construct = function(pos)
local node = minetest.get_node(pos)
spawn_flames(pos, node.param2)
end,
on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos)
give_xp(pos)
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,
on_metadata_inventory_move = on_metadata_inventory_move,
on_metadata_inventory_take = on_metadata_inventory_take,
on_receive_fields = receive_fields,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
on_rotate = on_rotate,
after_rotate = after_rotate_active,
})
minetest.register_craft({
output = "mcl_furnaces:furnace",
recipe = {
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
{ "mcl_core:cobble", "", "mcl_core:cobble" },
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
}
})
-- Add entry alias for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_furnaces:furnace", "nodes", "mcl_furnaces:furnace_active")
end
minetest.register_lbm({
label = "Active furnace flame particles",
name = "mcl_furnaces:flames",
nodenames = {"mcl_furnaces:furnace_active"},
run_at_every_load = true,
action = function(pos, node)
spawn_flames(pos, node.param2)
end,
})
-- Legacy
minetest.register_lbm({
label = "Update furnace formspecs (0.60.0)",
name = "mcl_furnaces:update_formspecs_0_60_0",
-- Only update inactive furnaces because active ones should update themselves
nodenames = { "mcl_furnaces:furnace" },
run_at_every_load = false,
action = function(pos, node)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", inactive_formspec)
end,
})

View File

@ -1,6 +1,558 @@
-- Load files local S = minetest.get_translator(minetest.get_current_modname())
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath.."/blast_furnace.lua") -- Load Blast Furnaces local LIGHT_ACTIVE_FURNACE = 13
dofile(modpath.."/furnace.lua") -- Load Furnaces
dofile(modpath.."/smoker.lua") -- Load Smokers --
-- Formspecs
--
local function active_formspec(fuel_percent, item_percent)
return "size[9,8.75]"..
"label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]"..
"list[context;src;2.75,0.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,0.5,1,1)..
"list[context;fuel;2.75,2.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,2.5,1,1)..
"list[context;dst;5.75,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(5.75,1.5,1,1)..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
(100-fuel_percent)..":default_furnace_fire_fg.png]"..
"image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:"..
(item_percent)..":gui_furnace_arrow_fg.png^[transformR270]"..
-- Craft guide button temporarily removed due to Minetest bug.
-- TODO: Add it back when the Minetest bug is fixed.
--"image_button[8,0;1,1;craftguide_book.png;craftguide;]"..
--"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;fuel]"..
"listring[current_player;main]"
end
local inactive_formspec = "size[9,8.75]"..
"label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]"..
"list[context;src;2.75,0.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,0.5,1,1)..
"list[context;fuel;2.75,2.5;1,1;]"..
mcl_formspec.get_itemslot_bg(2.75,2.5,1,1)..
"list[context;dst;5.75,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(5.75,1.5,1,1)..
"image[2.75,1.5;1,1;default_furnace_fire_bg.png]"..
"image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]"..
-- Craft guide button temporarily removed due to Minetest bug.
-- TODO: Add it back when the Minetest bug is fixed.
--"image_button[8,0;1,1;craftguide_book.png;craftguide;]"..
--"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]"..
"listring[context;dst]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;fuel]"..
"listring[current_player;main]"
local receive_fields = function(pos, formname, fields, sender)
if fields.craftguide then
mcl_craftguide.show(sender:get_player_name())
end
end
local function give_xp(pos, player)
local meta = minetest.get_meta(pos)
local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95)
local xp = meta:get_int("xp")
if xp > 0 then
if player then
mcl_experience.add_xp(player, xp)
else
mcl_experience.throw_xp(vector.add(pos, dir), xp)
end
meta:set_int("xp", 0)
end
end
--
-- Node callback functions that are the same for active and inactive furnace
--
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
end
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "fuel" then
-- Special case: empty bucket (not a fuel, but used for sponge drying)
if stack:get_name() == "mcl_buckets:bucket_empty" then
if inv:get_stack(listname, index):get_count() == 0 then
return 1
else
return 0
end
end
-- Test stack with size 1 because we burn one fuel at a time
local teststack = ItemStack(stack)
teststack:set_count(1)
local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}})
if output.time ~= 0 then
-- Only allow to place 1 item if fuel get replaced by recipe.
-- This is the case for lava buckets.
local replace_item = decremented_input.items[1]
if replace_item:is_empty() then
-- For most fuels, just allow to place everything
return stack:get_count()
else
if inv:get_stack(listname, index):get_count() == 0 then
return 1
else
return 0
end
end
else
return 0
end
elseif 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)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
end
return stack:get_count()
end
local function on_metadata_inventory_take(pos, listname, index, stack, player)
-- Award smelting achievements
if listname == "dst" then
if stack:get_name() == "mcl_core:iron_ingot" then
awards.unlock(player:get_player_name(), "mcl:acquireIron")
elseif stack:get_name() == "mcl_fishing:fish_cooked" then
awards.unlock(player:get_player_name(), "mcl:cookFish")
end
give_xp(pos, player)
end
end
local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
if from_list == "dst" then
give_xp(pos, player)
end
end
local function spawn_flames(pos, param2)
local minrelpos, maxrelpos
local dir = minetest.facedir_to_dir(param2)
if dir.x > 0 then
minrelpos = { x = -0.6, y = -0.05, z = -0.25 }
maxrelpos = { x = -0.55, y = -0.45, z = 0.25 }
elseif dir.x < 0 then
minrelpos = { x = 0.55, y = -0.05, z = -0.25 }
maxrelpos = { x = 0.6, y = -0.45, z = 0.25 }
elseif dir.z > 0 then
minrelpos = { x = -0.25, y = -0.05, z = -0.6 }
maxrelpos = { x = 0.25, y = -0.45, z = -0.55 }
elseif dir.z < 0 then
minrelpos = { x = -0.25, y = -0.05, z = 0.55 }
maxrelpos = { x = 0.25, y = -0.45, z = 0.6 }
else
return
end
mcl_particles.add_node_particlespawner(pos, {
amount = 4,
time = 0,
minpos = vector.add(pos, minrelpos),
maxpos = vector.add(pos, maxrelpos),
minvel = { x = -0.01, y = 0, z = -0.01 },
maxvel = { x = 0.01, y = 0.1, z = 0.01 },
minexptime = 0.3,
maxexptime = 0.6,
minsize = 0.4,
maxsize = 0.8,
texture = "mcl_particles_flame.png",
glow = LIGHT_ACTIVE_FURNACE,
}, "low")
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)
if name == "mcl_furnaces:furnace_active" then
spawn_flames(pos, node.param2)
else
mcl_particles.delete_node_particlespawners(pos)
end
end
local function furnace_node_timer(pos, elapsed)
--
-- Inizialize metadata
--
local meta = minetest.get_meta(pos)
local fuel_time = meta:get_float("fuel_time") or 0
local src_time = meta:get_float("src_time") or 0
local src_item = meta:get_string("src_item") or ""
local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
local inv = meta:get_inventory()
local srclist, fuellist
local cookable, cooked
local active = true
local fuel
srclist = inv:get_list("src")
fuellist = inv:get_list("fuel")
-- Check if src item has been changed
if srclist[1]:get_name() ~= src_item then
-- Reset cooking progress in this case
src_time = 0
src_item = srclist[1]:get_name()
end
local update = true
local elapsed_game_time = mcl_time.get_irl_seconds_passed_at_pos_or_nil(pos) or elapsed
while elapsed_game_time > 0.00001 and update do
--
-- Cooking
--
local el = elapsed_game_time
-- Check if we have cookable content: cookable
local aftercooked
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
cookable = cooked.time ~= 0
if cookable then
-- Successful cooking requires space in dst slot and time
if not inv:room_for_item("dst", cooked.item) then
cookable = false
end
end
if cookable then -- fuel lasts long enough, adjust el to cooking duration
el = math.min(el, cooked.time - src_time)
end
-- Check if we have enough fuel to burn
active = fuel_time < fuel_totaltime
if cookable and not active then
-- We need to get new fuel
local afterfuel
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
if fuel.time == 0 then
-- No valid fuel in fuel list -- stop
fuel_totaltime = 0
src_time = 0
update = false
else
-- Take fuel from fuel list
inv:set_stack("fuel", 1, afterfuel.items[1])
fuel_time = 0
fuel_totaltime = fuel.time
el = math.min(el, fuel_totaltime)
active = true
fuellist = inv:get_list("fuel")
end
elseif active then
el = math.min(el, fuel_totaltime - fuel_time)
-- The furnace is currently active and has enough fuel
fuel_time = fuel_time + el
end
-- If there is a cookable item then check if it is ready yet
if cookable and active then
src_time = src_time + el
-- Place result in dst list if done
if src_time >= cooked.time then
inv:add_item("dst", cooked.item)
inv:set_stack("src", 1, aftercooked.items[1])
-- Unique recipe: Pour water into empty bucket after cooking wet sponge successfully
if inv:get_stack("fuel", 1):get_name() == "mcl_buckets:bucket_empty" then
if srclist[1]:get_name() == "mcl_sponges:sponge_wet" then
inv:set_stack("fuel", 1, "mcl_buckets:bucket_water")
fuellist = inv:get_list("fuel")
-- Also for river water
elseif srclist[1]:get_name() == "mcl_sponges:sponge_wet_river_water" then
inv:set_stack("fuel", 1, "mcl_buckets:bucket_river_water")
fuellist = inv:get_list("fuel")
end
end
srclist = inv:get_list("src")
src_time = 0
meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count
end
end
elapsed_game_time = elapsed_game_time - el
end
if fuel and fuel_totaltime > fuel.time then
fuel_totaltime = fuel.time
end
if srclist and srclist[1]:is_empty() then
src_time = 0
end
--
-- Update formspec and node
--
local formspec = inactive_formspec
local item_percent = 0
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
end
local result = false
if active then
local fuel_percent = 0
if fuel_totaltime > 0 then
fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
end
formspec = active_formspec(fuel_percent, item_percent)
swap_node(pos, "mcl_furnaces:furnace_active")
-- make sure timer restarts automatically
result = true
else
swap_node(pos, "mcl_furnaces:furnace")
-- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop()
end
--
-- Set meta values
--
meta:set_float("fuel_totaltime", fuel_totaltime)
meta:set_float("fuel_time", fuel_time)
meta:set_float("src_time", src_time)
if srclist then
meta:set_string("src_item", src_item)
else
meta:set_string("src_item", "")
end
meta:set_string("formspec", formspec)
return result
end
local on_rotate, after_rotate_active
if minetest.get_modpath("screwdriver") then
on_rotate = screwdriver.rotate_simple
after_rotate_active = function(pos)
local node = minetest.get_node(pos)
mcl_particles.delete_node_particlespawners(pos)
if node.name == "mcl_furnaces:furnace" then
return
end
spawn_flames(pos, node.param2)
end
end
minetest.register_node("mcl_furnaces:furnace", {
description = S("Furnace"),
_tt_help = S("Uses fuel to smelt or cook items"),
_doc_items_longdesc = S("Furnaces cook or smelt several items, using a furnace fuel, into something else."),
_doc_items_usagehelp =
S([[
Use the furnace to open the furnace menu.
Place a furnace fuel in the lower slot and the source material in the upper slot.
The furnace will slowly use its fuel to smelt the item.
The result will be placed into the output slot at the right side.
]]).."\n"..
S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."),
_doc_items_hidden = false,
tiles = {
"default_furnace_top.png", "default_furnace_bottom.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front.png"
},
paramtype2 = "facedir",
groups = {pickaxey=1, container=4, deco_block=1, material_stone=1},
is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = furnace_node_timer,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta:to_table()
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst", "fuel"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2)
end,
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("fuel", 1)
inv:set_size("dst", 1)
end,
on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos)
give_xp(pos)
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
-- Reset accumulated game time when player works with furnace:
mcl_time.touch(pos)
minetest.get_node_timer(pos):start(1.0)
on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
end,
on_metadata_inventory_put = function(pos)
-- Reset accumulated game time when player works with furnace:
mcl_time.touch(pos)
-- start timer function, it will sort out whether furnace can burn or not.
minetest.get_node_timer(pos):start(1.0)
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
-- Reset accumulated game time when player works with furnace:
mcl_time.touch(pos)
-- start timer function, it will helpful if player clears dst slot
minetest.get_node_timer(pos):start(1.0)
on_metadata_inventory_take(pos, listname, index, stack, player)
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,
on_receive_fields = receive_fields,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
on_rotate = on_rotate,
})
minetest.register_node("mcl_furnaces:furnace_active", {
description = S("Burning Furnace"),
_doc_items_create_entry = false,
tiles = {
"default_furnace_top.png", "default_furnace_bottom.png",
"default_furnace_side.png", "default_furnace_side.png",
"default_furnace_side.png", "default_furnace_front_active.png",
},
paramtype2 = "facedir",
paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_furnaces:furnace",
groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1},
is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(),
on_timer = furnace_node_timer,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta
meta:from_table(oldmetadata)
local inv = meta:get_inventory()
for _, listname in ipairs({"src", "dst", "fuel"}) do
local stack = inv:get_stack(listname, 1)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
meta:from_table(meta2:to_table())
end,
on_construct = function(pos)
local node = minetest.get_node(pos)
spawn_flames(pos, node.param2)
end,
on_destruct = function(pos)
mcl_particles.delete_node_particlespawners(pos)
give_xp(pos)
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,
on_metadata_inventory_move = on_metadata_inventory_move,
on_metadata_inventory_take = on_metadata_inventory_take,
on_receive_fields = receive_fields,
_mcl_blast_resistance = 3.5,
_mcl_hardness = 3.5,
on_rotate = on_rotate,
after_rotate = after_rotate_active,
})
minetest.register_craft({
output = "mcl_furnaces:furnace",
recipe = {
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
{ "mcl_core:cobble", "", "mcl_core:cobble" },
{ "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" },
}
})
-- Add entry alias for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_furnaces:furnace", "nodes", "mcl_furnaces:furnace_active")
end
minetest.register_lbm({
label = "Active furnace flame particles",
name = "mcl_furnaces:flames",
nodenames = {"mcl_furnaces:furnace_active"},
run_at_every_load = true,
action = function(pos, node)
spawn_flames(pos, node.param2)
end,
})
-- Legacy
minetest.register_lbm({
label = "Update furnace formspecs (0.60.0)",
name = "mcl_furnaces:update_formspecs_0_60_0",
-- Only update inactive furnaces because active ones should update themselves
nodenames = { "mcl_furnaces:furnace" },
run_at_every_load = false,
action = function(pos, node)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", inactive_formspec)
end,
})

View File

@ -20,7 +20,7 @@ minetest.register_craftitem("mcl_mobitems:mutton", {
wield_image = "mcl_mobitems_mutton_raw.png", wield_image = "mcl_mobitems_mutton_raw.png",
on_place = minetest.item_eat(2), on_place = minetest.item_eat(2),
on_secondary_use = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2),
groups = { food = 2, eatable = 2 }, groups = { food = 2, eatable = 2, smoker_cookable = 1 },
_mcl_saturation = 1.2, _mcl_saturation = 1.2,
stack_max = 64, stack_max = 64,
}) })
@ -44,7 +44,7 @@ minetest.register_craftitem("mcl_mobitems:beef", {
wield_image = "mcl_mobitems_beef_raw.png", wield_image = "mcl_mobitems_beef_raw.png",
on_place = minetest.item_eat(3), on_place = minetest.item_eat(3),
on_secondary_use = minetest.item_eat(3), on_secondary_use = minetest.item_eat(3),
groups = { food = 2, eatable = 3 }, groups = { food = 2, eatable = 3, smoker_cookable = 1 },
_mcl_saturation = 1.8, _mcl_saturation = 1.8,
stack_max = 64, stack_max = 64,
}) })
@ -69,7 +69,7 @@ minetest.register_craftitem("mcl_mobitems:chicken", {
wield_image = "mcl_mobitems_chicken_raw.png", wield_image = "mcl_mobitems_chicken_raw.png",
on_place = minetest.item_eat(2), on_place = minetest.item_eat(2),
on_secondary_use = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2),
groups = { food = 2, eatable = 2 }, groups = { food = 2, eatable = 2, smoker_cookable = 1 },
_mcl_saturation = 1.2, _mcl_saturation = 1.2,
stack_max = 64, stack_max = 64,
}) })
@ -93,7 +93,7 @@ minetest.register_craftitem("mcl_mobitems:porkchop", {
wield_image = "mcl_mobitems_porkchop_raw.png", wield_image = "mcl_mobitems_porkchop_raw.png",
on_place = minetest.item_eat(3), on_place = minetest.item_eat(3),
on_secondary_use = minetest.item_eat(3), on_secondary_use = minetest.item_eat(3),
groups = { food = 2, eatable = 3 }, groups = { food = 2, eatable = 3, smoker_cookable = 1 },
_mcl_saturation = 1.8, _mcl_saturation = 1.8,
stack_max = 64, stack_max = 64,
}) })
@ -117,7 +117,7 @@ minetest.register_craftitem("mcl_mobitems:rabbit", {
wield_image = "mcl_mobitems_rabbit_raw.png", wield_image = "mcl_mobitems_rabbit_raw.png",
on_place = minetest.item_eat(3), on_place = minetest.item_eat(3),
on_secondary_use = minetest.item_eat(3), on_secondary_use = minetest.item_eat(3),
groups = { food = 2, eatable = 3 }, groups = { food = 2, eatable = 3, smoker_cookable = 1 },
_mcl_saturation = 1.8, _mcl_saturation = 1.8,
stack_max = 64, stack_max = 64,
}) })

View File

@ -10,7 +10,7 @@ local function register_raw_ore(description, n)
_doc_items_longdesc = S("Raw "..ore..". Mine a"..n.." "..ore.." ore to get it."), _doc_items_longdesc = S("Raw "..ore..". Mine a"..n.." "..ore.." ore to get it."),
inventory_image = texture..".png", inventory_image = texture..".png",
stack_max = 64, stack_max = 64,
groups = { craftitem = 1 }, groups = { craftitem = 1, blast_furnace_smeltable=1 },
}) })
minetest.register_node(raw_ingot.."_block", { minetest.register_node(raw_ingot.."_block", {
description = S("Block of Raw "..description), description = S("Block of Raw "..description),

View File

@ -0,0 +1,13 @@
Smoker for MineClone 5.
Heavily based on Minetest Game (default/furnace.lua) and the MineClone 5 Furnaces.
License of source code
----------------------
LGPLv2.1
Based on code from Minetest Game.
Modified by Wuzzy.
MCl 2 Furances modified by PrairieWind.
License of media
----------------
See the main MineClone 5 README.md file.

View File

@ -198,7 +198,7 @@ local function swap_node(pos, name)
end end
node.name = name node.name = name
minetest.swap_node(pos, node) minetest.swap_node(pos, node)
if name == "mcl_furnaces:smoker_active" then if name == "mcl_smoker:smoker_active" then
spawn_flames(pos, node.param2) spawn_flames(pos, node.param2)
else else
mcl_particles.delete_node_particlespawners(pos) mcl_particles.delete_node_particlespawners(pos)
@ -244,15 +244,7 @@ local function furnace_node_timer(pos, elapsed)
-- Check if we have cookable content: cookable -- Check if we have cookable content: cookable
local aftercooked local aftercooked
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
cookable = false cookable = minetest.get_item_group(inv:get_stack("src", 1):get_name(), "smoker_cookable") == 1
cookableItems = {"mcl_fishing:fish_raw", "mcl_fishing:salmon_raw", "mcl_farming:potato_item", "mcl_mobitems:mutton", "mcl_mobitems:beef", "mcl_mobitems:chicken", "mcl_mobitems:porkchop", "mcl_mobitems:rabbit"}
--for _, item in ipairs(cookableItems) do
for _,item in ipairs(cookableItems) do
local stack = inv:get_stack("src",1)
if stack:get_name() == item then
cookable = true
end
end
if cookable then if cookable then
-- Successful cooking requires space in dst slot and time -- Successful cooking requires space in dst slot and time
if not inv:room_for_item("dst", cooked.item) then if not inv:room_for_item("dst", cooked.item) then
@ -288,13 +280,13 @@ local function furnace_node_timer(pos, elapsed)
elseif active then elseif active then
el = math.min(el, fuel_totaltime - fuel_time) el = math.min(el, fuel_totaltime - fuel_time)
-- The furnace is currently active and has enough fuel -- The furnace is currently active and has enough fuel
fuel_time = fuel_time + el fuel_time = (fuel_time + el)*2
end end
-- If there is a cookable item then check if it is ready yet -- If there is a cookable item then check if it is ready yet
if cookable and active then if cookable and active then
-- in the src_time variable, the *1.5 is the multiplication that makes the smoker work faster than a normal furnace. I (PrairieWind) have it at 1.5 times faster, but it can be OP and 2 times faster, or 1.2 times faster. All are good numbers. -- in the src_time variable, the *2 is the multiplication that makes the smoker work faster than a normal furnace.
src_time = (src_time + el)*1.5 src_time = (src_time + el)*2
-- Place result in dst list if done -- Place result in dst list if done
if src_time >= cooked.time then if src_time >= cooked.time then
inv:add_item("dst", cooked.item) inv:add_item("dst", cooked.item)
@ -334,11 +326,11 @@ local function furnace_node_timer(pos, elapsed)
fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
end end
formspec = active_formspec(fuel_percent, item_percent) formspec = active_formspec(fuel_percent, item_percent)
swap_node(pos, "mcl_furnaces:smoker_active") swap_node(pos, "mcl_smoker:smoker_active")
-- make sure timer restarts automatically -- make sure timer restarts automatically
result = true result = true
else else
swap_node(pos, "mcl_furnaces:smoker") swap_node(pos, "mcl_smoker:smoker")
-- stop timer on the inactive furnace -- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop() minetest.get_node_timer(pos):stop()
end end
@ -365,17 +357,17 @@ if minetest.get_modpath("screwdriver") then
after_rotate_active = function(pos) after_rotate_active = function(pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
mcl_particles.delete_node_particlespawners(pos) mcl_particles.delete_node_particlespawners(pos)
if node.name == "mcl_furnaces:smoker" then if node.name == "mcl_smoker:smoker" then
return return
end end
spawn_flames(pos, node.param2) spawn_flames(pos, node.param2)
end end
end end
minetest.register_node("mcl_furnaces:smoker", { minetest.register_node("mcl_smoker:smoker", {
description = S("Smoker"), description = S("Smoker"),
_tt_help = S("Uses fuel to smelt or cook items"), _tt_help = S("Cooks food faster than furnace"),
_doc_items_longdesc = S("Smokers cook or smelt several items, using a furnace fuel, into something else, but faster than a normal furnace."), _doc_items_longdesc = S("Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace."),
_doc_items_usagehelp = _doc_items_usagehelp =
S([[ S([[
Use the furnace to open the furnace menu. Use the furnace to open the furnace menu.
@ -455,8 +447,8 @@ minetest.register_node("mcl_furnaces:smoker", {
on_rotate = on_rotate, on_rotate = on_rotate,
}) })
minetest.register_node("mcl_furnaces:smoker_active", { minetest.register_node("mcl_smoker:smoker_active", {
description = S("Burning Furnace"), description = S("Burning Smoker"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
tiles = { tiles = {
"smoker_top.png", "smoker_top.png", "smoker_top.png", "smoker_top.png",
@ -467,7 +459,7 @@ minetest.register_node("mcl_furnaces:smoker_active", {
paramtype2 = "facedir", paramtype2 = "facedir",
paramtype = "light", paramtype = "light",
light_source = LIGHT_ACTIVE_FURNACE, light_source = LIGHT_ACTIVE_FURNACE,
drop = "mcl_furnaces:smoker", drop = "mcl_smoker:smoker",
groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1}, groups = {pickaxey=1, container=4, deco_block=1, not_in_creative_inventory=1, material_stone=1},
is_ground_content = false, is_ground_content = false,
sounds = mcl_sounds.node_sound_stone_defaults(), sounds = mcl_sounds.node_sound_stone_defaults(),
@ -510,7 +502,7 @@ minetest.register_node("mcl_furnaces:smoker_active", {
}) })
minetest.register_craft({ minetest.register_craft({
output = "mcl_furnaces:smoker", output = "mcl_smoker:smoker",
recipe = { recipe = {
{ "", "group:tree", "" }, { "", "group:tree", "" },
{ "group:tree", "mcl_furnaces:furnace", "group:tree" }, { "group:tree", "mcl_furnaces:furnace", "group:tree" },
@ -518,30 +510,20 @@ minetest.register_craft({
} }
}) })
minetest.register_alias("mcl_smoker:smoker", "mcl_furnaces:smoker")
minetest.register_alias("mcl_smoker:smoker_active", "mcl_furnaces:smoker_active")
-- Add entry alias for the Help -- Add entry alias for the Help
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_furnaces:smoker", "nodes", "mcl_furnaces:smoker_active") doc.add_entry_alias("nodes", "mcl_smoker:smoker", "nodes", "mcl_smoker:smoker_active")
end end
minetest.register_lbm({ minetest.register_lbm({
label = "Active furnace flame particles", label = "Active furnace flame particles",
name = "mcl_furnaces:flames", name = "mcl_smoker:flames",
nodenames = {"mcl_furnaces:smoker_active"}, nodenames = {"mcl_smoker:smoker_active"},
run_at_every_load = true, run_at_every_load = true,
action = function(pos, node) action = function(pos, node)
spawn_flames(pos, node.param2) spawn_flames(pos, node.param2)
end, end,
}) })
-- Legacy
minetest.register_lbm({
label = "Update furnace formspecs (0.60.0)",
name = "mcl_furnaces:update_formspecs_0_60_0",
-- Only update inactive furnaces because active ones should update themselves
nodenames = { "mcl_furnaces:smoker" },
run_at_every_load = false,
action = function(pos, node)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", inactive_formspec)
end,
})

View File

@ -0,0 +1,5 @@
Inventory=
Smoker=
Cooks food faster than furnace=
Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=
Burning Smoker=

View File

@ -0,0 +1,3 @@
name = mcl_smoker
depends = mcl_init, mcl_formspec, mcl_core, mcl_furnaces, mcl_sounds, mcl_craftguide, mcl_achievements, mcl_particles
optional_depends = doc, screwdriver

View File

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 496 B

View File

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 525 B

View File

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 809 B

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 538 B

After

Width:  |  Height:  |  Size: 538 B

View File

Before

Width:  |  Height:  |  Size: 597 B

After

Width:  |  Height:  |  Size: 597 B