Compare commits

..

2 Commits

Author SHA1 Message Date
Nils Dagsson Moskopp 042e464d74
Make daylight detector work in Minetest 5.3.0
This patch contains a function that searches for a path to a node with
light level 15, which is guaranteed to be sunlight.
2022-02-07 16:09:01 +01:00
Nils Dagsson Moskopp 801be0f048
Make daylight detector ignore artificial light
The daylight detector code used get_node_light(), which detects both
natural and artificial light. This patch improves the code to use
get_natural_light(), which was introduced with Minetest 5.4.0.
2022-02-07 14:05:33 +01:00
31 changed files with 395 additions and 458 deletions

View File

@ -1 +0,0 @@
name = walkover

View File

@ -123,10 +123,6 @@ mobs:register_mob("mobs_mc:snowman", {
local pos = self.object:get_pos() local pos = self.object:get_pos()
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
if minetest.registered_items["mcl_farming:pumpkin_face"] then
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_farming:pumpkin_face")
end
-- Wear out -- Wear out
if not minetest.is_creative_enabled(clicker:get_player_name()) then if not minetest.is_creative_enabled(clicker:get_player_name()) then
item:add_wear(mobs_mc.misc.shears_wear) item:add_wear(mobs_mc.misc.shears_wear)

View File

@ -74,7 +74,7 @@ local professions = {
}, },
{ {
{ { "mcl_farming:pumpkin", 8, 13 }, E1 }, { { "mcl_farming:pumpkin_face", 8, 13 }, E1 },
{ E1, { "mcl_farming:pumpkin_pie", 2, 3} }, { E1, { "mcl_farming:pumpkin_pie", 2, 3} },
}, },

View File

@ -1 +0,0 @@
name = mcl_experience

View File

@ -1,2 +1 @@
name = mcl_formspec
description = Helper mod to simplify creation of formspecs a little bit description = Helper mod to simplify creation of formspecs a little bit

View File

@ -1,8 +1,4 @@
mcl_tmp_message = { mcl_tmp_message = {}
hud_hide_timeout = tonumber(
minetest.settings:get("mcl_tmp_message_hud_hide_timeout")
) or 10
}
local huds = {} local huds = {}
local hud_hide_timeouts = {} local hud_hide_timeouts = {}
@ -10,7 +6,7 @@ local hud_hide_timeouts = {}
function mcl_tmp_message.message(player, message) function mcl_tmp_message.message(player, message)
local name = player:get_player_name() local name = player:get_player_name()
player:hud_change(huds[name], "text", message) player:hud_change(huds[name], "text", message)
hud_hide_timeouts[name] = mcl_tmp_message.hud_hide_timeout hud_hide_timeouts[name] = 3
end end
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)

View File

@ -1 +0,0 @@
name = mcl_tmp_message

View File

@ -43,20 +43,14 @@ end
local comparator_activate = function(pos, node) local comparator_activate = function(pos, node)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
local onstate = def.comparator_onstate minetest.swap_node(pos, { name = def.comparator_onstate, param2 = node.param2 })
if onstate then
minetest.swap_node(pos, { name = onstate, param2 = node.param2 })
end
minetest.after(0.1, comparator_turnon , {pos = pos, node = node}) minetest.after(0.1, comparator_turnon , {pos = pos, node = node})
end end
local comparator_deactivate = function(pos, node) local comparator_deactivate = function(pos, node)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
local offstate = def.comparator_offstate minetest.swap_node(pos, { name = def.comparator_offstate, param2 = node.param2 })
if offstate then
minetest.swap_node(pos, { name = offstate, param2 = node.param2 })
end
minetest.after(0.1, comparator_turnoff, {pos = pos, node = node}) minetest.after(0.1, comparator_turnoff, {pos = pos, node = node})
end end

View File

@ -1,5 +1,69 @@
local S = minetest.get_translator("mesecons_solarpanel") local S = minetest.get_translator("mesecons_solarpanel")
local function path_to_sunlight_exists(position, light_level)
local neighbours = {
{ x = 0, y = 0, z =-1 },
{ x = 0, y = 0, z = 1 },
{ x = 0, y =-1, z = 0 },
{ x = 0, y = 1, z = 0 },
{ x =-1, y = 0, z = 0 },
{ x = 1, y = 0, z = 0 },
}
for i=1, #neighbours do
local offset = neighbours[i]
local position_new = vector.add(
position,
offset
)
local light_level_new = minetest.get_node_light(
position_new,
nil
)
if 15 == light_level_new then
-- found the sunlight
return true
elseif light_level_new > light_level then
-- search where light is brighter
if path_to_sunlight_exists(
position_new,
light_level_new
) then
return true
end
end
end
end
local function sunlight_visible(position)
local light_level
-- Minetest 5.4.0+ can measure the daylight level at a position
if nil ~= minetest.get_natural_light then
light_level = minetest.get_natural_light(
position,
nil
)
if light_level >= 12 then
return true
end
else -- Minetest 5.3.0 or less can only measure the light level
local time = minetest.get_timeofday() * 24000
-- only check light level during day
if time > 6000 and time < 18000 then
light_level = minetest.get_node_light(
position,
nil
)
if light_level >= 12 then
return path_to_sunlight_exists(
position,
12
)
end
end
end
return false
end
local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 } local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 }
-- Daylight Sensor -- Daylight Sensor
@ -95,9 +159,7 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local light = minetest.get_node_light(pos, nil) if sunlight_visible(pos) then
if light >= 12 and minetest.get_timeofday() > 0.2 and minetest.get_timeofday() < 0.8 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
mesecon.receptor_on(pos, mesecon.rules.pplate) mesecon.receptor_on(pos, mesecon.rules.pplate)
end end
@ -110,9 +172,7 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local light = minetest.get_node_light(pos, nil) if not sunlight_visible(pos) then
if light < 12 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon.receptor_off(pos, mesecon.rules.pplate)
end end
@ -202,9 +262,7 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local light = minetest.get_node_light(pos, nil) if not sunlight_visible(pos) then
if light < 12 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2}) minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2})
mesecon.receptor_on(pos, mesecon.rules.pplate) mesecon.receptor_on(pos, mesecon.rules.pplate)
end end
@ -217,9 +275,7 @@ minetest.register_abm({
interval = 1, interval = 1,
chance = 1, chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local light = minetest.get_node_light(pos, nil) if sunlight_visible(pos) then
if light >= 12 and minetest.get_timeofday() > 0.8 and minetest.get_timeofday() < 0.2 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2}) minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon.receptor_off(pos, mesecon.rules.pplate)
end end

View File

