2020-01-08 10:06:00 +01:00
|
|
|
--[[
|
|
|
|
|
|
|
|
Nether mod for minetest
|
|
|
|
|
|
|
|
Copyright (C) 2013 PilzAdam
|
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for
|
|
|
|
any purpose with or without fee is hereby granted, provided that the
|
|
|
|
above copyright notice and this permission notice appear in all copies.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
|
|
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
|
|
|
BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
|
|
|
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
|
|
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
|
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
SOFTWARE.
|
|
|
|
|
|
|
|
]]--
|
|
|
|
|
2020-01-06 12:21:15 +01:00
|
|
|
local S = nether.get_translator
|
|
|
|
|
2020-02-18 13:05:45 +01:00
|
|
|
-- Portal/wormhole nodes
|
2019-08-06 23:23:06 +02:00
|
|
|
|
2020-01-08 10:06:00 +01:00
|
|
|
nether.register_wormhole_node("nether:portal", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Nether Portal"),
|
2019-08-06 23:23:06 +02:00
|
|
|
post_effect_color = {
|
|
|
|
-- post_effect_color can't be changed dynamically in Minetest like the portal colour is.
|
2020-01-08 11:37:31 +01:00
|
|
|
-- If you need a different post_effect_color then use register_wormhole_node to create
|
2020-01-08 10:06:00 +01:00
|
|
|
-- another wormhole node and set it as the wormhole_node_name in your portaldef.
|
2019-08-06 23:23:06 +02:00
|
|
|
-- Hopefully this colour is close enough to magenta to work with the traditional magenta
|
|
|
|
-- portals, close enough to red to work for a red portal, and also close enough to red to
|
|
|
|
-- work with blue & cyan portals - since blue portals are sometimes portrayed as being red
|
|
|
|
-- from the opposite side / from the inside.
|
|
|
|
a = 160, r = 128, g = 0, b = 80
|
2020-01-08 10:06:00 +01:00
|
|
|
}
|
2019-08-06 23:23:06 +02:00
|
|
|
})
|
|
|
|
|
2020-02-18 13:05:45 +01:00
|
|
|
local portal_animation2 = {
|
|
|
|
name = "nether_portal_alt.png",
|
|
|
|
animation = {
|
|
|
|
type = "vertical_frames",
|
|
|
|
aspect_w = 16,
|
|
|
|
aspect_h = 16,
|
|
|
|
length = 0.5,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
nether.register_wormhole_node("nether:portal_alt", {
|
|
|
|
description = S("Portal"),
|
|
|
|
tiles = {
|
|
|
|
"nether_transparent.png",
|
|
|
|
"nether_transparent.png",
|
|
|
|
"nether_transparent.png",
|
|
|
|
"nether_transparent.png",
|
|
|
|
portal_animation2,
|
|
|
|
portal_animation2
|
|
|
|
},
|
|
|
|
post_effect_color = {
|
|
|
|
-- hopefully blue enough to work with blue portals, and green enough to
|
|
|
|
-- work with cyan portals.
|
|
|
|
a = 120, r = 0, g = 128, b = 188
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2019-08-06 23:23:06 +02:00
|
|
|
|
|
|
|
-- Nether nodes
|
|
|
|
|
|
|
|
minetest.register_node("nether:rack", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Netherrack"),
|
2019-08-06 23:23:06 +02:00
|
|
|
tiles = {"nether_rack.png"},
|
|
|
|
is_ground_content = true,
|
|
|
|
groups = {cracky = 3, level = 2},
|
|
|
|
sounds = default.node_sound_stone_defaults(),
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_node("nether:sand", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Nethersand"),
|
2019-08-06 23:23:06 +02:00
|
|
|
tiles = {"nether_sand.png"},
|
|
|
|
is_ground_content = true,
|
|
|
|
groups = {crumbly = 3, level = 2, falling_node = 1},
|
|
|
|
sounds = default.node_sound_gravel_defaults({
|
|
|
|
footstep = {name = "default_gravel_footstep", gain = 0.45},
|
|
|
|
}),
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_node("nether:glowstone", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Glowstone"),
|
2019-08-06 23:23:06 +02:00
|
|
|
tiles = {"nether_glowstone.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", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Nether Brick"),
|
2019-08-06 23:23:06 +02:00
|
|
|
tiles = {"nether_brick.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"
|
|
|
|
|
|
|
|
minetest.register_node("nether:fence_nether_brick", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Nether Brick Fence"),
|
2019-08-06 23:23:06 +02:00
|
|
|
drawtype = "fencelike",
|
|
|
|
tiles = {"nether_brick.png"},
|
|
|
|
inventory_image = fence_texture,
|
|
|
|
wield_image = fence_texture,
|
|
|
|
paramtype = "light",
|
|
|
|
sunlight_propagates = true,
|
|
|
|
is_ground_content = false,
|
|
|
|
selection_box = {
|
|
|
|
type = "fixed",
|
|
|
|
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
|
|
|
|
},
|
|
|
|
groups = {cracky = 2, level = 2},
|
|
|
|
sounds = default.node_sound_stone_defaults(),
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
-- Register stair and slab
|
|
|
|
|
|
|
|
stairs.register_stair_and_slab(
|
|
|
|
"nether_brick",
|
|
|
|
"nether:brick",
|
|
|
|
{cracky = 2, level = 2},
|
|
|
|
{"nether_brick.png"},
|
2020-02-08 08:00:01 +01:00
|
|
|
S("Nether Stair"),
|
|
|
|
S("Nether Slab"),
|
2020-02-04 19:35:22 +01:00
|
|
|
default.node_sound_stone_defaults(),
|
|
|
|
nil,
|
|
|
|
S("Inner Nether Stair"),
|
|
|
|
S("Outer Nether Stair")
|
2019-08-06 23:23:06 +02:00
|
|
|
)
|
|
|
|
|
2020-01-25 12:52:26 +01:00
|
|
|
stairs.register_stair(
|
|
|
|
"netherrack",
|
|
|
|
"nether:rack",
|
|
|
|
{cracky = 2, level = 2},
|
|
|
|
{"nether_rack.png"},
|
|
|
|
S("Netherrack stair"),
|
|
|
|
default.node_sound_stone_defaults()
|
|
|
|
)
|
|
|
|
|
2019-08-06 23:23:06 +02:00
|
|
|
-- StairsPlus
|
|
|
|
|
|
|
|
if minetest.get_modpath("moreblocks") then
|
|
|
|
stairsplus:register_all(
|
|
|
|
"nether", "brick", "nether:brick", {
|
2020-01-06 12:21:15 +01:00
|
|
|
description = S("Nether Brick"),
|
2019-08-06 23:23:06 +02:00
|
|
|
groups = {cracky = 2, level = 2},
|
|
|
|
tiles = {"nether_brick.png"},
|
|
|
|
sounds = default.node_sound_stone_defaults(),
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2020-01-25 12:52:26 +01:00
|
|
|
-- Fumaroles (Chimney's)
|
|
|
|
|
|
|
|
local function fumarole_startTimer(pos, timeout_factor)
|
|
|
|
|
|
|
|
if timeout_factor == nil then timeout_factor = 1 end
|
|
|
|
local next_timeout = (math.random(50, 900) / 10) * timeout_factor
|
|
|
|
|
|
|
|
minetest.get_meta(pos):set_float("expected_timeout", next_timeout)
|
|
|
|
minetest.get_node_timer(pos):start(next_timeout)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Create an LBM to start fumarole node timers
|
|
|
|
minetest.register_lbm({
|
|
|
|
label = "Start fumarole smoke",
|
|
|
|
name = "nether:start_fumarole",
|
|
|
|
nodenames = {"nether:fumarole"},
|
|
|
|
run_at_every_load = true,
|
|
|
|
action = function(pos, node)
|
|
|
|
local node_above = minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z})
|
|
|
|
if node_above.name == "air" then --and node.param2 % 4 == 0 then
|
|
|
|
fumarole_startTimer(pos)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|
|
|
|
|
|
|
|
local function set_fire(pos, extinguish)
|
|
|
|
local posBelow = {x = pos.x, y = pos.y - 1, z = pos.z}
|
|
|
|
|
|
|
|
if extinguish then
|
|
|
|
if minetest.get_node(pos).name == "fire:permanent_flame" then minetest.set_node(pos, {name="air"}) end
|
|
|
|
if minetest.get_node(posBelow).name == "fire:permanent_flame" then minetest.set_node(posBelow, {name="air"}) end
|
|
|
|
|
|
|
|
elseif minetest.get_node(posBelow).name == "air" then
|
|
|
|
minetest.set_node(posBelow, {name="fire:permanent_flame"})
|
|
|
|
elseif minetest.get_node(pos).name == "air" then
|
|
|
|
minetest.set_node(pos, {name="fire:permanent_flame"})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function fumarole_onTimer(pos, elapsed)
|
|
|
|
|
|
|
|
local expected_timeout = minetest.get_meta(pos):get_float("expected_timeout")
|
|
|
|
if elapsed > expected_timeout + 10 then
|
|
|
|
-- The timer didn't fire when it was supposed to, so the chunk was probably inactive and has
|
|
|
|
-- just been approached again, meaning *every* fumarole's on_timer is about to go off.
|
|
|
|
-- Skip this event and restart the clock for a future random interval.
|
|
|
|
fumarole_startTimer(pos, 1)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Fumaroles in the Nether can catch fire.
|
|
|
|
-- (if taken to the surface and used as cottage chimneys, they don't catch fire)
|
|
|
|
local inNether = pos.y <= nether.DEPTH and pos.y >= nether.DEPTH_FLOOR
|
|
|
|
local canCatchFire = inNether and minetest.registered_nodes["fire:permanent_flame"] ~= nil
|
|
|
|
local smoke_offset = 0
|
|
|
|
local timeout_factor = 1
|
|
|
|
local smoke_time_adj = 1
|
|
|
|
|
|
|
|
local posAbove = {x = pos.x, y = pos.y + 1, z = pos.z}
|
|
|
|
local extinguish = minetest.get_node(posAbove).name ~= "air"
|
|
|
|
|
|
|
|
if extinguish or (canCatchFire and math.floor(elapsed) % 7 == 0) then
|
|
|
|
|
|
|
|
if not extinguish then
|
|
|
|
-- fumarole gasses are igniting
|
|
|
|
smoke_offset = 1
|
|
|
|
timeout_factor = 0.22 -- reduce burning time
|
|
|
|
end
|
|
|
|
|
|
|
|
set_fire(posAbove, extinguish)
|
|
|
|
set_fire({x = pos.x + 1, y = pos.y + 1, z = pos.z}, extinguish)
|
|
|
|
set_fire({x = pos.x - 1, y = pos.y + 1, z = pos.z}, extinguish)
|
|
|
|
set_fire({x = pos.x, y = pos.y + 1, z = pos.z + 1}, extinguish)
|
|
|
|
set_fire({x = pos.x, y = pos.y + 1, z = pos.z - 1}, extinguish)
|
|
|
|
|
|
|
|
elseif inNether then
|
|
|
|
|
|
|
|
if math.floor(elapsed) % 3 == 1 then
|
|
|
|
-- throw up some embers / lava splash
|
|
|
|
local embers_particlespawn_def = {
|
|
|
|
amount = 6,
|
|
|
|
time = 0.1,
|
|
|
|
minpos = {x=pos.x - 0.1, y=pos.y + 0.0, z=pos.z - 0.1},
|
|
|
|
maxpos = {x=pos.x + 0.1, y=pos.y + 0.2, z=pos.z + 0.1},
|
|
|
|
minvel = {x = -.5, y = 4.5, z = -.5},
|
|
|
|
maxvel = {x = .5, y = 7, z = .5},
|
|
|
|
minacc = {x = 0, y = -10, z = 0},
|
|
|
|
maxacc = {x = 0, y = -10, z = 0},
|
|
|
|
minexptime = 1.4,
|
|
|
|
maxexptime = 1.4,
|
|
|
|
minsize = .2,
|
|
|
|
maxsize = .8,
|
|
|
|
texture = "^[colorize:#A00:255",
|
|
|
|
glow = 8
|
|
|
|
}
|
|
|
|
minetest.add_particlespawner(embers_particlespawn_def)
|
|
|
|
embers_particlespawn_def.texture = "^[colorize:#A50:255"
|
|
|
|
embers_particlespawn_def.maxvel.y = 3
|
|
|
|
embers_particlespawn_def.glow = 12
|
|
|
|
minetest.add_particlespawner(embers_particlespawn_def)
|
|
|
|
|
|
|
|
else
|
|
|
|
-- gas noises
|
|
|
|
minetest.sound_play("nether_fumarole", {
|
|
|
|
pos = pos,
|
|
|
|
max_hear_distance = 60,
|
|
|
|
gain = 0.24,
|
|
|
|
pitch = math.random(35, 95) / 100
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
else
|
|
|
|
-- we're not in the Nether, so can afford to be a bit more smokey
|
|
|
|
timeout_factor = 0.4
|
|
|
|
smoke_time_adj = 1.3
|
|
|
|
end
|
|
|
|
|
|
|
|
-- let out some smoke
|
|
|
|
minetest.add_particlespawner({
|
|
|
|
amount = 12 * smoke_time_adj,
|
|
|
|
time = math.random(40, 60) / 10 * smoke_time_adj,
|
|
|
|
minpos = {x=pos.x - 0.2, y=pos.y + smoke_offset, z=pos.z - 0.2},
|
|
|
|
maxpos = {x=pos.x + 0.2, y=pos.y + smoke_offset, z=pos.z + 0.2},
|
|
|
|
minvel = {x=0, y=0.7, z=-0},
|
|
|
|
maxvel = {x=0, y=0.8, z=-0},
|
|
|
|
minacc = {x=0.0,y=0.0,z=-0},
|
|
|
|
maxacc = {x=0.0,y=0.1,z=-0},
|
|
|
|
minexptime = 5,
|
|
|
|
maxexptime = 5.5,
|
|
|
|
minsize = 1.5,
|
|
|
|
maxsize = 7,
|
|
|
|
texture = "nether_smoke_puff.png",
|
|
|
|
})
|
|
|
|
|
|
|
|
fumarole_startTimer(pos, timeout_factor)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
minetest.register_node("nether:fumarole", {
|
|
|
|
description="Fumarolic Chimney",
|
|
|
|
tiles = {"nether_rack.png"},
|
|
|
|
on_timer = fumarole_onTimer,
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
|
|
fumarole_onTimer(pos, 1)
|
|
|
|
return false
|
|
|
|
end,
|
|
|
|
is_ground_content = true,
|
|
|
|
groups = {cracky = 3, level = 2, fumarole=1},
|
|
|
|
paramtype = "light",
|
|
|
|
drawtype = "nodebox",
|
|
|
|
node_box = {
|
|
|
|
type = "fixed",
|
|
|
|
fixed = {
|
|
|
|
{-0.5000, -0.5000, -0.5000, -0.2500, 0.5000, 0.5000},
|
|
|
|
{-0.5000, -0.5000, -0.5000, 0.5000, 0.5000, -0.2500},
|
|
|
|
{-0.5000, -0.5000, 0.2500, 0.5000, 0.5000, 0.5000},
|
|
|
|
{0.2500, -0.5000, -0.5000, 0.5000, 0.5000, 0.5000}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
selection_box = {type = 'fixed', fixed = {-.5, -.5, -.5, .5, .5, .5}}
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_node("nether:fumarole_slab", {
|
|
|
|
description="Fumarolic Chimney Slab",
|
|
|
|
tiles = {"nether_rack.png"},
|
|
|
|
is_ground_content = true,
|
|
|
|
on_timer = fumarole_onTimer,
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
|
|
fumarole_onTimer(pos, 1)
|
|
|
|
return false
|
|
|
|
end,
|
|
|
|
groups = {cracky = 3, level = 2, fumarole=1},
|
|
|
|
paramtype = "light",
|
|
|
|
drawtype = "nodebox",
|
|
|
|
node_box = {
|
|
|
|
type = "fixed",
|
|
|
|
fixed = {
|
|
|
|
{-0.5000, -0.5000, -0.5000, -0.2500, 0.000, 0.5000},
|
|
|
|
{-0.5000, -0.5000, -0.5000, 0.5000, 0.000, -0.2500},
|
|
|
|
{-0.5000, -0.5000, 0.2500, 0.5000, 0.000, 0.5000},
|
|
|
|
{0.2500, -0.5000, -0.5000, 0.5000, 0.000, 0.5000}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
selection_box = {type = 'fixed', fixed = {-.5, -.5, -.5, .5, 0, .5}},
|
|
|
|
collision_box = {type = 'fixed', fixed = {-.5, -.5, -.5, .5, 0, .5}}
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_node("nether:fumarole_corner", {
|
|
|
|
description="Fumarolic Chimney Corner",
|
|
|
|
tiles = {"nether_rack.png"},
|
|
|
|
is_ground_content = true,
|
|
|
|
groups = {cracky = 3, level = 2, fumarole=1},
|
|
|
|
paramtype = "light",
|
|
|
|
paramtype2 = "facedir",
|
|
|
|
drawtype = "nodebox",
|
|
|
|
node_box = {
|
|
|
|
type = "fixed",
|
|
|
|
fixed = {
|
|
|
|
{-0.2500, -0.5000, 0.5000, 0.000, 0.5000, 0.000},
|
|
|
|
{-0.5000, -0.5000, 0.2500, 0.000, 0.5000, 0.000},
|
|
|
|
{-0.5000, -0.5000, 0.2500, 0.000, 0.000, -0.5000},
|
|
|
|
{0.000, -0.5000, -0.5000, 0.5000, 0.000, 0.5000}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
selection_box = {
|
|
|
|
type = 'fixed',
|
|
|
|
fixed = {
|
|
|
|
{-.5, -.5, -.5, .5, 0, .5},
|
|
|
|
{0, 0, .5, -.5, .5, 0},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
-- nether:airlike_darkness is an air node through which light does not propagate.
|
|
|
|
-- Use of it should be avoided when possible as it has the appearance of a lighting bug.
|
|
|
|
-- Fumarole decorations use it to stop the propagation of light from the lava below,
|
|
|
|
-- since engine limitations mean any mesh or nodebox node will light up if it has lava
|
|
|
|
-- below it.
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
2019-08-06 23:23:06 +02:00
|
|
|
-- 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"},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
|