mirror of
https://github.com/minetest-mods/nether.git
synced 2025-06-30 23:40:45 +02:00
Add the Mantle
Adds a magma oceans region to the nether outside the existing nether caverns, which can be reached via tunnels. Other misc changes: * chatcomment nether_whereami, a debug aid for knowing which perlin-noise region you are in * Nether ores no longer obtainable on the ceiling * Move crafts into crafts.lua * Add steam to lava cooling, and play bubbling lava upon death by lava * Add cracked netherbrick a decorative node which can only be obtained from dungeons or structures I encourage someone to improve or replace the cracked netherbrick texture. For copyright purposes it's currently a derivative work (by me, 2020) from nether_brick.png, which is licensed under CC BY-SA 3.0 by PilzAdam, so it can fall under the "All other media" PilzAdam's credit in readme.md rather than need its own entry.
This commit is contained in:
396
nodes.lua
396
nodes.lua
@ -75,6 +75,15 @@ minetest.register_node("nether:rack", {
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
-- Deep Netherrack, found in the mantle / central magma layers
|
||||
minetest.register_node("nether:rack_deep", {
|
||||
description = S("Deep-Netherrack"),
|
||||
tiles = {"nether_rack_deep.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 3, level = 2},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("nether:sand", {
|
||||
description = S("Nethersand"),
|
||||
tiles = {"nether_sand.png"},
|
||||
@ -95,6 +104,17 @@ minetest.register_node("nether:glowstone", {
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
-- Deep glowstone, found in the mantle / central magma layers
|
||||
minetest.register_node("nether:glowstone_deep", {
|
||||
description = S("Deep-Glowstone"),
|
||||
tiles = {"nether_glowstone_deep.png"},
|
||||
is_ground_content = true,
|
||||
light_source = 14,
|
||||
paramtype = "light",
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("nether:brick", {
|
||||
description = S("Nether Brick"),
|
||||
tiles = {"nether_brick.png"},
|
||||
@ -111,6 +131,15 @@ minetest.register_node("nether:brick_compressed", {
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
-- A decorative node which can only be obtained from dungeons or structures
|
||||
minetest.register_node("nether:brick_cracked", {
|
||||
description = S("Cracked Nether Brick"),
|
||||
tiles = {"nether_brick_cracked.png"},
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 2, level = 2},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
local fence_texture =
|
||||
"default_fence_overlay.png^nether_brick.png^default_fence_overlay.png^[makealpha:255,126,126"
|
||||
|
||||
@ -169,6 +198,345 @@ if minetest.get_modpath("moreblocks") then
|
||||
end
|
||||
|
||||
|
||||
-- Mantle nodes
|
||||
|
||||
-- Nether basalt is intended as a valuable material and possible portalstone - an alternative to
|
||||
-- obsidian that's available for other mods to use.
|
||||
-- It cannot be found in the regions of the nether where Nether portals link to, so requires a journey to obtain.
|
||||
minetest.register_node("nether:basalt", {
|
||||
description = S("Blue Basalt"),
|
||||
tiles = {
|
||||
"nether_basalt.png",
|
||||
"nether_basalt.png",
|
||||
"nether_basalt_side.png",
|
||||
"nether_basalt_side.png",
|
||||
"nether_basalt_side.png",
|
||||
"nether_basalt_side.png"
|
||||
},
|
||||
is_ground_content = true,
|
||||
groups = {cracky = 1, level = 3}, -- set proper digging times and uses, and maybe explosion immune if api handles that
|
||||
on_blast = function() --[[blast proof]] end,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
-- Potentially a portalstone, but will also be a stepping stone between basalt
|
||||
-- and chiseled basalt.
|
||||
-- It can only be introduced by the biomes-based mapgen, since it requires the
|
||||
-- MT 5.0 world-align texture features.
|
||||
minetest.register_node("nether:basalt_hewn", {
|
||||
description = S("Hewn Basalt"),
|
||||
tiles = {{
|
||||
name = "nether_basalt_hewn.png",
|
||||
align_style = "world",
|
||||
scale = 2
|
||||
}},
|
||||
inventory_image = minetest.inventorycube(
|
||||
"nether_basalt_hewn.png^[sheet:2x2:0,0",
|
||||
"nether_basalt_hewn.png^[sheet:2x2:0,1",
|
||||
"nether_basalt_hewn.png^[sheet:2x2:1,1"
|
||||
),
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 1, level = 2},
|
||||
on_blast = function() --[[blast proof]] end,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
-- Chiselled basalt is intended as a portalstone - an alternative to obsidian that's
|
||||
-- available for other mods to use. It is crafted from Hewn Basalt.
|
||||
-- It should only be introduced by the biomes-based mapgen, since in future it may
|
||||
-- require the MT 5.0 world-align texture features.
|
||||
minetest.register_node("nether:basalt_chiselled", {
|
||||
description = S("Chiselled Basalt"),
|
||||
tiles = {
|
||||
"nether_basalt_chiselled_top.png",
|
||||
"nether_basalt_chiselled_top.png" .. "^[transformFY",
|
||||
"nether_basalt_chiselled_side.png",
|
||||
"nether_basalt_chiselled_side.png",
|
||||
"nether_basalt_chiselled_side.png",
|
||||
"nether_basalt_chiselled_side.png"
|
||||
},
|
||||
inventory_image = minetest.inventorycube(
|
||||
"nether_basalt_chiselled_top.png",
|
||||
"nether_basalt_chiselled_side.png",
|
||||
"nether_basalt_chiselled_side.png"
|
||||
),
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 1, level = 2},
|
||||
on_blast = function() --[[blast proof]] end,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
-- Lava-sea source
|
||||
-- This is a lava source using a different animated texture so that each node
|
||||
-- is out of phase in its animation from its neighbor. This prevents the magma
|
||||
-- ocean from visually clumping together into a patchwork of 16x16 squares.
|
||||
-- It can only be used by the biomes-based mapgen, since it requires the MT 5.0
|
||||
-- world-align texture features.
|
||||
local lavasea_source = {}
|
||||
local lava_source = minetest.registered_nodes["default:lava_source"]
|
||||
for key, value in pairs(lava_source) do lavasea_source[key] = value end
|
||||
lavasea_source.name = nil
|
||||
lavasea_source.tiles = {
|
||||
{
|
||||
name = "nether_lava_source_animated.png",
|
||||
backface_culling = false,
|
||||
align_style = "world",
|
||||
scale = 2,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 3.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "nether_lava_source_animated.png",
|
||||
backface_culling = true,
|
||||
align_style = "world",
|
||||
scale = 2,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 3.0,
|
||||
},
|
||||
},
|
||||
}
|
||||
lavasea_source.liquid_alternative_source = "nether:lava_source"
|
||||
lavasea_source.inventory_image = minetest.inventorycube(
|
||||
"nether_lava_source_animated.png^[sheet:2x16:0,0",
|
||||
"nether_lava_source_animated.png^[sheet:2x16:0,1",
|
||||
"nether_lava_source_animated.png^[sheet:2x16:1,1"
|
||||
)
|
||||
minetest.register_node("nether:lava_source", lavasea_source)
|
||||
|
||||
|
||||
-- a place to store the original ABM function so nether.cool_lava() can call it
|
||||
local original_cool_lava_action
|
||||
|
||||
nether.cool_lava = function(pos, node)
|
||||
|
||||
local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local node_above = minetest.get_node(pos_above)
|
||||
|
||||
-- Evaporate water sitting above lava, if it's in the Nether.
|
||||
-- (we don't want Nether mod to affect overworld lava mechanics)
|
||||
if minetest.get_node_group(node_above.name, "water") > 0 and
|
||||
pos.y < nether.DEPTH_CEILING and pos.y > nether.DEPTH_FLOOR then
|
||||
-- cools_lava might be a better group to check for, but perhaps there's
|
||||
-- something in that group that isn't a liquid and shouldn't be evaporated?
|
||||
minetest.swap_node(pos_above, {name="air"})
|
||||
end
|
||||
|
||||
-- add steam to cooling lava
|
||||
minetest.add_particlespawner({
|
||||
amount = 20,
|
||||
time = 0.15,
|
||||
minpos = {x=pos.x - 0.4, y=pos.y - 0, z=pos.z - 0.4},
|
||||
maxpos = {x=pos.x + 0.4, y=pos.y + 0.5, z=pos.z + 0.4},
|
||||
minvel = {x = -0.5, y = 0.5, z = -0.5},
|
||||
maxvel = {x = 0.5, y = 1.5, z = 0.5},
|
||||
minacc = {x = 0, y = 0.1, z = 0},
|
||||
maxacc = {x = 0, y = 0.2, z = 0},
|
||||
minexptime = 0.5,
|
||||
maxexptime = 1.3,
|
||||
minsize = 1.5,
|
||||
maxsize = 3.5,
|
||||
texture = "nether_particle_anim4.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 7,
|
||||
aspect_h = 7,
|
||||
length = 1.4,
|
||||
}
|
||||
})
|
||||
|
||||
if node.name == "nether:lava_source" or node.name == "nether:lava_crust" then
|
||||
-- use swap_node to avoid triggering the lava_crust's after_destruct
|
||||
minetest.swap_node(pos, {name = "nether:basalt"})
|
||||
|
||||
minetest.sound_play("default_cool_lava",
|
||||
{pos = pos, max_hear_distance = 16, gain = 0.25}, true)
|
||||
else
|
||||
-- chain the original ABM action to handle conventional lava
|
||||
original_cool_lava_action(pos, node)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
|
||||
-- register a bucket of Lava-sea source - but make it just the same bucket as default lava.
|
||||
-- (by doing this in register_on_mods_loaded we don't need to declare a soft dependency)
|
||||
if minetest.get_modpath("bucket") and minetest.global_exists("bucket") then
|
||||
local lava_bucket = bucket.liquids["default:lava_source"]
|
||||
if lava_bucket ~= nil then
|
||||
local lavasea_bucket = {}
|
||||
for key, value in pairs(lava_bucket) do lavasea_bucket[key] = value end
|
||||
lavasea_bucket.source = "nether:lava_source"
|
||||
bucket.liquids[lavasea_bucket.source] = lavasea_bucket
|
||||
end
|
||||
end
|
||||
|
||||
-- include "nether:lava_source" in any "default:lava_source" ABMs
|
||||
local function include_nether_lava(set_of_nodes)
|
||||
if (type(set_of_nodes) == "table") then
|
||||
for _, nodename in pairs(set_of_nodes) do
|
||||
if nodename == "default:lava_source" then
|
||||
-- I'm amazed this works, but it does
|
||||
table.insert(set_of_nodes, "nether:lava_source")
|
||||
break;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, abm in pairs(minetest.registered_abms) do
|
||||
include_nether_lava(abm.nodenames)
|
||||
include_nether_lava(abm.neighbors)
|
||||
if abm.label == "Lava cooling" and abm.action ~= nil then
|
||||
-- lets have lava_crust cool as well
|
||||
original_cool_lava_action = abm.action
|
||||
abm.action = nether.cool_lava
|
||||
table.insert(abm.nodenames, "nether:lava_crust")
|
||||
end
|
||||
end
|
||||
for _, lbm in pairs(minetest.registered_lbms) do
|
||||
include_nether_lava(lbm.nodenames)
|
||||
end
|
||||
--minetest.log("minetest.registered_abms" .. dump(minetest.registered_abms))
|
||||
--minetest.log("minetest.registered_lbms" .. dump(minetest.registered_lbms))
|
||||
end)
|
||||
|
||||
-- creates a lava splash, and leaves lava_source in place of the lava_crust
|
||||
local function smash_lava_crust(pos, playsound)
|
||||
|
||||
local lava_particlespawn_def = {
|
||||
amount = 6,
|
||||
time = 0.1,
|
||||
minpos = {x=pos.x - 0.5, y=pos.y + 0.3, z=pos.z - 0.5},
|
||||
maxpos = {x=pos.x + 0.5, y=pos.y + 0.5, z=pos.z + 0.5},
|
||||
minvel = {x = -1.5, y = 1.5, z = -1.5},
|
||||
maxvel = {x = 1.5, y = 5, z = 1.5},
|
||||
minacc = {x = 0, y = -10, z = 0},
|
||||
maxacc = {x = 0, y = -10, z = 0},
|
||||
minexptime = 1,
|
||||
maxexptime = 1,
|
||||
minsize = .2,
|
||||
maxsize = .8,
|
||||
texture = "^[colorize:#A00:255",
|
||||
glow = 8
|
||||
}
|
||||
minetest.add_particlespawner(lava_particlespawn_def)
|
||||
lava_particlespawn_def.texture = "^[colorize:#FB0:255"
|
||||
lava_particlespawn_def.maxvel.y = 3
|
||||
lava_particlespawn_def.glow = 12
|
||||
minetest.add_particlespawner(lava_particlespawn_def)
|
||||
|
||||
minetest.set_node(pos, {name = "default:lava_source"})
|
||||
|
||||
if math.random(1, 3) == 1 and minetest.registered_nodes["fire:basic_flame"] ~= nil then
|
||||
-- occasionally brief flames will be seen when breaking lava crust
|
||||
local posAbove = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
if minetest.get_node(posAbove).name == "air" then
|
||||
minetest.set_node(posAbove, {name = "fire:basic_flame"})
|
||||
minetest.get_node_timer(posAbove):set(math.random(7, 15) / 10, 0)
|
||||
--[[ commented out because the flame sound plays for too long
|
||||
if minetest.global_exists("fire") and fire.update_player_sound ~= nil then
|
||||
-- The fire mod only updates its sound every 3 seconds, these flames will be
|
||||
-- out by then, so start the sound immediately
|
||||
local players = minetest.get_connected_players()
|
||||
for n = 1, #players do fire.update_player_sound(players[n]) end
|
||||
end]]
|
||||
end
|
||||
end
|
||||
|
||||
if playsound then
|
||||
minetest.sound_play(
|
||||
"nether_lava_bubble",
|
||||
-- this sample was encoded at 3x speed to reduce .ogg file size
|
||||
-- at the expense of higher frequencies, so pitch it down ~3x
|
||||
{pos = pos, pitch = 0.3, max_hear_distance = 8, gain = 0.4}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- lava_crust nodes can only be used in the biomes-based mapgen, since they require
|
||||
-- the MT 5.0 world-align texture features.
|
||||
minetest.register_node("nether:lava_crust", {
|
||||
description = "Lava crust",
|
||||
tiles = {
|
||||
{
|
||||
name="nether_lava_crust_animated.png",
|
||||
backface_culling=true,
|
||||
tileable_vertical=true,
|
||||
tileable_horizontal=true,
|
||||
align_style="world",
|
||||
scale=2,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1.8,
|
||||
},
|
||||
}
|
||||
},
|
||||
inventory_image = minetest.inventorycube(
|
||||
"nether_lava_crust_animated.png^[sheet:2x48:0,0",
|
||||
"nether_lava_crust_animated.png^[sheet:2x48:0,1",
|
||||
"nether_lava_crust_animated.png^[sheet:2x48:1,1"
|
||||
),
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
-- Damage is calculated "starting 0.1 above feet
|
||||
-- and progressing upwards in 1 node intervals", so
|
||||
-- lower this node's collision box by more than 0.1
|
||||
-- to ensure damage will be taken when standing on
|
||||
-- the node.
|
||||
{-0.5, -0.5, -0.5, 0.5, 0.39, 0.5}
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
-- Keep the selection box matching the visual node,
|
||||
-- rather than the collision_box.
|
||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
|
||||
},
|
||||
},
|
||||
|
||||
after_destruct = function(pos, oldnode)
|
||||
smash_lava_crust(pos, true)
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
end,
|
||||
on_blast = function(pos, intensity)
|
||||
smash_lava_crust(pos, false)
|
||||
end,
|
||||
|
||||
paramtype = "light",
|
||||
light_source = default.LIGHT_MAX - 3,
|
||||
buildable_to = false,
|
||||
walkable_to = true,
|
||||
is_ground_content = true,
|
||||
drop = {
|
||||
items = {{
|
||||
-- Allow SilkTouch-esque "pickaxes of preservation" to mine the lava crust intact, if PR #10141 gets merged.
|
||||
tools = {"this line will block early MT versions which don't respect the tool_groups restrictions"},
|
||||
tool_groups = {{"pickaxe", "preservation"}},
|
||||
items = {"nether:lava_crust"}
|
||||
}}
|
||||
},
|
||||
--liquid_viscosity = 7,
|
||||
damage_per_second = 2,
|
||||
groups = {oddly_breakable_by_hand = 3, cracky = 3, explody = 1, igniter = 1},
|
||||
})
|
||||
|
||||
|
||||
-- Fumaroles (Chimney's)
|
||||
|
||||
local function fumarole_startTimer(pos, timeout_factor)
|
||||
@ -393,31 +761,3 @@ local airlike_darkness = {}
|
||||
for k,v in pairs(minetest.registered_nodes["air"]) do airlike_darkness[k] = v end
|
||||
airlike_darkness.paramtype = "none"
|
||||
minetest.register_node("nether:airlike_darkness", airlike_darkness)
|
||||
|
||||
|
||||
-- Crafting
|
||||
|
||||
minetest.register_craft({
|
||||
output = "nether:brick 4",
|
||||
recipe = {
|
||||
{"nether:rack", "nether:rack"},
|
||||
{"nether:rack", "nether:rack"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "nether:fence_nether_brick 6",
|
||||
recipe = {
|
||||
{"nether:brick", "nether:brick", "nether:brick"},
|
||||
{"nether:brick", "nether:brick", "nether:brick"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "nether:brick_compressed",
|
||||
recipe = {
|
||||
{"nether:brick","nether:brick","nether:brick"},
|
||||
{"nether:brick","nether:brick","nether:brick"},
|
||||
{"nether:brick","nether:brick","nether:brick"},
|
||||
}
|
||||
})
|
||||
|
Reference in New Issue
Block a user