@ -81,7 +81,7 @@ function mcl_beds.register_bed(name, def)
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, is_ground_content = false,
stack_max = 1, stack_max = 1,
groups = {handy=1, bed = 1, dig_by_piston=1, bouncy=66, fall_damage_add_percent=-50, deco_block = 1, flammable=-1}, groups = {handy=1, flammable = 3, bed = 1, dig_by_piston=1, bouncy=66, fall_damage_add_percent=-50, deco_block = 1, flammable=-1},
_mcl_hardness = 0.2, _mcl_hardness = 0.2,
_mcl_blast_resistance = 1, _mcl_blast_resistance = 1,
sounds = def.sounds or default_sounds, sounds = def.sounds or default_sounds,
@ -204,7 +204,7 @@ function mcl_beds.register_bed(name, def)
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, is_ground_content = false,
-- FIXME: Should be bouncy=66, but this would be a higher bounciness than slime blocks! -- FIXME: Should be bouncy=66, but this would be a higher bounciness than slime blocks!
groups = {handy = 1, flammable = -1, bed = 2, dig_by_piston=1, bouncy=33, fall_damage_add_percent=-50, not_in_creative_inventory = 1}, groups = {handy = 1, flammable = 3, bed = 2, dig_by_piston=1, bouncy=33, fall_damage_add_percent=-50, not_in_creative_inventory = 1},
_mcl_hardness = 0.2, _mcl_hardness = 0.2,
_mcl_blast_resistance = 1, _mcl_blast_resistance = 1,
sounds = def.sounds or default_sounds, sounds = def.sounds or default_sounds,

View File

@ -18,21 +18,19 @@ minetest.register_node("mcl_farming:beetroot_0", {
_doc_items_longdesc = S("Beetroot plants are plants which grow on farmland under sunlight in 4 stages. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature."), _doc_items_longdesc = S("Beetroot plants are plants which grow on farmland under sunlight in 4 stages. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature."),
_doc_items_entry_name = S("Premature Beetroot Plant"), _doc_items_entry_name = S("Premature Beetroot Plant"),
paramtype = "light", paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = "mcl_farming:beetroot_seeds", drop = "mcl_farming:beetroot_seeds",
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_beetroot_0.png") }, tiles = {"mcl_farming_beetroot_0.png"},
use_texture_alpha = "clip",
inventory_image = "mcl_farming_beetroot_0.png", inventory_image = "mcl_farming_beetroot_0.png",
wield_image = "mcl_farming_beetroot_0.png", wield_image = "mcl_farming_beetroot_0.png",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, -6/16, 0.5} {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
@ -44,21 +42,19 @@ minetest.register_node("mcl_farming:beetroot_1", {
description = S("Premature Beetroot Plant (Stage 2)"), description = S("Premature Beetroot Plant (Stage 2)"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
paramtype = "light", paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = "mcl_farming:beetroot_seeds", drop = "mcl_farming:beetroot_seeds",
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_beetroot_1.png") }, tiles = {"mcl_farming_beetroot_1.png"},
use_texture_alpha = "clip",
inventory_image = "mcl_farming_beetroot_1.png", inventory_image = "mcl_farming_beetroot_1.png",
wield_image = "mcl_farming_beetroot_1.png", wield_image = "mcl_farming_beetroot_1.png",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, -4/16, 0.5} {-0.5, -0.5, -0.5, 0.5, -3/16, 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
@ -70,21 +66,19 @@ minetest.register_node("mcl_farming:beetroot_2", {
description = S("Premature Beetroot Plant (Stage 3)"), description = S("Premature Beetroot Plant (Stage 3)"),
_doc_items_create_entry = false, _doc_items_create_entry = false,
paramtype = "light", paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = "mcl_farming:beetroot_seeds", drop = "mcl_farming:beetroot_seeds",
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_beetroot_2.png") }, tiles = {"mcl_farming_beetroot_2.png"},
use_texture_alpha = "clip",
inventory_image = "mcl_farming_beetroot_2.png", inventory_image = "mcl_farming_beetroot_2.png",
wield_image = "mcl_farming_beetroot_2.png", wield_image = "mcl_farming_beetroot_2.png",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, 1/16, 0.5} {-0.5, -0.5, -0.5, 0.5, 2/16, 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
@ -97,12 +91,11 @@ minetest.register_node("mcl_farming:beetroot", {
_doc_items_longdesc = S("A mature beetroot plant is a farming plant which is ready to be harvested for a beetroot and some beetroot seeds. It won't grow any further."), _doc_items_longdesc = S("A mature beetroot plant is a farming plant which is ready to be harvested for a beetroot and some beetroot seeds. It won't grow any further."),
_doc_items_create_entry = true, _doc_items_create_entry = true,
paramtype = "light", paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = { drop = {
--[[ drops 1 beetroot guaranteed. --[[ drops 1 beetroot guaranteed.
drops 1-4 beetroot seeds: drops 1-4 beetroot seeds:
@ -119,14 +112,13 @@ minetest.register_node("mcl_farming:beetroot", {
{ items = {"mcl_farming:beetroot_seeds 1"}, rarity = 4 }, { items = {"mcl_farming:beetroot_seeds 1"}, rarity = 4 },
}, },
}, },
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_beetroot_3.png") }, tiles = {"mcl_farming_beetroot_3.png"},
use_texture_alpha = "clip",
inventory_image = "mcl_farming_beetroot_3.png", inventory_image = "mcl_farming_beetroot_3.png",
wield_image = "mcl_farming_beetroot_3.png", wield_image = "mcl_farming_beetroot_3.png",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, 2/16, 0.5} {-0.5, -0.5, -0.5, 0.5, 3/16, 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,beetroot=4}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,beetroot=4},

View File

@ -28,20 +28,18 @@ for i=1, 7 do
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity paramtype2 = "meshoptions",
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = "mcl_farming:carrot_item", drop = "mcl_farming:carrot_item",
tiles = { mcl_farming:align_plantlike_nodebox_texture(texture) }, tiles = {texture},
use_texture_alpha = "clip",
inventory_image = texture, inventory_image = texture,
wield_image = texture, wield_image = texture,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, sel_height - 1/16, 0.5} {-0.5, -0.5, -0.5, 0.5, sel_height, 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
@ -55,13 +53,11 @@ minetest.register_node("mcl_farming:carrot", {
_doc_items_longdesc = S("Mature carrot plants are ready to be harvested for carrots. They won't grow any further."), _doc_items_longdesc = S("Mature carrot plants are ready to be harvested for carrots. They won't grow any further."),
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity paramtype2 = "meshoptions",
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(), tiles = {"farming_carrot_4.png"},
tiles = { mcl_farming:align_plantlike_nodebox_texture("farming_carrot_4.png") },
use_texture_alpha = "clip",
inventory_image = "farming_carrot_4.png", inventory_image = "farming_carrot_4.png",
wield_image = "farming_carrot_4.png", wield_image = "farming_carrot_4.png",
drop = { drop = {
@ -76,7 +72,7 @@ minetest.register_node("mcl_farming:carrot", {
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, 3/16, 0.5} {-0.5, -0.5, -0.5, 0.5, 4/16, 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},

View File

@ -27,73 +27,3 @@ dofile(minetest.get_modpath("mcl_farming").."/potatoes.lua")
-- ========= BEETROOT ========= -- ========= BEETROOT =========
dofile(minetest.get_modpath("mcl_farming").."/beetroot.lua") dofile(minetest.get_modpath("mcl_farming").."/beetroot.lua")
-- This function generates a row of plantlike and nodebox nodes whose
-- name starts with a given string, starting at a given position. It
-- places a given node below so that the rendering can be examined.
local function generate_plant_row(prefix, pos, below_node)
local i = 1
for node_name, node in pairs(minetest.registered_nodes) do
if (
1 == node_name:find(prefix) and
(
"plantlike" == node.drawtype or
"nodebox" == node.drawtype
)
) then
local node_pos = {
x = pos.x + i,
y = pos.y,
z = pos.z,
}
minetest.set_node(
node_pos,
{
name = node_name,
param2 = node.place_param2 or 0
}
)
local below_pos = {
x = node_pos.x,
y = node_pos.y - 1,
z = node_pos.z
}
minetest.set_node(
below_pos,
below_node
)
i = i + 1
end
end
end
minetest.register_chatcommand("generate_farming_plant_rows",{
description = "Generates rows of mcl_farming plant nodes on farming soil and glass",
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
local pos = player:get_pos()
local node_prefixes = {
"mcl_farming:beetroot",
"mcl_farming:carrot",
"mcl_farming:melon",
"mcl_farming:potato",
"mcl_farming:pumpkin",
"mcl_farming:wheat",
}
for i,node_prefix in ipairs(node_prefixes) do
generate_plant_row(
node_prefix,
pos,
{ name = "mcl_farming:soil" }
)
pos.z = pos.z + 2
generate_plant_row(
node_prefix,
pos,
{ name = "mcl_core:glass" }
)
pos.z = pos.z + 2
end
end
})

View File

@ -91,18 +91,16 @@ for s=1,7 do
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
paramtype = "light", paramtype = "light",
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_plus_nodebox(),
sunlight_propagates = true, sunlight_propagates = true,
drop = stem_drop, drop = stem_drop,
tiles = { mcl_farming:align_plantlike_nodebox_texture(texture) }, tiles = {texture},
use_texture_alpha = "clip",
wield_image = texture, wield_image = texture,
inventory_image = texture, inventory_image = texture,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.15, -9/16, -0.15, 0.15, -9/16+h, 0.15} {-0.15, -0.5, -0.15, 0.15, -0.5+h, 0.15}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, plant_melon_stem=s}, groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, plant_melon_stem=s},

View File

@ -6,13 +6,13 @@ for i=1, 7 do
local texture, selbox local texture, selbox
if i < 3 then if i < 3 then
texture = "mcl_farming_potatoes_stage_0.png" texture = "mcl_farming_potatoes_stage_0.png"
selbox = { -0.5, -9/16, -0.5, 0.5, -6/16, 0.5 } selbox = { -0.5, -0.5, -0.5, 0.5, -5/16, 0.5 }
elseif i < 5 then elseif i < 5 then
texture = "mcl_farming_potatoes_stage_1.png" texture = "mcl_farming_potatoes_stage_1.png"
selbox = { -0.5, -9/16, -0.5, 0.5, -3/16, 0.5 } selbox = { -0.5, -0.5, -0.5, 0.5, -2/16, 0.5 }
else else
texture = "mcl_farming_potatoes_stage_2.png" texture = "mcl_farming_potatoes_stage_2.png"
selbox = { -0.5, -9/16, -0.5, 0.5, 1/16, 0.5 } selbox = { -0.5, -0.5, -0.5, 0.5, 2/16, 0.5 }
end end
local create, name, longdesc local create, name, longdesc
@ -33,15 +33,13 @@ for i=1, 7 do
_doc_items_entry_name = name, _doc_items_entry_name = name,
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
paramtype = "light", paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = "mcl_farming:potato_item", drop = "mcl_farming:potato_item",
tiles = { mcl_farming:align_plantlike_nodebox_texture(texture) }, tiles = { texture },
use_texture_alpha = "clip",
inventory_image = texture, inventory_image = texture,
wield_image = texture, wield_image = texture,
selection_box = { selection_box = {
@ -59,14 +57,12 @@ minetest.register_node("mcl_farming:potato", {
description = S("Mature Potato Plant"), description = S("Mature Potato Plant"),
_doc_items_longdesc = S("Mature potato plants are ready to be harvested for potatoes. They won't grow any further."), _doc_items_longdesc = S("Mature potato plants are ready to be harvested for potatoes. They won't grow any further."),
paramtype = "light", paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true, sunlight_propagates = true,
-- keep place_param2 for plantlike drawtype compatiblity
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(), tiles = {"mcl_farming_potatoes_stage_3.png"},
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_potatoes_stage_3.png") },
use_texture_alpha = "clip",
wield_image = "mcl_farming_potatoes_stage_3.png", wield_image = "mcl_farming_potatoes_stage_3.png",
inventory_image = "mcl_farming_potatoes_stage_3.png", inventory_image = "mcl_farming_potatoes_stage_3.png",
drop = { drop = {
@ -81,7 +77,7 @@ minetest.register_node("mcl_farming:potato", {
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{ -0.5, -9/16, -0.5, 0.5, 0, 0.5 } { -0.5, -0.5, -0.5, 0.5, 1/16, 0.5 }
} }
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},

View File

@ -63,18 +63,16 @@ for s=1,7 do
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
paramtype = "light", paramtype = "light",
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_plus_nodebox(),
sunlight_propagates = true, sunlight_propagates = true,
drop = stem_drop, drop = stem_drop,
tiles = { mcl_farming:align_plantlike_nodebox_texture(texture) }, tiles = {texture},
use_texture_alpha = "clip",
inventory_image = texture, inventory_image = texture,
wield_image = texture, wield_image = texture,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.15, -9/16, -0.15, 0.15, -9/16+h, 0.15} {-0.15, -0.5, -0.15, 0.15, -0.5+h, 0.15}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,}, groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,},
@ -106,6 +104,7 @@ local pumpkin_base_def = {
_mcl_blast_resistance = 1, _mcl_blast_resistance = 1,
_mcl_hardness = 1, _mcl_hardness = 1,
} }
minetest.register_node("mcl_farming:pumpkin", pumpkin_base_def)
local pumpkin_face_base_def = table.copy(pumpkin_base_def) local pumpkin_face_base_def = table.copy(pumpkin_base_def)
pumpkin_face_base_def.description = S("Pumpkin") pumpkin_face_base_def.description = S("Pumpkin")
@ -116,11 +115,6 @@ pumpkin_face_base_def.groups.armor_head=1
pumpkin_face_base_def._mcl_armor_mob_range_factor = 0 pumpkin_face_base_def._mcl_armor_mob_range_factor = 0
pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman" pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman"
pumpkin_face_base_def.groups.non_combat_armor=1 pumpkin_face_base_def.groups.non_combat_armor=1
pumpkin_face_base_def.on_construct = function(pos)
-- Attempt to spawn iron golem or snow golem
mobs_mc.tools.check_iron_golem_summon(pos)
mobs_mc.tools.check_snow_golem_summon(pos)
end
if minetest.get_modpath("mcl_armor") then if minetest.get_modpath("mcl_armor") then
pumpkin_face_base_def.on_secondary_use = armor.on_armor_use pumpkin_face_base_def.on_secondary_use = armor.on_armor_use
end end
@ -129,11 +123,12 @@ end
mcl_farming:add_plant("plant_pumpkin_stem", "mcl_farming:pumpkintige_unconnect", {"mcl_farming:pumpkin_1", "mcl_farming:pumpkin_2", "mcl_farming:pumpkin_3", "mcl_farming:pumpkin_4", "mcl_farming:pumpkin_5", "mcl_farming:pumpkin_6", "mcl_farming:pumpkin_7"}, 30, 5) mcl_farming:add_plant("plant_pumpkin_stem", "mcl_farming:pumpkintige_unconnect", {"mcl_farming:pumpkin_1", "mcl_farming:pumpkin_2", "mcl_farming:pumpkin_3", "mcl_farming:pumpkin_4", "mcl_farming:pumpkin_5", "mcl_farming:pumpkin_6", "mcl_farming:pumpkin_7"}, 30, 5)
-- Register actual pumpkin, connected stems and stem-to-pumpkin growth -- Register actual pumpkin, connected stems and stem-to-pumpkin growth
mcl_farming:add_gourd("mcl_farming:pumpkintige_unconnect", "mcl_farming:pumpkintige_linked", "mcl_farming:pumpkintige_unconnect", stem_def, stem_drop, "mcl_farming:pumpkin", pumpkin_base_def, 30, 15, "mcl_farming_pumpkin_stem_connected.png^[colorize:#FFA800:127") mcl_farming:add_gourd("mcl_farming:pumpkintige_unconnect", "mcl_farming:pumpkintige_linked", "mcl_farming:pumpkintige_unconnect", stem_def, stem_drop, "mcl_farming:pumpkin_face", pumpkin_face_base_def, 30, 15, "mcl_farming_pumpkin_stem_connected.png^[colorize:#FFA800:127",
function(pos)
-- Steal function to properly disconnect a carved pumpkin -- Attempt to spawn iron golem or snow golem
pumpkin_face_base_def.after_destruct = minetest.registered_nodes["mcl_farming:pumpkin"].after_destruct mobs_mc.tools.check_iron_golem_summon(pos)
minetest.register_node("mcl_farming:pumpkin_face", pumpkin_face_base_def) mobs_mc.tools.check_snow_golem_summon(pos)
end)
-- Jack o'Lantern -- Jack o'Lantern
minetest.register_node("mcl_farming:pumpkin_face_light", { minetest.register_node("mcl_farming:pumpkin_face_light", {
@ -170,6 +165,11 @@ minetest.register_craft({
recipe = {{"mcl_farming:pumpkin"}} recipe = {{"mcl_farming:pumpkin"}}
}) })
minetest.register_craft({
output = "mcl_farming:pumpkin_seeds 4",
recipe = {{"mcl_farming:pumpkin_face"}}
})
minetest.register_craftitem("mcl_farming:pumpkin_pie", { minetest.register_craftitem("mcl_farming:pumpkin_pie", {
description = S("Pumpkin Pie"), description = S("Pumpkin Pie"),
_doc_items_longdesc = S("A pumpkin pie is a tasty food item which can be eaten."), _doc_items_longdesc = S("A pumpkin pie is a tasty food item which can be eaten."),
@ -187,6 +187,11 @@ minetest.register_craft({
output = "mcl_farming:pumpkin_pie", output = "mcl_farming:pumpkin_pie",
recipe = {"mcl_farming:pumpkin", "mcl_core:sugar", "mcl_throwing:egg"}, recipe = {"mcl_farming:pumpkin", "mcl_core:sugar", "mcl_throwing:egg"},
}) })
minetest.register_craft({
type = "shapeless",
output = "mcl_farming:pumpkin_pie",
recipe = {"mcl_farming:pumpkin_face", "mcl_core:sugar", "mcl_throwing:egg"},
})
if minetest.get_modpath("doc") then if minetest.get_modpath("doc") then

View File

@ -178,7 +178,7 @@ end
- stem_def: Partial node definition of the fully-grown unconnected stem node. Many fields are already defined. You need to add `tiles` and `description` at minimum. Don't define on_construct without good reason - stem_def: Partial node definition of the fully-grown unconnected stem node. Many fields are already defined. You need to add `tiles` and `description` at minimum. Don't define on_construct without good reason
- stem_drop: Drop probability table for all stem - stem_drop: Drop probability table for all stem
- gourd_itemstring: Desired itemstring of the full gourd node - gourd_itemstring: Desired itemstring of the full gourd node
- gourd_def: (almost) full definition of the gourd node. This function will add on_construct and after_destruct to the definition for unconnecting any connected stems - gourd_def: (almost) full definition of the gourd node. This function will add on_construct and after_dig_node to the definition for unconnecting any connected stems
- grow_interval: Will attempt to grow a gourd periodically at this interval in seconds - grow_interval: Will attempt to grow a gourd periodically at this interval in seconds
- grow_chance: Chance of 1/grow_chance to grow a gourd next to the full unconnected stem after grow_interval has passed. Must be a natural number - grow_chance: Chance of 1/grow_chance to grow a gourd next to the full unconnected stem after grow_interval has passed. Must be a natural number
- connected_stem_texture: Texture of the connected stem - connected_stem_texture: Texture of the connected stem
@ -228,8 +228,8 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
end end
-- Register gourd -- Register gourd
if not gourd_def.after_destruct then if not gourd_def.after_dig_node then
gourd_def.after_destruct = function(blockpos, oldnode) gourd_def.after_dig_node = function(blockpos, oldnode, oldmetadata, user)
-- Disconnect any connected stems, turning them back to normal stems -- Disconnect any connected stems, turning them back to normal stems
for n=1, #neighbors do for n=1, #neighbors do
local offset = neighbors[n] local offset = neighbors[n]
@ -265,7 +265,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
stem_def.selection_box = { stem_def.selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.15, -9/16, -0.15, 0.15, 7/16, 0.15} {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}
}, },
} }
end end
@ -273,20 +273,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
stem_def.paramtype = "light" stem_def.paramtype = "light"
end end
if not stem_def.drawtype then if not stem_def.drawtype then
stem_def.drawtype = "nodebox" stem_def.drawtype = "plantlike"
end
if not stem_def.node_box then
stem_def.node_box = mcl_farming:get_plantlike_plus_nodebox()
end
if stem_def.tiles then
for i=1,#stem_def.tiles do
stem_def.tiles[i] = mcl_farming:align_plantlike_nodebox_texture(
stem_def.tiles[i]
)
end
end
if not stem_def.use_texture_alpha then
stem_def.use_texture_alpha = "clip"
end end
if stem_def.walkable == nil then if stem_def.walkable == nil then
stem_def.walkable = false stem_def.walkable = false
@ -313,9 +300,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
minetest.register_node(stem_itemstring, stem_def) minetest.register_node(stem_itemstring, stem_def)
-- Register connected stems -- Register connected stems
local connected_stem_texture = mcl_farming:align_plantlike_nodebox_texture(
connected_stem_texture
)
local connected_stem_tiles = { local connected_stem_tiles = {
{ "blank.png", --top { "blank.png", --top
"blank.png", -- bottom "blank.png", -- bottom
@ -347,16 +332,16 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s
} }
} }
local connected_stem_nodebox = { local connected_stem_nodebox = {
{-0.5, -9/16, 0, 0.5, 7/16, 0}, {-0.5, -0.5, 0, 0.5, 0.5, 0},
{-0.5, -9/16, 0, 0.5, 7/16, 0}, {-0.5, -0.5, 0, 0.5, 0.5, 0},
{0, -9/16, -0.5, 0, 7/16, 0.5}, {0, -0.5, -0.5, 0, 0.5, 0.5},
{0, -9/16, -0.5, 0, 7/16, 0.5}, {0, -0.5, -0.5, 0, 0.5, 0.5},
} }
local connected_stem_selectionbox = { local connected_stem_selectionbox = {
{-0.1, -9/16, -0.1, 0.5, 0.2 - 1/16, 0.1}, {-0.1, -0.5, -0.1, 0.5, 0.2, 0.1},
{-0.5, -9/16, -0.1, 0.1, 0.2 - 1/16, 0.1}, {-0.5, -0.5, -0.1, 0.1, 0.2, 0.1},
{-0.1, -9/16, -0.1, 0.1, 0.2 - 1/16, 0.5}, {-0.1, -0.5, -0.1, 0.1, 0.2, 0.5},
{-0.1, -9/16, -0.5, 0.1, 0.2 - 1/16, 0.1}, {-0.1, -0.5, -0.5, 0.1, 0.2, 0.1},
} }
for i=1, 4 do for i=1, 4 do
@ -484,40 +469,3 @@ minetest.register_lbm({
mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed) mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed)
end, end,
}) })
-- This function returns a nodebox that imitates a plantlike plus (+)
-- drawtype, but is shifted 1/16 lower, into the empty space above
-- farming soil. The regular plantlike drawtype can not do this.
function mcl_farming:get_plantlike_plus_nodebox()
return {
type = "fixed",
fixed = {
{ 0, -9/16, -0.15, 0, 7/16, 0.15 },
{ -0.15, -9/16, 0, 0.15, 7/16, 0 }
}
}
end
-- This function returns a nodebox that imitates a plantlike grid (#)
-- drawtype, but is shifted 1/16 lower, into the empty space above
-- farming soil. The regular plantlike drawtype can not do this.
function mcl_farming:get_plantlike_grid_nodebox()
return {
type = "fixed",
fixed = {
{ 4/16, -9/16, -8/16, 4/16, 7/16, 8/16},
{-4/16, -9/16, -8/16, -4/16, 7/16, 8/16},
{-8/16, -9/16, -4/16, 8/16, 7/16, -4/16},
{-8/16, -9/16, 4/16, 8/16, 7/16, 4/16},
}
}
end
-- This function takes a texture and returns a modified texture where
-- the bottom row is at the top, assuming 16px × 16px textures. This
-- is used to align textures to a “plantlike” nodebox shifted 1/16
-- below its own node into the empty space above farming soil.
function mcl_farming:align_plantlike_nodebox_texture(texture)
local texture = texture:gsub("%^", "\\%^"):gsub(":", "\\:")
return "[combine:16x16:0,-15=" .. texture .. ":0,1=" .. texture
end

View File

@ -39,21 +39,19 @@ for i=1,7 do
_doc_items_entry_name = name, _doc_items_entry_name = name,
_doc_items_longdesc = longdesc, _doc_items_longdesc = longdesc,
paramtype = "light", paramtype = "light",
-- keep place_param2 for plantlike drawtype compatiblity paramtype2 = "meshoptions",
place_param2 = 3, place_param2 = 3,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(),
drop = "mcl_farming:wheat_seeds", drop = "mcl_farming:wheat_seeds",
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_wheat_stage_"..(i-1)..".png") }, tiles = {"mcl_farming_wheat_stage_"..(i-1)..".png"},
use_texture_alpha = "clip",
inventory_image = "mcl_farming_wheat_stage_"..(i-1)..".png", inventory_image = "mcl_farming_wheat_stage_"..(i-1)..".png",
wield_image = "mcl_farming_wheat_stage_"..(i-1)..".png", wield_image = "mcl_farming_wheat_stage_"..(i-1)..".png",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.5, -9/16, -0.5, 0.5, sel_heights[i] - 1/16, 0.5} {-0.5, -0.5, -0.5, 0.5, sel_heights[i], 0.5}
}, },
}, },
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1}, groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1},
@ -67,21 +65,13 @@ minetest.register_node("mcl_farming:wheat", {
_doc_items_longdesc = S("Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further."), _doc_items_longdesc = S("Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further."),
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
-- keep place_param2 for plantlike drawtype compatiblity paramtype2 = "meshoptions",
place_param2 = 3, place_param2 = 3,
walkable = false, walkable = false,
drawtype = "nodebox", drawtype = "plantlike",
node_box = mcl_farming:get_plantlike_grid_nodebox(), tiles = {"mcl_farming_wheat_stage_7.png"},
tiles = { mcl_farming:align_plantlike_nodebox_texture("mcl_farming_wheat_stage_7.png") },
use_texture_alpha = "clip",
inventory_image = "mcl_farming_wheat_stage_7.png", inventory_image = "mcl_farming_wheat_stage_7.png",
wield_image = "mcl_farming_wheat_stage_7.png", wield_image = "mcl_farming_wheat_stage_7.png",
selection_box = {
type = "fixed",
fixed = {
{ -0.5, -9/16, -0.5, 0.5, 7/16, 0.5 }
}
},
drop = { drop = {
max_items = 4, max_items = 4,
items = { items = {

View File

@ -5,6 +5,29 @@ mcl_fire = {}
local S = minetest.get_translator("mcl_fire") local S = minetest.get_translator("mcl_fire")
local N = function(s) return s end local N = function(s) return s end
-- inverse pyramid pattern above lava source, floor 1 of 2:
local lava_fire=
{
{ x =-1, y = 1, z =-1},
{ x =-1, y = 1, z = 0},
{ x =-1, y = 1, z = 1},
{ x = 0, y = 1, z =-1},
{ x = 0, y = 1, z = 0},
{ x = 0, y = 1, z = 1},
{ x = 1, y = 1, z =-1},
{ x = 1, y = 1, z = 0},
{ x = 1, y = 1, z = 1}
}
local alldirs=
{
{ x =-1, y = 0, z = 0},
{ x = 1, y = 0, z = 0},
{ x = 0, y =-1, z = 0},
{ x = 0, y = 1, z = 0},
{ x = 0, y = 0, z =-1},
{ x = 0, y = 0, z = 1}
}
local spawn_smoke = function(pos) local spawn_smoke = function(pos)
mcl_particles.add_node_particlespawner(pos, { mcl_particles.add_node_particlespawner(pos, {
amount = 0.1, amount = 0.1,
@ -27,34 +50,6 @@ local spawn_smoke = function(pos)
}, "high") }, "high")
end end
local adjacents = {
{ x =-1, y = 0, z = 0 },
{ x = 1, y = 0, z = 0 },
{ x = 0, y = 1, z = 0 },
{ x = 0, y =-1, z = 0 },
{ x = 0, y = 0, z =-1 },
{ x = 0, y = 0, z = 1 },
}
math.randomseed(os.time())
local function shuffle_table(t)
for i = #t, 1, -1 do
local r = math.random(i)
t[i], t[r] = t[r], t[i]
end
end
shuffle_table(adjacents)
local function has_flammable(pos)
for k,v in pairs(adjacents) do
local p=vector.add(pos,v)
local n=minetest.get_node_or_nil(p)
if n and minetest.get_item_group(n.name, "flammable") ~= 0 then
return p
end
end
end
-- --
-- Items -- Items
-- --
@ -90,6 +85,10 @@ local fire_death_messages = {
N("@1 died in a fire."), N("@1 died in a fire."),
} }
local fire_timer = function(pos)
minetest.get_node_timer(pos):start(math.random(3, 7))
end
local spawn_fire = function(pos, age) local spawn_fire = function(pos, age)
minetest.set_node(pos, {name="mcl_fire:fire", param2 = age}) minetest.set_node(pos, {name="mcl_fire:fire", param2 = age})
minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z})
@ -125,6 +124,82 @@ minetest.register_node("mcl_fire:fire", {
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
end end
end, end,
on_timer = function(pos)
local node = minetest.get_node(pos)
-- Age is a number from 0 to 15 and is increased every timer step.
-- "old" fire is more likely to be extinguished
local age = node.param2
local flammables = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"})
local below = minetest.get_node({x=pos.x, y=pos.z-1, z=pos.z})
local below_is_flammable = minetest.get_item_group(below.name, "flammable") > 0
-- Extinguish fire
if (not fire_enabled) and (math.random(1,3) == 1) then
minetest.remove_node(pos)
return
end
if age == 15 and not below_is_flammable then
minetest.remove_node(pos)
return
elseif age > 3 and #flammables == 0 and not below_is_flammable and math.random(1,4) == 1 then
minetest.remove_node(pos)
return
end
local age_add = 1
-- If fire spread is disabled, we have to skip the "destructive" code
if (not fire_enabled) then
if age + age_add <= 15 then
node.param2 = age + age_add
minetest.set_node(pos, node)
end
-- Restart timer
fire_timer(pos)
return
end
-- Spawn fire to nearby flammable nodes
local is_next_to_flammable = minetest.find_node_near(pos, 2, {"group:flammable"}) ~= nil
if is_next_to_flammable and math.random(1,2) == 1 then
-- The fire we spawn copies the age of this fire.
-- This prevents fire from spreading infinitely far as the fire fire dies off
-- quicker the further it has spreaded.
local age_next = math.min(15, age + math.random(0, 1))
-- Select random type of fire spread
local burntype = math.random(1,2)
if burntype == 1 then
-- Spawn fire in air
local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"})
while #nodes > 0 do
local r = math.random(1, #nodes)
if minetest.find_node_near(nodes[r], 1, {"group:flammable"}) then
spawn_fire(nodes[r], age_next)
break
else
table.remove(nodes, r)
end
end
else
-- Burn flammable block
local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"})
if #nodes > 0 then
local r = math.random(1, #nodes)
local nn = minetest.get_node(nodes[r]).name
local ndef = minetest.registered_nodes[nn]
local fgroup = minetest.get_item_group(nn, "flammable")
if ndef and ndef._on_burn then
ndef._on_burn(nodes[r])
elseif fgroup ~= -1 then
spawn_fire(nodes[r], age_next)
end
end
end
end
-- Regular age increase
if age + age_add <= 15 then
node.param2 = age + age_add
minetest.set_node(pos, node)
end
-- Restart timer
fire_timer(pos)
end,
drop = "", drop = "",
sounds = {}, sounds = {},
-- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer -- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer
@ -134,12 +209,14 @@ minetest.register_node("mcl_fire:fire", {
local dim = mcl_worlds.pos_to_dimension(bpos) local dim = mcl_worlds.pos_to_dimension(bpos)
if under == "mcl_nether:magma" or under == "mcl_nether:netherrack" or (under == "mcl_core:bedrock" and dim == "end") then if under == "mcl_nether:magma" or under == "mcl_nether:netherrack" or (under == "mcl_core:bedrock" and dim == "end") then
minetest.set_node(pos, {name="mcl_fire:eternal_fire"}) minetest.swap_node(pos, {name = "mcl_fire:eternal_fire"})
end end
if minetest.get_modpath("mcl_portals") then if minetest.get_modpath("mcl_portals") then
mcl_portals.light_nether_portal(pos) mcl_portals.light_nether_portal(pos)
end end
fire_timer(pos)
spawn_smoke(pos) spawn_smoke(pos)
end, end,
on_destruct = function(pos) on_destruct = function(pos)
@ -178,7 +255,29 @@ minetest.register_node("mcl_fire:eternal_fire", {
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
end end
end, end,
on_timer = function(pos)
if fire_enabled then
local airs = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"})
while #airs > 0 do
local r = math.random(1, #airs)
if minetest.find_node_near(airs[r], 1, {"group:flammable"}) then
local node = minetest.get_node(airs[r])
local age = node.param2
local age_next = math.min(15, age + math.random(0, 1))
spawn_fire(airs[r], age_next)
break
else
table.remove(airs, r)
end
end
end
-- Restart timer
fire_timer(pos)
end,
-- Start burning timer and light Nether portal (if possible)
on_construct = function(pos) on_construct = function(pos)
fire_timer(pos)
if minetest.get_modpath("mcl_portals") then if minetest.get_modpath("mcl_portals") then
mcl_portals.light_nether_portal(pos) mcl_portals.light_nether_portal(pos)
end end
@ -303,6 +402,114 @@ if flame_sound then
end end
--
-- ABMs
--
-- Extinguish all flames quickly with water and such
minetest.register_abm({
label = "Extinguish fire",
nodenames = {"mcl_fire:fire", "mcl_fire:eternal_fire"},
neighbors = {"group:puts_out_fire"},
interval = 3,
chance = 1,
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
minetest.remove_node(pos)
minetest.sound_play("fire_extinguish_flame",
{pos = pos, max_hear_distance = 16, gain = 0.15}, true)
end,
})
-- Enable the following ABMs according to 'enable fire' setting
local function has_flammable(pos)
local npos, node
for n, v in ipairs(alldirs) do
npos = vector.add(pos, v)
node = minetest.get_node_or_nil(npos)
if node and node.name and minetest.get_item_group(node.name, "flammable") ~= 0 then
return npos
end
end
return false
end
if not fire_enabled then
-- Occasionally remove fire if fire disabled
-- NOTE: Fire is normally extinguished in timer function
minetest.register_abm({
label = "Remove disabled fire",
nodenames = {"mcl_fire:fire"},
interval = 10,
chance = 10,
catch_up = false,
action = minetest.remove_node,
})
else -- Fire enabled
-- Set fire to air nodes
minetest.register_abm({
label = "Ignite fire by lava",
nodenames = {"group:lava"},
neighbors = {"air"},
interval = 7,
chance = 3,
catch_up = false,
action = function(pos)
local i, dir, target, node, i2, f
i = math.random(1,9)
dir = lava_fire[i]
target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}
node = minetest.get_node(target)
if not node or node.name ~= "air" then
i = ((i + math.random(0,7)) % 9) + 1
dir = lava_fire[i]
target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z}
node = minetest.get_node(target)
if not node or node.name ~= "air" then
return
end
end
i2 = math.random(1,15)
if i2 < 10 then
local dir2, target2, node2
dir2 = lava_fire[i2]
target2 = {x=target.x+dir2.x, y=target.y+dir2.y, z=target.z+dir2.z}
node2 = minetest.get_node(target2)
if node2 and node2.name == "air" then
f = has_flammable(target2)
if f then
minetest.after(1, spawn_fire, {x=target2.x, y=target2.y, z=target2.z})
minetest.add_particle({
pos = vector.new({x=pos.x, y=pos.y+0.5, z=pos.z}),
velocity={x=f.x-pos.x, y=math.max(f.y-pos.y,0.7), z=f.z-pos.z},
expirationtime=1, size=1.5, collisiondetection=false,
glow=minetest.LIGHT_MAX, texture="mcl_particles_flame.png"
})
return
end
end
end
f = has_flammable(target)
if f then
minetest.after(1, spawn_fire, {x=target.x, y=target.y, z=target.z})
minetest.add_particle({
pos = vector.new({x=pos.x, y=pos.y+0.5, z=pos.z}),
velocity={x=f.x-pos.x, y=math.max(f.y-pos.y,0.25), z=f.z-pos.z},
expirationtime=1, size=1, collisiondetection=false,
glow=minetest.LIGHT_MAX, texture="mcl_particles_flame.png"
})
end
end,
})
end
-- Set pointed_thing on (normal) fire. -- Set pointed_thing on (normal) fire.
-- * pointed_thing: Pointed thing to ignite -- * pointed_thing: Pointed thing to ignite
-- * player: Player who sets fire or nil if nobody -- * player: Player who sets fire or nil if nobody
@ -328,144 +535,6 @@ mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire)
end end
end end
--
-- ABMs
--
-- Extinguish all flames quickly with water and such
minetest.register_abm({
label = "Extinguish fire",
nodenames = {"mcl_fire:fire", "mcl_fire:eternal_fire"},
neighbors = {"group:puts_out_fire"},
interval = 3,
chance = 1,
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
minetest.remove_node(pos)
minetest.sound_play("fire_extinguish_flame",
{pos = pos, max_hear_distance = 16, gain = 0.15}, true)
end,
})
-- Enable the following ABMs according to 'enable fire' setting
-- [...]a fire that is not adjacent to any flammable block does not spread, even to another flammable block within the normal range.
-- https://minecraft.fandom.com/wiki/Fire#Spread
local function check_aircube(p1,p2)
local nds=minetest.find_nodes_in_area(p1,p2,{"air"})
shuffle_table(nds)
for k,v in pairs(nds) do
if has_flammable(v) then return v end
end
end
-- [...] a fire block can turn any air block that is adjacent to a flammable block into a fire block. This can happen at a distance of up to one block downward, one block sideways (including diagonals), and four blocks upward of the original fire block (not the block the fire is on/next to).
local function get_ignitable(pos)
return check_aircube(vector.add(pos,vector.new(-1,-1,-1)),vector.add(pos,vector.new(1,4,1)))
end
-- Fire spreads from a still lava block similarly: any air block one above and up to one block sideways (including diagonals) or two above and two blocks sideways (including diagonals) that is adjacent to a flammable block may be turned into a fire block.
local function get_ignitable_by_lava(pos)
return check_aircube(vector.add(pos,vector.new(-1,1,-1)),vector.add(pos,vector.new(1,1,1))) or check_aircube(vector.add(pos,vector.new(-2,2,-2)),vector.add(pos,vector.new(2,2,2))) or nil
end
if not fire_enabled then
-- Occasionally remove fire if fire disabled
-- NOTE: Fire is normally extinguished in timer function
minetest.register_abm({
label = "Remove disabled fire",
nodenames = {"mcl_fire:fire"},
interval = 10,
chance = 10,
catch_up = false,
action = minetest.remove_node,
})
else -- Fire enabled
-- Fire Spread
minetest.register_abm({
label = "Ignite flame",
nodenames ={"mcl_fire:fire","mcl_fire:eternal_fire"},
interval = 7,
chance = 12,
catch_up = false,
action = function(pos)
local p = get_ignitable(pos)
if p then
spawn_fire(p)
shuffle_table(adjacents)
end
end
})
--lava fire spread
minetest.register_abm({
label = "Ignite fire by lava",
nodenames = {"mcl_core:lava_source","mcl_nether:nether_lava_source"},
neighbors = {"air","group:flammable"},
interval = 7,
chance = 3,
catch_up = false,
action = function(pos)
local p=get_ignitable_by_lava(pos)
if p then
spawn_fire(p)
end
end,
})
minetest.register_abm({
label = "Remove fires",
nodenames = {"mcl_fire:fire"},
interval = 7,
chance = 3,
catch_up = false,
action = function(pos)
local p=has_flammable(pos)
if p then
local n=minetest.get_node_or_nil(p)
if n and minetest.get_item_group(n.name, "flammable") < 1 then
minetest.remove_node(pos)
end
else
minetest.remove_node(pos)
end
end,
})
-- Remove flammable nodes around basic flame
minetest.register_abm({
label = "Remove flammable nodes",
nodenames = {"mcl_fire:fire","mcl_fire:eternal_fire"},
neighbors = {"group:flammable"},
interval = 5,
chance = 18,
catch_up = false,
action = function(pos)
local p = has_flammable(pos)
if not p then
return
end
local nn = minetest.get_node(p).name
local def = minetest.registered_nodes[nn]
local fgroup = minetest.get_item_group(nn, "flammable")
if def and def._on_burn then
def._on_burn(p)
elseif fgroup ~= -1 then
spawn_fire(p)
minetest.check_for_falling(p)
end
end
})
end
minetest.register_lbm({ minetest.register_lbm({
label = "Smoke particles from fire", label = "Smoke particles from fire",
name = "mcl_fire:smoke", name = "mcl_fire:smoke",

View File

@ -1,5 +1,4 @@
local S = minetest.get_translator("mcl_tnt") local S = minetest.get_translator("mcl_tnt")
local tnt_drop_rate = tonumber(minetest.settings:get("mcl_tnt_drop_rate") or 1.0)
local tnt_griefing = minetest.settings:get_bool("mcl_tnt_griefing", true) local tnt_griefing = minetest.settings:get_bool("mcl_tnt_griefing", true)
local mod_death_messages = minetest.get_modpath("mcl_death_messages") local mod_death_messages = minetest.get_modpath("mcl_death_messages")
@ -181,7 +180,7 @@ function TNT:on_step(dtime)
self.blinkstatus = not self.blinkstatus self.blinkstatus = not self.blinkstatus
end end
if self.timer > tnt.BOOMTIMER then if self.timer > tnt.BOOMTIMER then
mcl_explosions.explode(self.object:get_pos(), 4, { drop_chance = tnt_drop_rate }, self.object) mcl_explosions.explode(self.object:get_pos(), 4, {}, self.object)
self.object:remove() self.object:remove()
end end
end end

View File

@ -232,10 +232,10 @@ if minetest.get_modpath("mcl_farming") then
local wear = mcl_autogroup.get_wear(toolname, "shearsy") local wear = mcl_autogroup.get_wear(toolname, "shearsy")
itemstack:add_wear(wear) itemstack:add_wear(wear)
end end
minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pointed_thing.above}, true) minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true)
local dir = vector.subtract(pointed_thing.under, pointed_thing.above) local dir = vector.subtract(pointed_thing.under, pointed_thing.above)
local param2 = minetest.dir_to_facedir(dir) local param2 = minetest.dir_to_facedir(dir)
minetest.set_node(pointed_thing.under, {name="mcl_farming:pumpkin_face", param2 = param2}) minetest.swap_node(pointed_thing.under, {name="mcl_farming:pumpkin_face", param2 = param2})
minetest.add_item(pointed_thing.above, "mcl_farming:pumpkin_seeds 4") minetest.add_item(pointed_thing.above, "mcl_farming:pumpkin_seeds 4")
end end
return itemstack return itemstack

View File

@ -1 +0,0 @@
name = screwdriver

View File

@ -3532,7 +3532,7 @@ local function register_decorations()
-- Pumpkin -- Pumpkin
minetest.register_decoration({ minetest.register_decoration({
deco_type = "simple", deco_type = "simple",
decoration = "mcl_farming:pumpkin", decoration = "mcl_farming:pumpkin_face",
param2 = 0, param2 = 0,
param2_max = 3, param2_max = 3,
place_on = {"group:grass_block_no_snow"}, place_on = {"group:grass_block_no_snow"},

View File

@ -868,7 +868,7 @@ local function register_mgv6_decorations()
-- Pumpkin -- Pumpkin
minetest.register_decoration({ minetest.register_decoration({
deco_type = "simple", deco_type = "simple",
decoration = "mcl_farming:pumpkin", decoration = "mcl_farming:pumpkin_face",
param2 = 0, param2 = 0,
param2_max = 3, param2_max = 3,
place_on = {"group:grass_block_no_snow"}, place_on = {"group:grass_block_no_snow"},

View File

@ -532,24 +532,14 @@ local function dir_to_rotation(dir)
return "0" return "0"
end end
mcl_structures.generate_test_structure_comparator = function(pos, rotation, pr)
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_test_structure_comparator.mts"
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, nil, pr)
end
mcl_structures.generate_test_structure_fireproof = function(pos, rotation, pr) mcl_structures.generate_test_structure_fireproof = function(pos, rotation, pr)
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_test_structure_fireproof.mts" local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_test_structure_fireproof.mts"
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, nil, pr) mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, nil, pr)
end end
mcl_structures.generate_test_structure_tnt = function(pos, rotation, pr)
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_test_structure_tnt.mts"
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, nil, pr)
end
-- Debug command -- Debug command
minetest.register_chatcommand("spawnstruct", { minetest.register_chatcommand("spawnstruct", {
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | test_structure_comparator | test_structure_fireproof | test_structure_tnt", params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | test_structure_fireproof",
description = S("Generate a pre-defined structure near your position."), description = S("Generate a pre-defined structure near your position."),
privs = {debug = true}, privs = {debug = true},
func = function(name, param) func = function(name, param)
@ -583,12 +573,8 @@ minetest.register_chatcommand("spawnstruct", {
mcl_structures.generate_end_exit_portal(pos, rot, pr) mcl_structures.generate_end_exit_portal(pos, rot, pr)
elseif param == "end_portal_shrine" then elseif param == "end_portal_shrine" then
mcl_structures.generate_end_portal_shrine(pos, rot, pr) mcl_structures.generate_end_portal_shrine(pos, rot, pr)
elseif param == "test_structure_comparator" then
mcl_structures.generate_test_structure_comparator(pos, rot, pr)
elseif param == "test_structure_fireproof" then elseif param == "test_structure_fireproof" then
mcl_structures.generate_test_structure_fireproof(pos, rot, pr) mcl_structures.generate_test_structure_fireproof(pos, rot, pr)
elseif param == "test_structure_tnt" then
mcl_structures.generate_test_structure_tnt(pos, rot, pr)
elseif param == "" then elseif param == "" then
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.") message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
errord = true errord = true

View File

@ -1 +0,0 @@
name = mcl_engine_workarounds

View File

@ -1 +0,0 @@
name = mcl_selftests

View File

@ -1 +0,0 @@
name = mcl_player

View File

@ -24,9 +24,6 @@ mcl_doWeatherCycle (Change weather) bool true
# Note that blocks never have drops when in Creative Mode. # Note that blocks never have drops when in Creative Mode.
mcl_doTileDrops (Blocks have drops) bool true mcl_doTileDrops (Blocks have drops) bool true
# Chance of a node destroyed by a TNT explosion to be dropped as an item
mcl_tnt_drop_rate (TNT drop rate) float 1.0 0.0 1.0
# If enabled, TNT explosions destroy blocks. # If enabled, TNT explosions destroy blocks.
mcl_tnt_griefing (TNT destroys blocks) bool true mcl_tnt_griefing (TNT destroys blocks) bool true
@ -105,9 +102,6 @@ animated_chests (Animated chests) bool true
# Whether to preview the player in inventory in 3D (requires Minetest 5.4) # Whether to preview the player in inventory in 3D (requires Minetest 5.4)
3d_player_preview (3D Player preview) bool true 3d_player_preview (3D Player preview) bool true
# How long a temporary message will be shown in the HUD
mcl_tmp_message_hud_hide_timeout (Temporary message display duration) int 10 0 60
[Experimental] [Experimental]
# Whether ice is translucent. If disabled, ice is fully opaque. # Whether ice is translucent. If disabled, ice is fully opaque.
# #