mirror of
https://github.com/HybridDog/nether-pack.git
synced 2025-06-29 14:41:05 +02:00
Compare commits
9 Commits
html_forms
...
master
Author | SHA1 | Date | |
---|---|---|---|
8be1f839c5 | |||
9c3fc65544 | |||
0351e12bac | |||
1c033a048f | |||
02d14a8970 | |||
76708b02d5 | |||
f12d33c743 | |||
435cef6f81 | |||
01cd7c8e5b |
16
README.md
16
README.md
@ -3,13 +3,9 @@ https://forum.minetest.net/viewtopic.php?f=9&t=10265
|
|||||||
|
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
* Find a way to get the perlin noise inside [-1; 1] or use another noise
|
* Mapgen: Find a way to get the perlin noise values inside [-1; 1] or use
|
||||||
* Add some node which containing items to the simple pyramid "buildings"
|
another noise.
|
||||||
* Change the sky background, fog, etc. in the nether
|
The problem is visible in the nether forest, where the mapgen code flattens
|
||||||
* Improve the guide formspec.
|
the ceiling if it is very high.
|
||||||
Writing it in Markdown would be nice.
|
* Mapgen: Generate more detail inside the simple pyramid-like "buildings",
|
||||||
These could be useful:
|
e.g. add a small treasure chest node which contains items
|
||||||
* https://forum.minetest.net/viewtopic.php?t=23855
|
|
||||||
Minetest Bedrock Markup Language
|
|
||||||
* https://github.com/mpeterv/markdown
|
|
||||||
Markdown to HTML converter; Minetest formspecs support HTML
|
|
||||||
|
@ -4,7 +4,7 @@ read_globals = {
|
|||||||
"string",
|
"string",
|
||||||
|
|
||||||
-- Mods
|
-- Mods
|
||||||
"default", "stairs", "creative"
|
"default", "stairs"
|
||||||
}
|
}
|
||||||
globals = {"nether"}
|
globals = {"nether"}
|
||||||
ignore = {
|
ignore = {
|
||||||
@ -13,3 +13,5 @@ ignore = {
|
|||||||
"411", "421", "422", "423", "431", "432",
|
"411", "421", "422", "423", "431", "432",
|
||||||
-- Shadowing
|
-- Shadowing
|
||||||
}
|
}
|
||||||
|
-- Allow very long lines in guide.lua for the HTML code
|
||||||
|
files["guide.lua"] = {ignore = {"631"}}
|
||||||
|
157
nether/common.lua
Normal file
157
nether/common.lua
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
dofile(nether.path .. "/settings.lua")
|
||||||
|
|
||||||
|
local in_mapgen_env = nether.env_type == "ssm_mapgen"
|
||||||
|
|
||||||
|
-- vars
|
||||||
|
nether.v = {}
|
||||||
|
local v = nether.v
|
||||||
|
|
||||||
|
--== EDITABLE OPTIONS ==--
|
||||||
|
|
||||||
|
-- Depth of the nether
|
||||||
|
v.nether_middle = -20000
|
||||||
|
|
||||||
|
-- forest bottom perlin multiplication
|
||||||
|
v.f_bottom_scale = 4
|
||||||
|
|
||||||
|
-- forest bottom height
|
||||||
|
v.f_h_min = v.nether_middle+10
|
||||||
|
|
||||||
|
-- forest top height
|
||||||
|
v.f_h_max = v.f_h_min+250
|
||||||
|
|
||||||
|
-- Frequency of trees in the nether forest (higher is less frequent)
|
||||||
|
v.tree_rarity = 200
|
||||||
|
|
||||||
|
-- Frequency of glowflowers in the nether forest (higher is less frequent)
|
||||||
|
v.glowflower_rarity = 120
|
||||||
|
|
||||||
|
-- Frequency of nether grass in the nether forest (higher is less frequent)
|
||||||
|
v.grass_rarity = 2
|
||||||
|
|
||||||
|
-- Frequency of nether mushrooms in the nether forest (higher is less frequent)
|
||||||
|
v.mushroom_rarity = 80
|
||||||
|
|
||||||
|
v.abm_tree_interval = 864
|
||||||
|
v.abm_tree_chance = 100
|
||||||
|
|
||||||
|
-- height of the nether generation's end
|
||||||
|
v.nether_start = v.f_h_max+100
|
||||||
|
|
||||||
|
-- Height of the nether (bottom of the nether is nether_middle - NETHER_HEIGHT)
|
||||||
|
v.NETHER_HEIGHT = 30
|
||||||
|
|
||||||
|
-- bottom height of the nether.
|
||||||
|
v.nether_bottom = v.nether_middle - v.NETHER_HEIGHT - 100
|
||||||
|
|
||||||
|
-- Maximum amount of randomness in the map generation
|
||||||
|
v.NETHER_RANDOM = 2
|
||||||
|
|
||||||
|
-- Frequency of Glowstone on the "roof" of the Nether (higher is less frequent)
|
||||||
|
v.GLOWSTONE_FREQ_ROOF = 500
|
||||||
|
|
||||||
|
-- Frequency of lava (higher is less frequent)
|
||||||
|
v.LAVA_FREQ = 100
|
||||||
|
|
||||||
|
v.nether_structure_freq = 350
|
||||||
|
v.NETHER_SHROOM_FREQ = 100
|
||||||
|
|
||||||
|
-- Maximum height of lava
|
||||||
|
--v.LAVA_HEIGHT = 2
|
||||||
|
-- Frequency of Glowstone on lava (higher is less frequent)
|
||||||
|
--v.GLOWSTONE_FREQ_LAVA = 2
|
||||||
|
-- Height of nether structures
|
||||||
|
--v.NETHER_TREESIZE = 2
|
||||||
|
-- Frequency of apples in a nether structure (higher is less frequent)
|
||||||
|
--v.NETHER_APPLE_FREQ = 5
|
||||||
|
-- Frequency of healing apples in a nether structure (higher is less frequent)
|
||||||
|
--v.NETHER_HEAL_APPLE_FREQ = 10
|
||||||
|
-- Start position for the Throne of Hades (y is relative to the bottom of the
|
||||||
|
-- nether)
|
||||||
|
--v.HADES_THRONE_STARTPOS = {x=0, y=1, z=0}
|
||||||
|
-- Spawn pos for when the nether hasn't been loaded yet (i.e. no portal in the
|
||||||
|
-- nether) (y is relative to the bottom of the nether)
|
||||||
|
--v.NETHER_SPAWNPOS = {x=0, y=5, z=0}
|
||||||
|
-- Structure of the nether portal (all is relative to the nether portal creator
|
||||||
|
-- block)
|
||||||
|
|
||||||
|
--== END OF EDITABLE OPTIONS ==--
|
||||||
|
|
||||||
|
-- Generated variables
|
||||||
|
v.NETHER_BOTTOM = (v.nether_middle - v.NETHER_HEIGHT)
|
||||||
|
v.nether_buildings = v.NETHER_BOTTOM+12
|
||||||
|
|
||||||
|
function nether.query_contents()
|
||||||
|
local c = {
|
||||||
|
ignore = minetest.get_content_id("ignore"),
|
||||||
|
air = minetest.get_content_id("air"),
|
||||||
|
lava = minetest.get_content_id("default:lava_source"),
|
||||||
|
gravel = minetest.get_content_id("default:gravel"),
|
||||||
|
coal = minetest.get_content_id("default:stone_with_coal"),
|
||||||
|
diamond = minetest.get_content_id("default:stone_with_diamond"),
|
||||||
|
mese = minetest.get_content_id("default:mese"),
|
||||||
|
|
||||||
|
--https://github.com/Zeg9/minetest-glow
|
||||||
|
glowstone = minetest.get_content_id("glow:stone"),
|
||||||
|
|
||||||
|
nether_shroom = minetest.get_content_id("riesenpilz:nether_shroom"),
|
||||||
|
|
||||||
|
netherrack = minetest.get_content_id("nether:netherrack"),
|
||||||
|
netherrack_tiled = minetest.get_content_id("nether:netherrack_tiled"),
|
||||||
|
netherrack_black = minetest.get_content_id("nether:netherrack_black"),
|
||||||
|
netherrack_blue = minetest.get_content_id("nether:netherrack_blue"),
|
||||||
|
netherrack_brick = minetest.get_content_id("nether:netherrack_brick"),
|
||||||
|
white = minetest.get_content_id("nether:white"),
|
||||||
|
|
||||||
|
nether_vine = minetest.get_content_id("nether:vine"),
|
||||||
|
blood = minetest.get_content_id("nether:blood"),
|
||||||
|
blood_top = minetest.get_content_id("nether:blood_top"),
|
||||||
|
blood_stem = minetest.get_content_id("nether:blood_stem"),
|
||||||
|
nether_apple = minetest.get_content_id("nether:apple"),
|
||||||
|
|
||||||
|
nether_tree = minetest.get_content_id("nether:tree"),
|
||||||
|
nether_tree_corner = minetest.get_content_id("nether:tree_corner"),
|
||||||
|
nether_leaves = minetest.get_content_id("nether:leaves"),
|
||||||
|
nether_grass = {
|
||||||
|
minetest.get_content_id("nether:grass_small"),
|
||||||
|
minetest.get_content_id("nether:grass_middle"),
|
||||||
|
minetest.get_content_id("nether:grass_big")
|
||||||
|
},
|
||||||
|
glowflower = minetest.get_content_id("nether:glowflower"),
|
||||||
|
nether_dirt = minetest.get_content_id("nether:dirt"),
|
||||||
|
nether_dirt_top = minetest.get_content_id("nether:dirt_top"),
|
||||||
|
nether_dirt_bottom = minetest.get_content_id("nether:dirt_bottom"),
|
||||||
|
}
|
||||||
|
local trn = {c.nether_tree, c.nether_tree_corner, c.nether_leaves,
|
||||||
|
c.nether_fruit}
|
||||||
|
local nether_tree_nodes = {}
|
||||||
|
for i = 1,#trn do
|
||||||
|
nether_tree_nodes[trn[i]] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
return c, nether_tree_nodes
|
||||||
|
end
|
||||||
|
|
||||||
|
if nether.log_level >= 1 then
|
||||||
|
local mod_prefix = in_mapgen_env and "[nether(mg)] " or "[nether] "
|
||||||
|
|
||||||
|
function nether:inform(msg, spam, t)
|
||||||
|
if spam <= self.log_level then
|
||||||
|
local info
|
||||||
|
if t then
|
||||||
|
info = mod_prefix .. msg .. (" after ca. %.3g s"):format(
|
||||||
|
(minetest.get_us_time() - t) / 1000000)
|
||||||
|
else
|
||||||
|
info = mod_prefix .. msg
|
||||||
|
end
|
||||||
|
print(info)
|
||||||
|
if self.log_to_chat then
|
||||||
|
minetest.chat_send_all(info)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
function nether.inform()
|
||||||
|
end
|
||||||
|
end
|
312
nether/grow_structures.lua
Normal file
312
nether/grow_structures.lua
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
|
||||||
|
local netherstructure_height = 6
|
||||||
|
|
||||||
|
local function vmanip_with_r_area(width, height, pos)
|
||||||
|
local manip = minetest.get_voxel_manip()
|
||||||
|
local emerged_pos1, emerged_pos2 = manip:read_from_map(
|
||||||
|
{x=pos.x-width, y=pos.y, z=pos.z-width},
|
||||||
|
{x=pos.x+width, y=pos.y+height, z=pos.z+width}
|
||||||
|
)
|
||||||
|
return manip, VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function inform_grow(pos, t1, name, generated)
|
||||||
|
nether:inform(name.." grew at " .. minetest.pos_to_string(pos),
|
||||||
|
generated and 3 or 2, t1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_vm_data(manip, nodes, pos, t1, name, generated)
|
||||||
|
manip:set_data(nodes)
|
||||||
|
manip:write_to_map(not generated)
|
||||||
|
inform_grow(pos, t1, name, generated)
|
||||||
|
end
|
||||||
|
|
||||||
|
local c, contents_defined
|
||||||
|
local function define_contents()
|
||||||
|
if not contents_defined then
|
||||||
|
c = nether.query_contents()
|
||||||
|
contents_defined = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function grow_netherstructure_into_raw(area, nodes, pos, generated)
|
||||||
|
define_contents()
|
||||||
|
|
||||||
|
local height = netherstructure_height
|
||||||
|
|
||||||
|
local vi = area:indexp(pos)
|
||||||
|
for _ = 0, height-1 do
|
||||||
|
nodes[vi] = c.blood_stem
|
||||||
|
vi = vi + area.ystride
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = -1,1 do
|
||||||
|
for j = -1,1 do
|
||||||
|
nodes[area:index(pos.x+i, pos.y+height, pos.z+j)] = c.blood_top
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k = -1, 1, 2 do
|
||||||
|
for l = -2+1, 2 do
|
||||||
|
local p1 = {pos.x+2*k, pos.y+height, pos.z-l*k}
|
||||||
|
local p2 = {pos.x+l*k, pos.y+height, pos.z+2*k}
|
||||||
|
local udat = c.blood_top
|
||||||
|
if math.random(2) == 1 then
|
||||||
|
nodes[area:index(p1[1], p1[2], p1[3])] = c.blood_top
|
||||||
|
nodes[area:index(p2[1], p2[2], p2[3])] = c.blood_top
|
||||||
|
udat = c.blood
|
||||||
|
end
|
||||||
|
nodes[area:index(p1[1], p1[2]-1, p1[3])] = udat
|
||||||
|
nodes[area:index(p2[1], p2[2]-1, p2[3])] = udat
|
||||||
|
end
|
||||||
|
for l = 0, 1 do
|
||||||
|
for _,p in ipairs({
|
||||||
|
{pos.x+k, pos.y+height-1, pos.z-l*k},
|
||||||
|
{pos.x+l*k, pos.y+height-1, pos.z+k},
|
||||||
|
}) do
|
||||||
|
if math.random(2) == 1 then
|
||||||
|
nodes[area:index(p[1], p[2], p[3])] = c.nether_apple
|
||||||
|
--elseif math.random(10) == 1 then
|
||||||
|
-- nodes[area:index(p[1], p[2], p[3])] = c.apple
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function nether.grow_netherstructure_into(area, nodes, pos, generated)
|
||||||
|
local t1 = minetest.get_us_time()
|
||||||
|
|
||||||
|
if not pos.x then print(dump(pos))
|
||||||
|
nether:inform("Error: "..dump(pos), 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
grow_netherstructure_into_raw(area, nodes, pos, generated)
|
||||||
|
|
||||||
|
inform_grow(pos, t1, "blood", generated)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nether.grow_netherstructure(pos, generated)
|
||||||
|
local t1 = minetest.get_us_time()
|
||||||
|
|
||||||
|
if not pos.x then print(dump(pos))
|
||||||
|
nether:inform("Error: "..dump(pos), 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local height = netherstructure_height
|
||||||
|
local manip, area = vmanip_with_r_area(2, height, pos)
|
||||||
|
local nodes = manip:get_data()
|
||||||
|
|
||||||
|
grow_netherstructure_into_raw(area, nodes, pos, generated)
|
||||||
|
|
||||||
|
set_vm_data(manip, nodes, pos, t1, "blood", generated)
|
||||||
|
end
|
||||||
|
|
||||||
|
local poshash = minetest.hash_node_position
|
||||||
|
local pos_from_hash = minetest.get_position_from_hash
|
||||||
|
|
||||||
|
local function soft_node(id)
|
||||||
|
return id == c.air or id == c.ignore
|
||||||
|
end
|
||||||
|
|
||||||
|
local function update_minmax(min, max, p)
|
||||||
|
min.x = math.min(min.x, p.x)
|
||||||
|
max.x = math.max(max.x, p.x)
|
||||||
|
min.z = math.min(min.z, p.z)
|
||||||
|
max.z = math.max(max.z, p.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
local fruit_chances = {}
|
||||||
|
for y = -2,1 do --like a hyperbola
|
||||||
|
fruit_chances[y] = math.floor(-4/(y-2)+0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
local dirs = {
|
||||||
|
{-1, 0, 12, 19},
|
||||||
|
{1, 0, 12, 13},
|
||||||
|
{0, 1, 4},
|
||||||
|
{0, -1, 4, 10},
|
||||||
|
}
|
||||||
|
|
||||||
|
local h_max = 26
|
||||||
|
local h_stem_min = 3
|
||||||
|
local h_stem_max = 7
|
||||||
|
local h_arm_min = 2
|
||||||
|
local h_arm_max = 6
|
||||||
|
local r_arm_min = 1
|
||||||
|
local r_arm_max = 5
|
||||||
|
local fruit_rarity = 25 --a bigger number results in less fruits
|
||||||
|
local leaf_thickness = 3 --a bigger number results in more blank trees
|
||||||
|
|
||||||
|
local h_trunk_max = h_max-h_arm_max
|
||||||
|
|
||||||
|
function nether.grow_tree(pos, generated)
|
||||||
|
local t1 = minetest.get_us_time()
|
||||||
|
|
||||||
|
define_contents()
|
||||||
|
|
||||||
|
local min = vector.new(pos)
|
||||||
|
local max = vector.new(pos)
|
||||||
|
min.y = min.y-1
|
||||||
|
max.y = max.y+h_max
|
||||||
|
|
||||||
|
local trunks = {}
|
||||||
|
local trunk_corners = {}
|
||||||
|
local h_stem = math.random(h_stem_min, h_stem_max)
|
||||||
|
local todo,n = {{x=pos.x, y=pos.y+h_stem, z=pos.z}},1
|
||||||
|
while n do
|
||||||
|
local p = todo[n]
|
||||||
|
todo[n] = nil
|
||||||
|
n = next(todo)
|
||||||
|
|
||||||
|
local used_dirs,u = {},1
|
||||||
|
for _,dir in pairs(dirs) do
|
||||||
|
if math.random(1,2) == 1 then
|
||||||
|
used_dirs[u] = dir
|
||||||
|
u = u+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not used_dirs[1] then
|
||||||
|
local dir1 = math.random(4)
|
||||||
|
local dir2 = math.random(3)
|
||||||
|
if dir1 <= dir2 then
|
||||||
|
dir2 = dir2+1
|
||||||
|
end
|
||||||
|
used_dirs[1] = dirs[dir1]
|
||||||
|
used_dirs[2] = dirs[dir2]
|
||||||
|
end
|
||||||
|
for _,dir in pairs(used_dirs) do
|
||||||
|
local p = vector.new(p)
|
||||||
|
local r = math.random(r_arm_min, r_arm_max)
|
||||||
|
for j = 1,r do
|
||||||
|
local x = p.x+j*dir[1]
|
||||||
|
local z = p.z+j*dir[2]
|
||||||
|
trunks[poshash{x=x, y=p.y, z=z}] = dir[3]
|
||||||
|
end
|
||||||
|
r = r+1
|
||||||
|
p.x = p.x+r*dir[1]
|
||||||
|
p.z = p.z+r*dir[2]
|
||||||
|
trunk_corners[poshash(p)] = dir[4] or dir[3]
|
||||||
|
local h = math.random(h_arm_min, h_arm_max)
|
||||||
|
for i = 1,h do
|
||||||
|
p.y = p.y + i
|
||||||
|
trunks[poshash(p)] = true
|
||||||
|
p.y = p.y - i
|
||||||
|
end
|
||||||
|
p.y = p.y+h
|
||||||
|
--n = #todo+1 -- caused small trees
|
||||||
|
todo[#todo+1] = p
|
||||||
|
end
|
||||||
|
if p.y > pos.y+h_trunk_max then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
n = n or next(todo)
|
||||||
|
end
|
||||||
|
local leaves = {}
|
||||||
|
local fruits = {}
|
||||||
|
local trunk_ps = {}
|
||||||
|
local count = 0
|
||||||
|
|
||||||
|
local ps = {}
|
||||||
|
local trunk_count = 0
|
||||||
|
for i,par2 in pairs(trunks) do
|
||||||
|
local pos = pos_from_hash(i)
|
||||||
|
update_minmax(min, max, pos)
|
||||||
|
local z,y,x = pos.z, pos.y, pos.x
|
||||||
|
trunk_count = trunk_count+1
|
||||||
|
ps[trunk_count] = {z,y,x, par2}
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,d in pairs(ps) do
|
||||||
|
if d[4] == true then
|
||||||
|
d[4] = nil
|
||||||
|
end
|
||||||
|
trunk_ps[#trunk_ps+1] = d
|
||||||
|
local pz, py, px = unpack(d)
|
||||||
|
count = count+1
|
||||||
|
if count > leaf_thickness then
|
||||||
|
count = 0
|
||||||
|
for y = -2,2 do
|
||||||
|
local fruit_chance = fruit_chances[y]
|
||||||
|
for z = -2,2 do
|
||||||
|
for x = -2,2 do
|
||||||
|
local distq = x*x+y*y+z*z
|
||||||
|
if distq ~= 0
|
||||||
|
and math.random(1, math.sqrt(distq)) == 1 then
|
||||||
|
local x = x+px
|
||||||
|
local y = y+py
|
||||||
|
local z = z+pz
|
||||||
|
local vi = poshash{x=x, y=y, z=z}
|
||||||
|
if not trunks[vi] then
|
||||||
|
if fruit_chance
|
||||||
|
and math.random(1, fruit_rarity) == 1
|
||||||
|
and math.random(1, fruit_chance) == 1 then
|
||||||
|
fruits[vi] = true
|
||||||
|
else
|
||||||
|
leaves[vi] = true
|
||||||
|
end
|
||||||
|
update_minmax(min, max, {x=x, z=z})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--ps = nil
|
||||||
|
--collectgarbage()
|
||||||
|
|
||||||
|
for i = -1,h_stem+1 do
|
||||||
|
-- param2 explicitly set 0 due to possibly previous leaves node
|
||||||
|
trunk_ps[#trunk_ps+1] = {pos.z, pos.y+i, pos.x, 0}
|
||||||
|
end
|
||||||
|
|
||||||
|
local manip = minetest.get_voxel_manip()
|
||||||
|
local emerged_pos1, emerged_pos2 = manip:read_from_map(min, max)
|
||||||
|
local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
|
||||||
|
local nodes = manip:get_data()
|
||||||
|
local param2s = manip:get_param2_data()
|
||||||
|
|
||||||
|
for i in pairs(leaves) do
|
||||||
|
local p = area:indexp(pos_from_hash(i))
|
||||||
|
if soft_node(nodes[p]) then
|
||||||
|
nodes[p] = c.nether_leaves
|
||||||
|
param2s[p] = math.random(0,179)
|
||||||
|
--param2s[p] = math.random(0,44)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i in pairs(fruits) do
|
||||||
|
local p = area:indexp(pos_from_hash(i))
|
||||||
|
if soft_node(nodes[p]) then
|
||||||
|
nodes[p] = c.nether_apple
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1,#trunk_ps do
|
||||||
|
local p = trunk_ps[i]
|
||||||
|
local par = p[4]
|
||||||
|
p = area:index(p[3], p[2], p[1])
|
||||||
|
if par then
|
||||||
|
param2s[p] = par
|
||||||
|
end
|
||||||
|
nodes[p] = c.nether_tree
|
||||||
|
end
|
||||||
|
|
||||||
|
for i,par2 in pairs(trunk_corners) do
|
||||||
|
local vi = area:indexp(pos_from_hash(i))
|
||||||
|
nodes[vi] = c.nether_tree_corner
|
||||||
|
param2s[vi] = par2
|
||||||
|
end
|
||||||
|
|
||||||
|
manip:set_data(nodes)
|
||||||
|
manip:set_param2_data(param2s)
|
||||||
|
manip:write_to_map(not generated)
|
||||||
|
nether:inform("a nether tree with " .. trunk_count ..
|
||||||
|
" branch trunk nodes grew at " .. minetest.pos_to_string(pos),
|
||||||
|
generated and 3 or 2, t1)
|
||||||
|
end
|
652
nether/guide.lua
652
nether/guide.lua
@ -1,427 +1,238 @@
|
|||||||
local cube = minetest.inventorycube
|
-- The content of the guide
|
||||||
|
|
||||||
-- the content of the guide
|
|
||||||
local guide_infos = {
|
local guide_infos = {
|
||||||
{
|
{"Nether Mushroom",
|
||||||
description = "Mushrooms",
|
[[Nether mushrooms can be found on the nether's ground and on Dirty Netherrack. They can be dug by hand.
|
||||||
{"text", "Nether mushrooms can be found on the nether's ground and\n"..
|
<item name=riesenpilz:nether_shroom width=100>
|
||||||
"on netherrack soil, it can be dug by hand."},
|
|
||||||
{"image", {1, 1, "riesenpilz_nether_shroom_side.png"}},
|
<my_h2><b>Crafting Items</b></my_h2>
|
||||||
{"y", 0.2},
|
If we drop a Nether mushroom without holding the fast key, we can split it into its stem and head. We can use them to craft a Nether Mushroom Pickaxe, a Nether Blood Extractor, and an uncooked Nether Pearl.
|
||||||
{"text", "If you drop it without holding the fast key, you can split it into its stem and head:"},
|
<item name=nether:shroom_head width=100> <item name=nether:shroom_stem width=100>
|
||||||
{"image", {1, 1, "nether_shroom_top.png", 1}},
|
|
||||||
{"image", {1, 1, "nether_shroom_stem.png"}},
|
<my_h2><b>Cultivating Mushrooms</b></my_h2>
|
||||||
{"y", 0.1},
|
We can get more mushrooms using Dirty Netherrack:
|
||||||
{"text", "You can get more mushrooms by using a netherrack soil:\n"..
|
1. Search a dark place (light level <= 7) and, if necessary, place Netherrack with air above it
|
||||||
"1. search a dark place and, if necessary, place netherrack with air about it\n"..
|
<img name=nether_netherrack.png width=100>
|
||||||
"2. right click with cooked blood onto the netherrack to make it soiled\n"..
|
2. Right click with Cooked Blood onto the Netherrack to turn it into Dirty Netherrack
|
||||||
"3. right click onto the netherrack soil with a nether mushroom head to add some spores\n"..
|
<item name=nether:hotbed width=100> <img name=nether_netherrack.png^nether_netherrack_soil.png width=100>
|
||||||
"4. dig the mushroom which grew after some time to make place for another one"},
|
3. Right click onto the Dirty Netherrack with a Nether mushroom head to add some spores
|
||||||
{"image", {1, 1, "riesenpilz_nether_shroom_side.png", 6, 0.12}},
|
<item name=nether:shroom_head width=100> <img name=nether_netherrack.png^nether_netherrack_soil.png width=100>
|
||||||
{"y", 1},
|
4. Wait
|
||||||
{"image", {1, 1, "nether_netherrack.png^nether_netherrack_soil.png", 1.8}},
|
5. Dig the Nether mushroom which grew after some time to make place for another one. After some time new spores need to be added (step 3).
|
||||||
{"image", {1, 1, "nether_hotbed.png", 1.3, -0.4}},
|
<img name=riesenpilz_nether_shroom_side.png width=100>
|
||||||
{"image", {1, 1, "nether_netherrack.png^nether_netherrack_soil.png", 3.6}},
|
<img name=nether_netherrack.png^nether_netherrack_soil.png width=100>
|
||||||
{"image", {1, 1, "nether_shroom_top.png", 3.1, -0.5}},
|
]]},
|
||||||
{"image", {1, 1, "nether_netherrack.png^nether_netherrack_soil.png", 6}},
|
|
||||||
{"image", {1, 1, "nether_netherrack.png"}},
|
{"Blood Structures",
|
||||||
},
|
[[We can find blood structures on the ground and dig their nodes with the bare hand. They contain four kinds of nodes: Nether Blood Stem, Nether Blood, Nether Blood Head, and Nether Fruit.
|
||||||
{
|
<item name=nether:blood_stem width=100> <item name=nether:blood width=100> <item name=nether:apple width=100>
|
||||||
description = "Tools",
|
We can craft four Nether Blood Wood nodes with the stem.
|
||||||
{"text", "You can craft 5 kinds of tools in the nether,\n"..
|
<item name=nether:wood width=100>
|
||||||
"which (except the mushroom pick) require sticks to be crafted:"},
|
The four red blood nodes can be cooked in a furnace and, except Nether Blood Wood, their blood can be extracted with a Nether Blood Extractor.
|
||||||
{"image", {1, 1, "nether_pick_mushroom.png"}},
|
|
||||||
{"y", 0.1},
|
<my_h2><b>Nether Fruit</b></my_h2>
|
||||||
{"text", "strength : 1\n"..
|
<item name=nether:apple width=100>
|
||||||
"The mushroom pick needs mushroom stems and heads to be crafted."},
|
Eating a Nether Fruit decreases life but it might work against hunger and give us blood:
|
||||||
{"image", {1, 1, "nether_pick_wood.png"}},
|
<item name=nether:blood_extracted width=100>
|
||||||
{"y", 0.1},
|
If we eat it at the right place inside a portal, we will teleport instead of getting blood.
|
||||||
{"text", "strength : 2\n"..
|
If we drop it without holding the fast key, we can split it into its fruit and leaf:
|
||||||
"The nether wood pick can be crafted with cooked nether blood wood."},
|
<item name=nether:fruit_leaf width=100> <item name=nether:fruit_no_leaf width=100>
|
||||||
{"image", {1, 1, "nether_axe_netherrack.png", 1.5}},
|
We can craft a fruit leave block out of 9 fruit leaves
|
||||||
{"image", {1, 1, "nether_shovel_netherrack.png", 3}},
|
The fruit can be used to craft a nether pearl.
|
||||||
{"image", {1, 1, "nether_sword_netherrack.png", 4.5}},
|
<item name=nether:fruit_leaves width=100>
|
||||||
{"image", {1, 1, "nether_pick_netherrack.png"}},
|
A fruit leaves block
|
||||||
{"y", 0.1},
|
|
||||||
{"text", "strength : 3\n"..
|
<my_h2><b>Cultivating Blood Structures</b></my_h2>
|
||||||
"The red netherrack tools can be crafted with usual netherrack."},
|
If we dig a Nether vine we get a Nether Blood Child. If this sapling is put in a dark place (light level <= 3) on top of a Nether Blood Head node, it grows into a new blood structure after some time.
|
||||||
{"image", {1, 1, "nether_axe_netherrack_blue.png", 1.5}},
|
<img name=nether_sapling.png width=100>
|
||||||
{"image", {1, 1, "nether_shovel_netherrack_blue.png", 3}},
|
<img name=nether_blood.png^nether_blood_side.png width=100>
|
||||||
{"image", {1, 1, "nether_sword_netherrack_blue.png", 4.5}},
|
]]},
|
||||||
{"image", {1, 1, "nether_pick_netherrack_blue.png"}},
|
|
||||||
{"y", 0.1},
|
{"Tools",
|
||||||
{"text", "strength : 3\n"..
|
[[We can craft five kinds of tools in the nether, which (except the Nether Mushroom Pickaxe) require sticks to be crafted. To obtain Nether Sticks we can use the Nether Blood Extractor.
|
||||||
"The blue netherrack tools can be crafted with blue netherrack."},
|
|
||||||
{"image", {1, 1, "nether_axe_white.png", 1.5}},
|
<my_h2><b>Nether Mushroom Pickaxe</b></my_h2>
|
||||||
{"image", {1, 1, "nether_shovel_white.png", 3}},
|
<item name=nether:pick_mushroom width=100>
|
||||||
{"image", {1, 1, "nether_sword_white.png", 4.5}},
|
Strength: 1
|
||||||
{"image", {1, 1, "nether_pick_white.png"}},
|
This pickaxe needs mushroom stems and heads to be crafted.
|
||||||
{"y", 0.1},
|
|
||||||
{"text", "strength : 3\n"..
|
<my_h2><b>Nether Wood Pickaxe</b></my_h2>
|
||||||
"The siwtonic tools can be crafted with the siwtonic ore."},
|
<item name=nether:pick_wood width=100>
|
||||||
},
|
Strength: 2
|
||||||
{
|
This pickaxe can be crafted with Cooked Nether Blood Wood.
|
||||||
description = "Blood structures",
|
|
||||||
{"text", "You can find blood structures on the ground and\n"..
|
<my_h2><b>Netherrack Tools</b></my_h2>
|
||||||
"dig their nodes even with the bare hand."},
|
<item name=nether:axe_netherrack width=100> <item name=nether:shovel_netherrack width=100> <item name=nether:sword_netherrack width=100> <item name=nether:pick_netherrack width=100>
|
||||||
{"y", 0.5},
|
Strength: 3
|
||||||
{"text", "One contains 4 kinds of blocks :"},
|
The red Netherrack tools can be crafted with usual Netherrack.
|
||||||
{"image", {1, 1, cube("nether_blood.png"), 1}},
|
|
||||||
{"image", {1, 1,
|
<my_h2><b>Faster Tools</b></my_h2>
|
||||||
cube("nether_blood_top.png",
|
<item name=nether:axe_netherrack_blue width=100> <item name=nether:shovel_netherrack_blue width=100> <item name=nether:sword_netherrack_blue width=100> <item name=nether:pick_netherrack_blue width=100>
|
||||||
"nether_blood.png^nether_blood_side.png",
|
Strength: 3
|
||||||
"nether_blood.png^nether_blood_side.png"),
|
The blue Netherrack tools can be crafted with Blue Netherrack.
|
||||||
2}},
|
|
||||||
{"image", {1, 1, "nether_fruit.png", 3}},
|
<item name=nether:axe_white width=100> <item name=nether:shovel_white width=100> <item name=nether:sword_white width=100> <item name=nether:pick_white width=100>
|
||||||
{"image", {1, 1, cube("nether_blood_stem_top.png",
|
Strength: 3
|
||||||
"nether_blood_stem.png", "nether_blood_stem.png")}},
|
The Siwtonic tools can be crafted with the Siwtonic block.
|
||||||
{"y", 0.1},
|
]]},
|
||||||
{"text", "Blood stem, blood, blood head and nether fruit"},
|
|
||||||
{"y", 0.1},
|
{"Cooking",
|
||||||
{"text", "You can craft 4 blood wood with the stem :"},
|
[[To get a furnace we need to dig at least 8 Netherrack Bricks. They can be found at pyramid-like constructions and require at least a strength 1 nether pickaxe to be dug.
|
||||||
{"image", {1, 1, cube("nether_wood.png")}},
|
To begin cooking things, we can use a mushroom or fruit to power a furnace. After that it is recommended to use cooked blood nodes.
|
||||||
{"y", 0.1},
|
|
||||||
{"text", "The 4 blood nodes can be cooked and, except\n"..
|
<my_h2><b>Craft Recipe</b></my_h2>
|
||||||
"blood wood, their blood can be extracted."},
|
To craft the furnace, we can use the netherrack bricks like cobble:
|
||||||
},
|
<item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100>
|
||||||
{
|
<item name=nether:netherrack_brick width=100> <img name=nether_transparent.png width=100> <item name=nether:netherrack_brick width=100>
|
||||||
description = "Fruits",
|
<item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick width=100>
|
||||||
{"text", "You can find the nether fruits on blood structures\n"..
|
|
||||||
"and dig them even with the bare hand."},
|
<my_h2><b>Cooking Outputs</b></my_h2>
|
||||||
{"image", {1, 1, "nether_fruit.png"}},
|
Some nether items can be cooked, for example the Blood Structure's nodes.
|
||||||
{"text", "Eating it will make you lose life but\n"..
|
<item name=nether:blood_stem_cooked width=100> <item name=nether:blood_cooked width=100> <item name=nether:blood_top_cooked width=100> <item name=nether:wood_cooked width=100>
|
||||||
"it might feed you and give you blood :"},
|
Other cookable items are Blood and an item to get a Nether Pearl.
|
||||||
{"image", {1, 1, "nether_blood_extracted.png"}},
|
<item name=nether:hotbed width=100> <item name=nether:pearl width=100>
|
||||||
{"y", 0.2},
|
]]},
|
||||||
{"text", "If you eat it at the right place inside a portal,\n"..
|
|
||||||
"you will teleport instead of getting blood."},
|
{"Nether Blood Extractor",
|
||||||
{"y", 0.2},
|
[[With this extractor we can separate Blood from the Blood Structure's nodes. An alternative way to get Blood is to eat Nether Fruits. The Nether Blood Extractor enables us to obtain a Nether Blood Stem Extracted, which we can craft to (empty) Nether Wood and then to Nether Sticks.
|
||||||
{"text", "If you drop it without holding the fast key,\n"..
|
|
||||||
"you can split it into its fruit and leaf:"},
|
<my_h2><b>Craft Recipe</b></my_h2>
|
||||||
{"image", {1, 1, "nether_fruit_leaf.png", 1}},
|
We can craft the Nether Blood Extractor as follows:
|
||||||
{"image", {1, 1, "nether_fruit_no_leaf.png"}},
|
<item name=nether:netherrack_brick width=100> <item name=nether:blood_top_cooked width=100> <item name=nether:netherrack_brick width=100>
|
||||||
{"y", 0.2},
|
<item name=nether:blood_cooked width=100> <item name=nether:shroom_stem width=100> <item name=nether:blood_cooked width=100> <img name=nether_transparent.png width=100> <item name=nether:extractor width=100>
|
||||||
{"text", "Craft a fruit leave block out of 9 fruit leaves\n"..
|
<item name=nether:netherrack_brick width=100> <item name=nether:blood_stem_cooked width=100> <item name=nether:netherrack_brick width=100>
|
||||||
"The fruit can be used to craft a nether pearl."},
|
|
||||||
{"image", {1, 1, cube("nether_fruit_leaves.png")}},
|
<my_h2><b>Usage</b></my_h2>
|
||||||
{"y", 0.2},
|
We can feed the extractor with Blood to make it separate Blood from neighbouring nodes:
|
||||||
{"text", "A fruit leaves block"},
|
1. Place the Nether Blood Extractor somewhere
|
||||||
},
|
2. Place four or fewer Blood Structure's nodes next to it. Example viewed from the top:
|
||||||
{
|
<img name=nether_transparent.png width=100> <img name=nether_blood_stem_top.png width=100> <img name=nether_transparent.png width=100>
|
||||||
description = "Cooking",
|
<img name=nether_blood.png width=100> <img name=nether_blood_extractor.png width=100> <img name=nether_blood.png width=100>
|
||||||
{"text", "To get a furnace you need to dig at least 8 netherrack bricks.\n"..
|
<img name=nether_transparent.png width=100> <img name=nether_blood.png width=100> <img name=nether_transparent.png width=100>
|
||||||
"They can be found at pyramid like constructions and require at least\n"..
|
3. Right click the extractor with Blood to power it
|
||||||
"a strength 1 nether pick to be dug.\n"..
|
<img name=nether_transparent.png width=100> <img name=nether_blood_stem_top_empty.png width=100> <img name=nether_transparent.png width=100>
|
||||||
"To craft the furnace, use the netherrack bricks like cobble:"},
|
<img name=nether_blood_empty.png width=100> <img name=nether_blood_extractor.png width=100> <img name=nether_blood_empty.png width=100>
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 0.5}},
|
<img name=nether_transparent.png width=100> <img name=nether_blood_empty.png width=100> <img name=nether_transparent.png width=100>
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 1}},
|
4. Take the new extracted blood and dig the extracted nodes
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png")}},
|
]]},
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 1}},
|
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png")}},
|
{"Ores and Bricks",
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 0.5}},
|
[[Digging ores requires a pickaxe from the nether of a sufficient strength. Pickaxes from the overworld do not work in general.
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 1}},
|
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png")}},
|
<my_h2><b>Strength 1</b></my_h2>
|
||||||
{"y", 0.2},
|
<item name=glow:stone width=100>
|
||||||
{"text", "To begin cooking stuff, you can use a mushroom or fruit.\n"..
|
The Glowing stone can be dug with pickaxes from the overworld or a pickaxe from the nether with a strenght of least one. We can find it on the nether's and nether forest's ceiling and use it for lighting.
|
||||||
"After that it's recommended to use cooked blood nodes."},
|
|
||||||
{"y", 0.1},
|
<my_h2><b>Strength 2</b></my_h2>
|
||||||
{"text", "Some nether items can be cooked:"},
|
<item name=nether:netherrack width=100> <item name=nether:netherrack_tiled width=100> <item name=nether:netherrack_black width=100>
|
||||||
{"image", {1, 1, cube("nether_blood_stem_top_cooked.png",
|
The (red) Netherrack is generated like stone, Tiled Netherrack is generated like coal ore and the Black Netherrack is generated like gravel.
|
||||||
"nether_blood_stem_cooked.png", "nether_blood_stem_cooked.png"),
|
|
||||||
0.35}},
|
<my_h2><b>Strength 3</b></my_h2>
|
||||||
{"image", {1, 1, cube("nether_blood_cooked.png"), 1.6}},
|
<item name=nether:netherrack_blue width=100> <item name=nether:white width=100>
|
||||||
{"image", {1, 1,
|
The Blue Netherrack is generated like diamond ore and the Siwtonic block is generated like mese blocks.
|
||||||
cube("nether_blood_top_cooked.png",
|
|
||||||
"nether_blood_cooked.png^nether_blood_side_cooked.png",
|
<my_h2><b>Bricks</b></my_h2>
|
||||||
"nether_blood_cooked.png^nether_blood_side_cooked.png"),
|
There are three types of Bricks: red, Blue, and Black Netherrack Brick. We can craft them from the corresponding Netherrack nodes and additionally, the (red) Netherrack Brick is generated in pyramid-like structures in the nether. In comparison to the Netherrack nodes, all three Bricks can be dug with a pickaxe with strength 1.
|
||||||
2.9}},
|
<item name=nether:netherrack_brick width=100> <item name=nether:netherrack_brick_blue width=100> <item name=nether:netherrack_brick_black width=100>
|
||||||
{"image", {1, 1, cube("nether_wood_cooked.png"), 4.3}},
|
]]},
|
||||||
{"y", 1.2},
|
|
||||||
{"text", "Some cooked blood stem, cooked blood,\n"..
|
{"Nether Vines",
|
||||||
"cooked blood head and cooked blood wood,"},
|
[[Nether vines are at the ceiling of the nether and can be dug by hand. They drop Nether Blood Child nodes, from which we can grow Blood Structures. By feeding Blood to a Nether vine with air beneath it, it grows one node.
|
||||||
{"image", {1, 1, "nether_hotbed.png", 0.3}},
|
<item name=nether:vine width=100>
|
||||||
{"image", {1, 1, "nether_pearl.png", 2}},
|
]]},
|
||||||
{"y", 1.2},
|
|
||||||
{"text", "Some cooked extracted blood and a nether pearl"},
|
{"Portals",
|
||||||
},
|
[[This nether mod supports two types of portals: the well-known Minecraft-like one made of Obsidian, and a portal which is specific to this mod. The Obsidian portal allows us to reach the nether from the overworld, but it is one-way and kills us.
|
||||||
{
|
|
||||||
description = "Extractors",
|
<my_h2><b>Build Instructions</b></my_h2>
|
||||||
{"text", "Here you can find out information about the nether extractor."},
|
A nether portal requires the following nodes:
|
||||||
{"y", 0.2},
|
<item name=nether:wood_empty width=100> <item name=nether:netherrack_black width=100> <item name=nether:netherrack_brick_blue width=100> <item name=nether:netherrack width=100> <item name=nether:blood_cooked width=100> <item name=nether:apple width=100> <item name=nether:white width=100>
|
||||||
{"text", "Here you can see its craft recipe:"},
|
* 25 (empty) Nether Wood (height 5-6)
|
||||||
{"image", {0.5, 0.5, cube("nether_blood_top_cooked.png",
|
* 16 Black Netherrack (height 1)
|
||||||
"nether_blood_cooked.png^nether_blood_side_cooked.png",
|
* 12 Blue Netherrack Bricks (height 2-4)
|
||||||
"nether_blood_cooked.png^nether_blood_side_cooked.png"), 0.5}},
|
* 8 (red) Netherrack (height 1)
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 1}},
|
* 8 Cooked Nether Blood (height 5)
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png")}},
|
* 4 Nether Fruits (height 4)
|
||||||
{"image", {0.5, 0.5, cube("nether_blood_extractor.png"), 2.5}},
|
* 2 Siwtonic blocks (height 1 and 5)
|
||||||
{"image", {0.5, 0.5, "nether_shroom_stem.png", 0.5}},
|
|
||||||
{"image", {0.5, 0.5, cube("nether_blood_cooked.png"), 1}},
|
The heights in parenthesis correspond to the relative vertical positions of the nodes. When built, the portal should look approximately like this one:
|
||||||
{"image", {0.5, 0.5, cube("nether_blood_cooked.png")}},
|
<img name=nether_teleporter.png width=600>
|
||||||
{"image", {0.5, 0.5, cube("nether_blood_stem_top_cooked.png",
|
|
||||||
"nether_blood_stem_cooked.png", "nether_blood_stem_cooked.png"),
|
<my_h2><b>Usage</b></my_h2>
|
||||||
0.5}},
|
Before using the portal the first time, we may want to fill our inventory with enough items so that we can build a second portal on the overworld to get back.
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png"), 1}},
|
We can activate the portal as follows:
|
||||||
{"image", {0.5, 0.5, cube("nether_netherrack_brick.png")}},
|
1. Stand in the middle on the Siwtonic block
|
||||||
{"y", 0.2},
|
2. Eat a Nether Fruit. If the portal was built correctly, we can hear a special sound and are teleported to the overworld.
|
||||||
{"text", "Extract blood from the blood nodes you get from the blood structures.\n"..
|
|
||||||
"You can also get blood with a nether fruit."},
|
If two portals in the nether and overworld have the same X and Z coordinates, they teleport us to the centre, i.e. onto the Siwtonic block, of the opposite portal when eating a Nether Fruit.
|
||||||
{"y", 0.2},
|
]]},
|
||||||
{"text", "So you can use it:\n"..
|
|
||||||
"1. place it somewhere\n"..
|
{"Pearls",
|
||||||
"2. place blood blocks next to it (4 or less)\n"..
|
[[The nether pearl can be used to teleport by throwing it.
|
||||||
"3. right click with extracted blood onto it to power it\n"..
|
|
||||||
"4. take the new extracted blood and dig the extracted nodes"},
|
<my_h2><b>Craft Recipe</b></my_h2>
|
||||||
{"y", 0.2},
|
First, we need to craft two Nether Mushroom Heads and a Nether Fruit Without Leaf together as follows:
|
||||||
{"text", "Example (view from the top):"},
|
<item name=nether:shroom_head width=100>
|
||||||
{"y", 0.88},
|
<item name=nether:fruit_no_leaf width=100>
|
||||||
{"image", {1, 1, "nether_blood_stem_top.png", 0.82, -0.88}},
|
<item name=nether:shroom_head width=100>
|
||||||
{"image", {1, 1, "nether_blood.png", 1.63}},
|
This gives us the Nether Fruit in Mushroom (FIM), which we can cook in a furnace to obtain a Nether Pearl.
|
||||||
{"image", {1, 1, "nether_blood_extractor.png", 0.82}},
|
<item name=nether:fim width=100> <item name=nether:pearl width=100>
|
||||||
{"image", {1, 1, "nether_blood_stem_top_empty.png", 3.82, -0.88}},
|
]]},
|
||||||
{"image", {1, 1, "nether_blood_empty.png", 4.63}},
|
|
||||||
{"image", {1, 1, "nether_blood_empty.png", 3.001}},
|
{"Nether Forest",
|
||||||
{"image", {1, 1, "nether_blood_extractor.png", 3.82}},
|
[[The nether forest is generated in caves above the nether and contains decorative plants.
|
||||||
{"image", {1, 1, "nether_blood.png"}},
|
|
||||||
{"image", {1, 1, "nether_blood.png", 0.82, -0.12}},
|
<my_h2><b>Grass and Flower</b></my_h2>
|
||||||
{"image", {1, 1, "nether_blood_empty.png", 3.82, -0.12}},
|
<item name=nether:grass_big width=100> <item name=nether:grass_middle width=100> <item name=nether:grass_small width=100>
|
||||||
{"y", 1.2},
|
We can craft the Nether Grass item to another grass item, which can be cooked to get Dried Nether Grass. We can then craft this dried grass to paper.
|
||||||
{"text", "The empty blood stem can be crafted into empty nether wood,\n"..
|
|
||||||
"which can be crafted into nether sticks."},
|
<item name=nether:glowflower width=100>
|
||||||
},
|
The Glowing Flower can be used for lighting and decoration.
|
||||||
{
|
|
||||||
description = "Ores",
|
<my_h2><b>Nether Tree</b></my_h2>
|
||||||
{"text", "You can find 5 types of ores:"},
|
<item name=nether:tree width=100>
|
||||||
{"image", {1, 1, cube("nether_netherrack_black.png"), 4}},
|
Nether trunks can be found at Nether Trees and be crafted into Nether Wood Blocks via Nether Wood Planks. Furthermore, the Nether Tree Saplings grow even in the overworld if they have Nether Dirt beneath them.
|
||||||
{"image", {1, 1, cube("nether_netherrack.png")}},
|
]]}
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "The red netherrack is generated like stone.\n"..
|
|
||||||
"The black netherrack is generated like gravel.\n"..
|
|
||||||
"Both require at least a strength 2 nether pick to be dug."},
|
|
||||||
{"image", {1, 1, cube("nether_white.png"), 4}},
|
|
||||||
{"image", {1, 1, cube("nether_netherrack_blue.png")}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "The blue netherrack is generated like diamond ore.\n"..
|
|
||||||
"The siwtonic ore is generated like mese blocks.\n"..
|
|
||||||
"Both require at least a strength 3 nether pick to be dug."},
|
|
||||||
{"image", {1, 1, cube("nether_netherrack_tiled.png"), 4}},
|
|
||||||
{"image", {1, 1, cube("glow_stone.png")}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "Glow stone can be used for lighting.\n"..
|
|
||||||
"Tiled netherrack is generated like coal ore.\n"..
|
|
||||||
"Glow stone requires at least a strength 1 pick to be dug.\n"..
|
|
||||||
"Dig tiled netherrack with at least a level 2 pickaxe."},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description = "Vines",
|
|
||||||
{"text", "Feed nether vines with blood.\n"..
|
|
||||||
"Dig them with anything."},
|
|
||||||
{"image", {1, 1, "nether_vine.png"}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "Grow nether child by placing\n"..
|
|
||||||
"placing it to a dark place onto a\n"..
|
|
||||||
"blood structure head node."},
|
|
||||||
{"image", {1, 1, "nether_sapling.png"}},
|
|
||||||
{"y", -0.10},
|
|
||||||
{"image", {1, 1, "nether_blood.png^nether_blood_side.png"}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description = "Pearls",
|
|
||||||
{"text", "The nether pearl can be used to teleport by throwing it.\n"..
|
|
||||||
"Here is how to get one :"},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "First of all craft 2 mushroom heads and 1 nether fruit\n"..
|
|
||||||
"without leaf together :"},
|
|
||||||
{"image", {1, 1, "nether_shroom_top.png"}},
|
|
||||||
{"image", {1, 1, "nether_fim.png", 3}},
|
|
||||||
{"image", {1, 1, "nether_fruit_no_leaf.png"}},
|
|
||||||
{"image", {1, 1, "nether_shroom_top.png"}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "Put the result into the furnace\n"..
|
|
||||||
"to cook it into a nether pearl :"},
|
|
||||||
{"image", {1, 1, "nether_pearl.png"}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description = "Bricks",
|
|
||||||
{"text", "Craft bricks out of red,\n"..
|
|
||||||
"black and blue netherrack."},
|
|
||||||
{"image", {1, 1, cube("nether_netherrack_brick_black.png"), 1}},
|
|
||||||
{"image", {1, 1, cube("nether_netherrack_brick_blue.png"), 2}},
|
|
||||||
{"image", {1, 1, cube("nether_netherrack_brick.png")}},
|
|
||||||
{"y", 0.4},
|
|
||||||
{"text", "Dig them with at least a level 1 pickaxe."},
|
|
||||||
{"y", 0.2},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description = "Portals",
|
|
||||||
{"text", "Here you can find out how to built the nether portal."},
|
|
||||||
{"y", 0.3},
|
|
||||||
{"text", "A nether portal requires following nodes:"},
|
|
||||||
{"y", 0.05},
|
|
||||||
{"text", "25 empty nether wooden planks\n"..
|
|
||||||
"16 black netherrack\n"..
|
|
||||||
"12 blue netherrack bricks\n"..
|
|
||||||
"8 red netherrack\n"..
|
|
||||||
"8 cooked nether blood\n"..
|
|
||||||
"4 nether fruits\n"..
|
|
||||||
"2 siwtonic blocks"},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "It should look approximately like this one:"},
|
|
||||||
{"image", {5.625, 6, "nether_teleporter.png", 0, -1.5}},
|
|
||||||
{"y", 5.5},
|
|
||||||
{"text", "Activate it by standing in the middle,\n"..
|
|
||||||
"on the siwtonic block and eating a nether fruit.\n"..
|
|
||||||
"Take enough stuff with you to build a portal when you'll come back."},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description = "Forests",
|
|
||||||
{"text", "The nether forest is generated in caves,\n"..
|
|
||||||
"above the usual nether."},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "There you can find some plants:"},
|
|
||||||
{"image", {1, 1, "nether_grass_middle.png", 1}},
|
|
||||||
{"image", {1, 1, "nether_grass_big.png", 2}},
|
|
||||||
{"image", {1, 1, "nether_grass_small.png"}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "Use the nether forest grass to get paper.\n"..
|
|
||||||
"Craft paper out of the dried grass."},
|
|
||||||
{"image", {1, 1, cube("nether_tree_top.png", "nether_tree.png", "nether_tree.png")}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "Nether trunks can be found at nether trees.\n"..
|
|
||||||
"Craft nether wood out of nether trunk."},
|
|
||||||
{"image", {1, 1, "nether_glowflower.png"}},
|
|
||||||
{"y", 0.2},
|
|
||||||
{"text", "Use it for lighting and decoration."},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- the size of guide pages
|
-- The guide formspecs
|
||||||
local guide_size = {x=40, y=10, cx=0.2, cy=0.2}
|
local guide_forms = {}
|
||||||
|
|
||||||
-- informations about settings and ...
|
-- Convert the guide content to formspecs
|
||||||
local formspec_offset = {x=0.25, y=0.50}
|
|
||||||
local font_size
|
|
||||||
if minetest.is_singleplayer() then
|
|
||||||
font_size = tonumber(minetest.settings:get("font_size")) or 13
|
|
||||||
else
|
|
||||||
font_size = 13
|
|
||||||
end
|
|
||||||
guide_size.fx = math.floor((40*(guide_size.cx+formspec_offset.x))*font_size)
|
|
||||||
guide_size.fy = font_size/40
|
|
||||||
|
|
||||||
-- the default guide formspecs
|
|
||||||
local guide_forms = {
|
|
||||||
contents = "size[3.6,"..(#guide_infos)-2 ..";]label["..guide_size.cx+0.7 ..","..guide_size.cy+0.2 ..";Contents:]",
|
|
||||||
}
|
|
||||||
|
|
||||||
-- change the infos to formspecs
|
|
||||||
for n,data in ipairs(guide_infos) do
|
for n,data in ipairs(guide_infos) do
|
||||||
local html_text = ""
|
local title, html_content = data[1], data[2]
|
||||||
local form = ""
|
--~ local html_text = "<global background=#242424 size=24><tag name=my_h1 size=35>" ..
|
||||||
local y = 0
|
local html_text = "<global size=24><tag name=my_h1 size=35>" ..
|
||||||
local x = guide_size.cx
|
"<tag name=my_h2 size=30>" ..
|
||||||
for _,i in ipairs(data) do
|
"<my_h1><b><center>" .. title .. "</b></center></my_h1>\n" ..
|
||||||
local typ, content = unpack(i)
|
html_content
|
||||||
if typ == "y" then
|
local spec_width = 16
|
||||||
y = y+content
|
local spec_height = 16
|
||||||
elseif typ == "x" then
|
local html_padding = 0.5
|
||||||
x = math.max(x, content)
|
local form = ("formspec_version[4]size[%g,%g;]" ..
|
||||||
elseif typ == "text" then
|
"hypertext[%g,%g;%g,%g;html;%s]button[%g,%g;2,0.8;quit;Back]"
|
||||||
html_text = html_text .. content .. "\n"
|
|
||||||
local tab = minetest.wrap_text(content, guide_size.fx, true)
|
|
||||||
local l = guide_size.cx
|
|
||||||
for _,str in ipairs(tab) do
|
|
||||||
--~ form = form.."label["..guide_size.cx ..","..guide_size.cy+y..";"..str.."]"
|
|
||||||
y = y+guide_size.fy
|
|
||||||
l = math.max(l, #str)
|
|
||||||
end
|
|
||||||
x = math.max(x, l/font_size)
|
|
||||||
elseif typ == "image" then
|
|
||||||
local w, h, texture_name, px, py = unpack(content)
|
|
||||||
if not px then
|
|
||||||
--~ form = form.."image["..guide_size.cx..","..guide_size.cy+y+h*0.3 ..";"..w..","..h..";"..texture_name.."]"
|
|
||||||
html_text = html_text ..
|
|
||||||
("<img name=%s width=%g height=%g>\n"):format(
|
|
||||||
texture_name, w, h)
|
|
||||||
y = y+h
|
|
||||||
else
|
|
||||||
px = guide_size.cx+px
|
|
||||||
py = py or 0
|
|
||||||
html_text = html_text ..
|
|
||||||
("<img name=%s width=%g height=%g>\n"):format(
|
|
||||||
texture_name, w, h)
|
|
||||||
--~ form = form.."image["..px..","..
|
|
||||||
--~ guide_size.cy+y+h*0.3+py ..";"..w..","..h..";"..texture_name.."]"
|
|
||||||
x = math.max(x, px+w)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
form = ("formspec_version[4]size[%g,%g;]hypertext[0,0;%g,%g;html;%s]button[%g,%g;1,2;quit;Back]"
|
|
||||||
):format(
|
):format(
|
||||||
x * 1.8, y + 1,
|
spec_width, spec_height,
|
||||||
x * 1.8, y,
|
html_padding, html_padding,
|
||||||
|
spec_width - 2 * html_padding, spec_height - 1 - 2 * html_padding,
|
||||||
minetest.formspec_escape(html_text),
|
minetest.formspec_escape(html_text),
|
||||||
0.5 * x - 0.5, y)
|
0.5 * spec_width - 1, spec_height - 1)
|
||||||
|
|
||||||
guide_forms[n] = {data.description, form}
|
guide_forms[n] = {title, form}
|
||||||
end
|
end
|
||||||
print(dump(guide_forms))
|
|
||||||
--[[
|
|
||||||
for n,data in ipairs(guide_infos) do
|
|
||||||
local form = ""
|
|
||||||
local y = 0
|
|
||||||
local x = guide_size.cx
|
|
||||||
for _,i in ipairs(data) do
|
|
||||||
local typ, content = unpack(i)
|
|
||||||
if typ == "y" then
|
|
||||||
y = y+content
|
|
||||||
elseif typ == "x" then
|
|
||||||
x = math.max(x, content)
|
|
||||||
elseif typ == "text" then
|
|
||||||
local tab = minetest.wrap_text(content, guide_size.fx, true)
|
|
||||||
local l = guide_size.cx
|
|
||||||
for _,str in ipairs(tab) do
|
|
||||||
form = form.."label["..guide_size.cx ..","..guide_size.cy+y..";"..str.."]"
|
|
||||||
y = y+guide_size.fy
|
|
||||||
l = math.max(l, #str)
|
|
||||||
end
|
|
||||||
x = math.max(x, l/font_size)
|
|
||||||
elseif typ == "image" then
|
|
||||||
local w, h, texture_name, px, py = unpack(content)
|
|
||||||
if not px then
|
|
||||||
form = form.."image["..guide_size.cx..","..guide_size.cy+y+h*0.3 ..";"..w..","..h..";"..texture_name.."]"
|
|
||||||
y = y+h
|
|
||||||
else
|
|
||||||
px = guide_size.cx+px
|
|
||||||
py = py or 0
|
|
||||||
form = form.."image["..px..","..
|
|
||||||
guide_size.cy+y+h*0.3+py ..";"..w..","..h..";"..texture_name.."]"
|
|
||||||
x = math.max(x, px+w)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
form = "size["..x*1.8 ..","..y+1 ..";]"..form.."button["..x/2-0.5 ..","..y ..";1,2;quit;Back]"
|
|
||||||
guide_forms[n] = {data.description, form}
|
|
||||||
end
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local desc_tab = {}
|
local title_to_index = {}
|
||||||
for n, i in ipairs(guide_forms) do
|
for n, i in ipairs(guide_forms) do
|
||||||
desc_tab[i[1]] = n
|
title_to_index[i[1]] = n
|
||||||
end
|
end
|
||||||
|
|
||||||
-- creates contents formspec
|
-- Create the contents formspec
|
||||||
for y,i in ipairs(guide_forms) do
|
guide_forms.contents = "formspec_version[4]size[6," .. (#guide_infos) + 2 ..
|
||||||
local desc = i[1]
|
";]label[2,0.8;Contents:]"
|
||||||
local s = #desc * 1.3 / font_size + 1.5
|
for i, data in ipairs(guide_forms) do
|
||||||
|
local desc = data[1]
|
||||||
|
local y = i + 0.5 + 0.1
|
||||||
guide_forms.contents = guide_forms.contents ..
|
guide_forms.contents = guide_forms.contents ..
|
||||||
"button[" .. guide_size.cx * 12 / s - 0.5 .. "," ..
|
"button[0.5," .. y .. ";5,0.8;name;" .. desc .. "]"
|
||||||
guide_size.cy + y / 1.3 .. ";" .. s .. ",1;name;" .. desc .. "]"
|
|
||||||
end
|
|
||||||
|
|
||||||
-- shows the contents of the formspec
|
|
||||||
local function show_guide(pname)
|
|
||||||
minetest.show_formspec(pname, "nether_guide_contents", guide_forms["contents"])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
@ -430,14 +241,16 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
if fname
|
if fname
|
||||||
and pname then
|
and pname then
|
||||||
minetest.show_formspec(pname, "nether_guide", guide_forms[desc_tab[fname]][2])
|
minetest.show_formspec(pname, "nether_guide",
|
||||||
|
guide_forms[title_to_index[fname]][2])
|
||||||
end
|
end
|
||||||
elseif formname == "nether_guide" then
|
elseif formname == "nether_guide" then
|
||||||
local fname = fields.quit
|
local fname = fields.quit
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
if fname
|
if fname
|
||||||
and pname then
|
and pname then
|
||||||
minetest.show_formspec(pname, "nether_guide_contents", guide_forms["contents"])
|
minetest.show_formspec(pname, "nether_guide_contents",
|
||||||
|
guide_forms["contents"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@ -448,17 +261,16 @@ minetest.register_chatcommand("nether_help", {
|
|||||||
func = function(name)
|
func = function(name)
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
if not player then
|
if not player then
|
||||||
minetest.chat_send_player(name, "Something went wrong.")
|
return false, "Something went wrong."
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
if player:get_pos().y > nether.start then
|
if not nether.overworld_help and player:get_pos().y > nether.v.nether_start then
|
||||||
minetest.chat_send_player(name,
|
return false, "Usually you don't neet this guide here. " ..
|
||||||
"Usually you don't neet this guide here. " ..
|
"You can view it in the nether."
|
||||||
"You can view it in the nether.")
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
minetest.chat_send_player(name, "Showing guide...")
|
minetest.chat_send_player(name, "Showing guide...")
|
||||||
show_guide(name)
|
-- Show the Contents (overview) page
|
||||||
|
minetest.show_formspec(name, "nether_guide_contents",
|
||||||
|
guide_forms["contents"])
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
906
nether/init.lua
906
nether/init.lua
@ -17,891 +17,57 @@ if not rawget(_G, "nether") then
|
|||||||
nether = {}
|
nether = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--== EDITABLE OPTIONS ==--
|
-- similar to INIT
|
||||||
|
nether.env_type = "ssm" -- server-side-modding
|
||||||
|
|
||||||
-- Depth of the nether
|
nether.path = minetest.get_modpath("nether")
|
||||||
local nether_middle = -20000
|
local path = nether.path
|
||||||
|
|
||||||
-- forest bottom perlin multiplication
|
dofile(path .. "/common.lua")
|
||||||
local f_bottom_scale = 4
|
|
||||||
|
|
||||||
-- forest bottom height
|
|
||||||
local f_h_min = nether_middle+10
|
|
||||||
|
|
||||||
-- forest top height
|
|
||||||
local f_h_max = f_h_min+250
|
|
||||||
|
|
||||||
-- Frequency of trees in the nether forest (higher is less frequent)
|
|
||||||
local tree_rarity = 200
|
|
||||||
|
|
||||||
-- Frequency of glowflowers in the nether forest (higher is less frequent)
|
|
||||||
local glowflower_rarity = 120
|
|
||||||
|
|
||||||
-- Frequency of nether grass in the nether forest (higher is less frequent)
|
|
||||||
local grass_rarity = 2
|
|
||||||
|
|
||||||
-- Frequency of nether mushrooms in the nether forest (higher is less frequent)
|
|
||||||
local mushroom_rarity = 80
|
|
||||||
|
|
||||||
local abm_tree_interval = 864
|
|
||||||
local abm_tree_chance = 100
|
|
||||||
|
|
||||||
-- height of the nether generation's end
|
|
||||||
nether.start = f_h_max+100
|
|
||||||
|
|
||||||
-- Height of the nether (bottom of the nether is nether_middle - NETHER_HEIGHT)
|
|
||||||
local NETHER_HEIGHT = 30
|
|
||||||
|
|
||||||
-- Maximum amount of randomness in the map generation
|
|
||||||
local NETHER_RANDOM = 2
|
|
||||||
|
|
||||||
-- Frequency of Glowstone on the "roof" of the Nether (higher is less frequent)
|
|
||||||
local GLOWSTONE_FREQ_ROOF = 500
|
|
||||||
|
|
||||||
-- Frequency of lava (higher is less frequent)
|
|
||||||
local LAVA_FREQ = 100
|
|
||||||
|
|
||||||
local nether_structure_freq = 350
|
|
||||||
local NETHER_SHROOM_FREQ = 100
|
|
||||||
|
|
||||||
-- Maximum height of lava
|
|
||||||
--LAVA_HEIGHT = 2
|
|
||||||
-- Frequency of Glowstone on lava (higher is less frequent)
|
|
||||||
--GLOWSTONE_FREQ_LAVA = 2
|
|
||||||
-- Height of nether structures
|
|
||||||
--NETHER_TREESIZE = 2
|
|
||||||
-- Frequency of apples in a nether structure (higher is less frequent)
|
|
||||||
--NETHER_APPLE_FREQ = 5
|
|
||||||
-- Frequency of healing apples in a nether structure (higher is less frequent)
|
|
||||||
--NETHER_HEAL_APPLE_FREQ = 10
|
|
||||||
-- Start position for the Throne of Hades (y is relative to the bottom of the
|
|
||||||
-- nether)
|
|
||||||
--HADES_THRONE_STARTPOS = {x=0, y=1, z=0}
|
|
||||||
-- Spawn pos for when the nether hasn't been loaded yet (i.e. no portal in the
|
|
||||||
-- nether) (y is relative to the bottom of the nether)
|
|
||||||
--NETHER_SPAWNPOS = {x=0, y=5, z=0}
|
|
||||||
-- Structure of the nether portal (all is relative to the nether portal creator
|
|
||||||
-- block)
|
|
||||||
|
|
||||||
--== END OF EDITABLE OPTIONS ==--
|
|
||||||
|
|
||||||
local path = minetest.get_modpath"nether"
|
|
||||||
dofile(path .. "/settings.lua")
|
|
||||||
local nether_weird_noise = dofile(path .. "/weird_mapgen_noise.lua")
|
|
||||||
dofile(path .. "/items.lua")
|
dofile(path .. "/items.lua")
|
||||||
--dofile(path .. "/furnace.lua")
|
--dofile(path .. "/furnace.lua")
|
||||||
dofile(path .. "/pearl.lua")
|
dofile(path .. "/pearl.lua")
|
||||||
|
|
||||||
|
dofile(path .. "/grow_structures.lua")
|
||||||
|
|
||||||
if nether.log_level >= 1 then
|
if minetest.register_mapgen_script then
|
||||||
function nether:inform(msg, spam, t)
|
minetest.log("info", "nether mapgen running in mapgen env")
|
||||||
if spam <= self.log_level then
|
|
||||||
local info
|
minetest.register_mapgen_script(path .. "/init_emerge.lua")
|
||||||
if t then
|
|
||||||
info = "[nether] " .. msg .. (" after ca. %.3g s"):format(
|
minetest.set_gen_notify("custom", nil,
|
||||||
(minetest.get_us_time() - t) / 1000000)
|
{"nether:please_grow_trees", "nether:please_fix_light"})
|
||||||
else
|
|
||||||
info = "[nether] " .. msg
|
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
end
|
local t0 = minetest.get_us_time()
|
||||||
print(info)
|
|
||||||
if self.log_to_chat then
|
local gennotify = minetest.get_mapgen_object("gennotify")
|
||||||
minetest.chat_send_all(info)
|
|
||||||
end
|
-- forest trees
|
||||||
end
|
local trees_hashed = gennotify.custom["nether:please_grow_trees"] or {}
|
||||||
end
|
for i = 1, #trees_hashed do
|
||||||
else
|
local pos = minetest.get_position_from_hash(trees_hashed[i])
|
||||||
function nether.inform()
|
nether.grow_tree(pos, true)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if #trees_hashed > 0 then
|
||||||
-- Weierstrass function stuff from https://github.com/slemonide/gen
|
nether:inform(#trees_hashed .. " trees set", 2, t0)
|
||||||
local SIZE = 1000
|
|
||||||
local ssize = math.ceil(math.abs(SIZE))
|
|
||||||
local function do_ws_func(depth, a, x)
|
|
||||||
local n = math.pi * x / (16 * SIZE)
|
|
||||||
local y = 0
|
|
||||||
for k=1,depth do
|
|
||||||
y = y + math.sin(k^a * n) / k^a
|
|
||||||
end
|
|
||||||
return SIZE * y / math.pi
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local chunksize = minetest.settings:get"chunksize" or 5
|
-- fix light
|
||||||
local ws_lists = {}
|
local fixlight_area = gennotify.custom["nether:please_fix_light"]
|
||||||
local function get_ws_list(a,x)
|
if fixlight_area then
|
||||||
ws_lists[a] = ws_lists[a] or {}
|
t0 = minetest.get_us_time()
|
||||||
local v = ws_lists[a][x]
|
minetest.fix_light(fixlight_area[1], fixlight_area[2])
|
||||||
if v then
|
nether:inform("light fixed", 2, t0)
|
||||||
return v
|
|
||||||
end
|
end
|
||||||
v = {}
|
|
||||||
for x=x,x + (chunksize*16 - 1) do
|
|
||||||
local y = do_ws_func(ssize, a, x)
|
|
||||||
v[x] = y
|
|
||||||
end
|
|
||||||
ws_lists[a][x] = v
|
|
||||||
return v
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function dif(z1, z2)
|
|
||||||
return math.abs(z1-z2)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function pymg(x1, x2, z1, z2)
|
|
||||||
return math.max(dif(x1, x2), dif(z1, z2))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function r_area(manip, width, height, pos)
|
|
||||||
local emerged_pos1, emerged_pos2 = manip:read_from_map(
|
|
||||||
{x=pos.x-width, y=pos.y, z=pos.z-width},
|
|
||||||
{x=pos.x+width, y=pos.y+height, z=pos.z+width}
|
|
||||||
)
|
|
||||||
return VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function set_vm_data(manip, nodes, pos, t1, name, generated)
|
|
||||||
manip:set_data(nodes)
|
|
||||||
manip:write_to_map(not generated)
|
|
||||||
nether:inform(name.." grew at " .. minetest.pos_to_string(pos),
|
|
||||||
generated and 3 or 2, t1)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Generated variables
|
|
||||||
local NETHER_BOTTOM = (nether_middle - NETHER_HEIGHT)
|
|
||||||
nether.buildings = NETHER_BOTTOM+12
|
|
||||||
--~ local NETHER_ROOF_ABS = (nether_middle - NETHER_RANDOM)
|
|
||||||
local f_yscale_top = (f_h_max-f_h_min)/2
|
|
||||||
local f_yscale_bottom = f_yscale_top/2
|
|
||||||
--HADES_THRONE_STARTPOS_ABS = {x=HADES_THRONE_STARTPOS.x, y=(NETHER_BOTTOM +
|
|
||||||
--HADES_THRONE_STARTPOS.y), z=HADES_THRONE_STARTPOS.z}
|
|
||||||
--LAVA_Y = (NETHER_BOTTOM + LAVA_HEIGHT)
|
|
||||||
--HADES_THRONE_ABS = {}
|
|
||||||
--HADES_THRONE_ENDPOS_ABS = {}
|
|
||||||
--HADES_THRONE_GENERATED = minetest.get_worldpath() .. "/netherhadesthrone.txt"
|
|
||||||
--NETHER_SPAWNPOS_ABS = {x=NETHER_SPAWNPOS.x, y=(NETHER_BOTTOM +
|
|
||||||
--NETHER_SPAWNPOS.y), z=NETHER_SPAWNPOS.z}
|
|
||||||
--[[for i,v in ipairs(HADES_THRONE) do
|
|
||||||
v.pos.x = v.pos.x + HADES_THRONE_STARTPOS_ABS.x
|
|
||||||
v.pos.y = v.pos.y + HADES_THRONE_STARTPOS_ABS.y
|
|
||||||
v.pos.z = v.pos.z + HADES_THRONE_STARTPOS_ABS.z
|
|
||||||
HADES_THRONE_ABS[i] = v
|
|
||||||
end
|
|
||||||
local htx = 0
|
|
||||||
local hty = 0
|
|
||||||
local htz = 0
|
|
||||||
for i,v in ipairs(HADES_THRONE_ABS) do
|
|
||||||
if v.pos.x > htx then
|
|
||||||
htx = v.pos.x
|
|
||||||
end
|
|
||||||
if v.pos.y > hty then
|
|
||||||
hty = v.pos.y
|
|
||||||
end
|
|
||||||
if v.pos.z > htz then
|
|
||||||
htz = v.pos.z
|
|
||||||
end
|
|
||||||
end
|
|
||||||
HADES_THRONE_ENDPOS_ABS = {x=htx, y=hty, z=htz}]]
|
|
||||||
|
|
||||||
local c, nether_tree_nodes
|
|
||||||
local function define_contents()
|
|
||||||
c = {
|
|
||||||
ignore = minetest.get_content_id("ignore"),
|
|
||||||
air = minetest.get_content_id("air"),
|
|
||||||
lava = minetest.get_content_id("default:lava_source"),
|
|
||||||
gravel = minetest.get_content_id("default:gravel"),
|
|
||||||
coal = minetest.get_content_id("default:stone_with_coal"),
|
|
||||||
diamond = minetest.get_content_id("default:stone_with_diamond"),
|
|
||||||
mese = minetest.get_content_id("default:mese"),
|
|
||||||
|
|
||||||
--https://github.com/Zeg9/minetest-glow
|
|
||||||
glowstone = minetest.get_content_id("glow:stone"),
|
|
||||||
|
|
||||||
nether_shroom = minetest.get_content_id("riesenpilz:nether_shroom"),
|
|
||||||
|
|
||||||
netherrack = minetest.get_content_id("nether:netherrack"),
|
|
||||||
netherrack_tiled = minetest.get_content_id("nether:netherrack_tiled"),
|
|
||||||
netherrack_black = minetest.get_content_id("nether:netherrack_black"),
|
|
||||||
netherrack_blue = minetest.get_content_id("nether:netherrack_blue"),
|
|
||||||
netherrack_brick = minetest.get_content_id("nether:netherrack_brick"),
|
|
||||||
white = minetest.get_content_id("nether:white"),
|
|
||||||
|
|
||||||
nether_vine = minetest.get_content_id("nether:vine"),
|
|
||||||
blood = minetest.get_content_id("nether:blood"),
|
|
||||||
blood_top = minetest.get_content_id("nether:blood_top"),
|
|
||||||
blood_stem = minetest.get_content_id("nether:blood_stem"),
|
|
||||||
nether_apple = minetest.get_content_id("nether:apple"),
|
|
||||||
|
|
||||||
nether_tree = minetest.get_content_id("nether:tree"),
|
|
||||||
nether_tree_corner = minetest.get_content_id("nether:tree_corner"),
|
|
||||||
nether_leaves = minetest.get_content_id("nether:leaves"),
|
|
||||||
nether_grass = {
|
|
||||||
minetest.get_content_id("nether:grass_small"),
|
|
||||||
minetest.get_content_id("nether:grass_middle"),
|
|
||||||
minetest.get_content_id("nether:grass_big")
|
|
||||||
},
|
|
||||||
glowflower = minetest.get_content_id("nether:glowflower"),
|
|
||||||
nether_dirt = minetest.get_content_id("nether:dirt"),
|
|
||||||
nether_dirt_top = minetest.get_content_id("nether:dirt_top"),
|
|
||||||
nether_dirt_bottom = minetest.get_content_id("nether:dirt_bottom"),
|
|
||||||
}
|
|
||||||
local trn = {c.nether_tree, c.nether_tree_corner, c.nether_leaves,
|
|
||||||
c.nether_fruit}
|
|
||||||
nether_tree_nodes = {}
|
|
||||||
for i = 1,#trn do
|
|
||||||
nether_tree_nodes[trn[i]] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local pr, contents_defined
|
|
||||||
|
|
||||||
local function return_nether_ore(id, glowstone)
|
|
||||||
if glowstone
|
|
||||||
and pr:next(0,GLOWSTONE_FREQ_ROOF) == 1 then
|
|
||||||
return c.glowstone
|
|
||||||
end
|
|
||||||
if id == c.coal then
|
|
||||||
return c.netherrack_tiled
|
|
||||||
end
|
|
||||||
if id == c.gravel then
|
|
||||||
return c.netherrack_black
|
|
||||||
end
|
|
||||||
if id == c.diamond then
|
|
||||||
return c.netherrack_blue
|
|
||||||
end
|
|
||||||
if id == c.mese then
|
|
||||||
return c.white
|
|
||||||
end
|
|
||||||
return c.netherrack
|
|
||||||
end
|
|
||||||
|
|
||||||
local f_perlins = {}
|
|
||||||
|
|
||||||
-- abs(v) < 1-(persistance^octaves))/(1-persistance) = amp
|
|
||||||
--local perlin1 = minetest.get_perlin(13,3, 0.5, 50) --Get map specific perlin
|
|
||||||
-- local perlin2 = minetest.get_perlin(133,3, 0.5, 10)
|
|
||||||
-- local perlin3 = minetest.get_perlin(112,3, 0.5, 5)
|
|
||||||
local tmp = f_yscale_top*4
|
|
||||||
local tmp2 = tmp/f_bottom_scale
|
|
||||||
local perlins = {
|
|
||||||
{ -- amp 1.75
|
|
||||||
seed = 13,
|
|
||||||
octaves = 3,
|
|
||||||
persist = 0.5,
|
|
||||||
spread = {x=50, y=50, z=50},
|
|
||||||
scale = 1,
|
|
||||||
offset = 0,
|
|
||||||
},
|
|
||||||
{-- amp 1.75
|
|
||||||
seed = 133,
|
|
||||||
octaves = 3,
|
|
||||||
persist = 0.5,
|
|
||||||
spread = {x=10, y=10, z=10},
|
|
||||||
scale = 1,
|
|
||||||
offset = 0,
|
|
||||||
},
|
|
||||||
{-- amp 1.75
|
|
||||||
seed = 112,
|
|
||||||
octaves = 3,
|
|
||||||
persist = 0.5,
|
|
||||||
spread = {x=5, y=5, z=5},
|
|
||||||
scale = 1,
|
|
||||||
offset = 0,
|
|
||||||
},
|
|
||||||
--[[forest_bottom = {
|
|
||||||
seed = 11,
|
|
||||||
octaves = 3,
|
|
||||||
persist = 0.8,
|
|
||||||
spread = {x=tmp2, y=tmp2, z=tmp2},
|
|
||||||
scale = 1,
|
|
||||||
offset = 0,
|
|
||||||
},]]
|
|
||||||
forest_top = {-- amp 2.44
|
|
||||||
seed = 21,
|
|
||||||
octaves = 3,
|
|
||||||
persist = 0.8,
|
|
||||||
spread = {x=tmp, y=tmp, z=tmp},
|
|
||||||
scale = 1,
|
|
||||||
offset = 0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- buffers, see https://forum.minetest.net/viewtopic.php?f=18&t=16043
|
|
||||||
local pelin_maps
|
|
||||||
local pmap1 = {}
|
|
||||||
local pmap2 = {}
|
|
||||||
local pmap3 = {}
|
|
||||||
local pmap_f_top = {}
|
|
||||||
local data = {}
|
|
||||||
|
|
||||||
local structures_enabled = true
|
|
||||||
local vine_maxlength = math.floor(NETHER_HEIGHT/4+0.5)
|
|
||||||
-- Create the Nether
|
|
||||||
minetest.register_on_generated(function(minp, maxp, seed)
|
|
||||||
--avoid big map generation
|
|
||||||
if not (maxp.y >= NETHER_BOTTOM-100 and minp.y <= nether.start) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local t1 = minetest.get_us_time()
|
|
||||||
nether:inform("generates at: x=["..minp.x.."; "..maxp.x.."]; y=[" ..
|
|
||||||
minp.y.."; "..maxp.y.."]; z=["..minp.z.."; "..maxp.z.."]", 2)
|
|
||||||
|
|
||||||
if not contents_defined then
|
|
||||||
define_contents()
|
|
||||||
contents_defined = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local buildings = 0
|
|
||||||
if maxp.y <= NETHER_BOTTOM then
|
|
||||||
buildings = 1
|
|
||||||
elseif minp.y <= nether.buildings then
|
|
||||||
buildings = 2
|
|
||||||
end
|
|
||||||
|
|
||||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
||||||
vm:get_data(data)
|
|
||||||
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
|
||||||
|
|
||||||
pr = PseudoRandom(seed+33)
|
|
||||||
local tab,num = {},1
|
|
||||||
local trees,num_trees = {},1
|
|
||||||
|
|
||||||
--local perlin1 = minetest.get_perlin(13,3, 0.5, 50)
|
|
||||||
--local perlin2 = minetest.get_perlin(133,3, 0.5, 10)
|
|
||||||
--local perlin3 = minetest.get_perlin(112,3, 0.5, 5)
|
|
||||||
|
|
||||||
local side_length = maxp.x - minp.x + 1
|
|
||||||
local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
|
|
||||||
|
|
||||||
if not pelin_maps then
|
|
||||||
pelin_maps = {
|
|
||||||
a = minetest.get_perlin_map(perlins[1], map_lengths_xyz),
|
|
||||||
b = minetest.get_perlin_map(perlins[2], map_lengths_xyz),
|
|
||||||
c = minetest.get_perlin_map(perlins[3], map_lengths_xyz),
|
|
||||||
forest_top = minetest.get_perlin_map(perlins.forest_top,
|
|
||||||
map_lengths_xyz),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
pelin_maps.a:get_2d_map_flat({x=minp.x, y=minp.z}, pmap1)
|
|
||||||
pelin_maps.b:get_2d_map_flat({x=minp.x, y=minp.z}, pmap2)
|
|
||||||
pelin_maps.c:get_2d_map_flat({x=minp.x, y=minp.z}, pmap3)
|
|
||||||
|
|
||||||
local forest_possible = maxp.y > f_h_min and minp.y < f_h_max
|
|
||||||
|
|
||||||
--local pmap_f_bottom = minetest.get_perlin_map(perlins.forest_bottom,
|
|
||||||
-- map_lengths_xyz):get_2d_map_flat({x=minp.x, y=minp.z})
|
|
||||||
local perlin_f_bottom, strassx, strassz
|
|
||||||
if forest_possible then
|
|
||||||
perlin_f_bottom = minetest.get_perlin(11, 3, 0.8, tmp2)
|
|
||||||
pelin_maps.forest_top:get_2d_map_flat({x=minp.x, y=minp.z}, pmap_f_top)
|
|
||||||
strassx = get_ws_list(2, minp.x)
|
|
||||||
strassz = get_ws_list(2, minp.z)
|
|
||||||
end
|
|
||||||
|
|
||||||
local num2, tab2
|
|
||||||
if buildings >= 1 then
|
|
||||||
num2 = 1
|
|
||||||
tab2 = nether_weird_noise({x=minp.x, y=nether.buildings-79, z=minp.z},
|
|
||||||
pymg, 200, 8, 10, side_length-1)
|
|
||||||
end
|
|
||||||
|
|
||||||
local count = 0
|
|
||||||
for z=minp.z, maxp.z do
|
|
||||||
for x=minp.x, maxp.x do
|
|
||||||
|
|
||||||
count = count+1
|
|
||||||
|
|
||||||
local test = pmap1[count]+1
|
|
||||||
local test2 = pmap2[count]
|
|
||||||
local test3 = math.abs(pmap3[count])
|
|
||||||
|
|
||||||
local t = math.floor(test*3+0.5)
|
|
||||||
|
|
||||||
local h
|
|
||||||
if test2 < 0 then
|
|
||||||
h = math.floor(test2*3+0.5)-1
|
|
||||||
else
|
|
||||||
h = 3+t+pr:next(0,NETHER_RANDOM)
|
|
||||||
end
|
|
||||||
|
|
||||||
local generate_vine = false
|
|
||||||
if test3 >= 0.72+pr:next(0,NETHER_RANDOM)/10
|
|
||||||
and pr:next(0,NETHER_RANDOM) == 1 then
|
|
||||||
generate_vine = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local bottom = NETHER_BOTTOM+h
|
|
||||||
local top = nether_middle-pr:next(0,NETHER_RANDOM)+t
|
|
||||||
|
|
||||||
local py_h = 0
|
|
||||||
local difn, noisp, py_h_g
|
|
||||||
if buildings >= 1 then
|
|
||||||
py_h = tab2[num2].y
|
|
||||||
num2 = num2+1
|
|
||||||
|
|
||||||
difn = nether.buildings-py_h
|
|
||||||
if difn == 5 then
|
|
||||||
noisp = 1
|
|
||||||
elseif difn < 5 then
|
|
||||||
noisp = 2
|
|
||||||
end
|
|
||||||
py_h_g = nether.buildings-7
|
|
||||||
end
|
|
||||||
|
|
||||||
local vi = area:index(x, minp.y, z)
|
|
||||||
if buildings == 1
|
|
||||||
and noisp then
|
|
||||||
if noisp == 1 then
|
|
||||||
for _ = 1,side_length do
|
|
||||||
data[vi] = c.netherrack_brick
|
|
||||||
vi = vi + area.ystride
|
|
||||||
end
|
|
||||||
else
|
|
||||||
for _ = 1,side_length do
|
|
||||||
data[vi] = c.lava
|
|
||||||
vi = vi + area.ystride
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
|
|
||||||
local r_structure = pr:next(1,nether_structure_freq)
|
|
||||||
local r_shroom = pr:next(1,NETHER_SHROOM_FREQ)
|
|
||||||
local r_glowstone = pr:next(0,GLOWSTONE_FREQ_ROOF)
|
|
||||||
local r_vine_length = pr:next(1,vine_maxlength)
|
|
||||||
|
|
||||||
local f_bottom, f_top, is_forest, f_h_dirt
|
|
||||||
if forest_possible then
|
|
||||||
local p = {x=math.floor(x/f_bottom_scale),
|
|
||||||
z=math.floor(z/f_bottom_scale)}
|
|
||||||
local pstr = p.x.." "..p.z
|
|
||||||
if not f_perlins[pstr] then
|
|
||||||
f_perlins[pstr] = math.floor(f_h_min + (math.abs(
|
|
||||||
perlin_f_bottom:get_2d{x=p.x, y=p.z} + 1))
|
|
||||||
* f_yscale_bottom + 0.5)
|
|
||||||
end
|
|
||||||
local top_noise = pmap_f_top[count]+1
|
|
||||||
if top_noise < 0 then
|
|
||||||
top_noise = -top_noise/10
|
|
||||||
--nether:inform("ERROR: (perlin noise) "..
|
|
||||||
-- pmap_f_top[count].." is not inside [-1; 1]", 1)
|
|
||||||
end
|
|
||||||
f_top = math.floor(f_h_max - top_noise*f_yscale_top + 0.5)
|
|
||||||
f_bottom = f_perlins[pstr]+pr:next(0,f_bottom_scale-1)
|
|
||||||
is_forest = f_bottom < f_top
|
|
||||||
f_h_dirt = f_bottom-pr:next(0,1)
|
|
||||||
end
|
|
||||||
|
|
||||||
for y=minp.y, maxp.y do
|
|
||||||
local d_p_addp = data[vi]
|
|
||||||
--if py_h >= maxp.y-4 then
|
|
||||||
if y <= py_h
|
|
||||||
and noisp then
|
|
||||||
if noisp == 1 then
|
|
||||||
data[vi] = c.netherrack_brick
|
|
||||||
elseif noisp == 2 then
|
|
||||||
if y == py_h then
|
|
||||||
data[vi] = c.netherrack_brick
|
|
||||||
elseif y == py_h_g
|
|
||||||
and pr:next(1,3) <= 2 then
|
|
||||||
data[vi] = c.netherrack
|
|
||||||
elseif y <= py_h_g then
|
|
||||||
data[vi] = c.lava
|
|
||||||
else
|
|
||||||
data[vi] = c.air
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif d_p_addp ~= c.air then
|
|
||||||
|
|
||||||
if is_forest
|
|
||||||
and y == f_bottom then
|
|
||||||
data[vi] = c.nether_dirt_top
|
|
||||||
elseif is_forest
|
|
||||||
and y < f_bottom
|
|
||||||
and y >= f_h_dirt then
|
|
||||||
data[vi] = c.nether_dirt
|
|
||||||
elseif is_forest
|
|
||||||
and y == f_h_dirt-1 then
|
|
||||||
data[vi] = c.nether_dirt_bottom
|
|
||||||
elseif is_forest
|
|
||||||
and y == f_h_dirt+1 then
|
|
||||||
if pr:next(1,tree_rarity) == 1 then
|
|
||||||
trees[num_trees] = {x=x, y=y, z=z}
|
|
||||||
num_trees = num_trees+1
|
|
||||||
elseif pr:next(1,mushroom_rarity) == 1 then
|
|
||||||
data[vi] = c.nether_shroom
|
|
||||||
elseif pr:next(1,glowflower_rarity) == 1 then
|
|
||||||
data[vi] = c.glowflower
|
|
||||||
elseif pr:next(1,grass_rarity) == 1 then
|
|
||||||
data[vi] = c.nether_grass[pr:next(1,3)]
|
|
||||||
else
|
|
||||||
data[vi] = c.air
|
|
||||||
end
|
|
||||||
elseif is_forest
|
|
||||||
and y > f_bottom
|
|
||||||
and y < f_top then
|
|
||||||
if not nether_tree_nodes[d_p_addp] then
|
|
||||||
data[vi] = c.air
|
|
||||||
end
|
|
||||||
elseif is_forest
|
|
||||||
and y == f_top then
|
|
||||||
local sel = math.floor(strassx[x]+strassz[z]+0.5)%10
|
|
||||||
if sel <= 5 then
|
|
||||||
data[vi] = return_nether_ore(d_p_addp, true)
|
|
||||||
elseif sel == 6 then
|
|
||||||
data[vi] = c.netherrack_black
|
|
||||||
elseif sel == 7 then
|
|
||||||
data[vi] = c.glowstone
|
|
||||||
else
|
|
||||||
data[vi] = c.air
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif y <= NETHER_BOTTOM then
|
|
||||||
if y <= bottom then
|
|
||||||
data[vi] = return_nether_ore(d_p_addp, true)
|
|
||||||
else
|
|
||||||
data[vi] = c.lava
|
|
||||||
end
|
|
||||||
elseif r_structure == 1
|
|
||||||
and y == bottom then
|
|
||||||
tab[num] = {x=x, y=y-1, z=z}
|
|
||||||
num = num+1
|
|
||||||
elseif y <= bottom then
|
|
||||||
if pr:next(1,LAVA_FREQ) == 1 then
|
|
||||||
data[vi] = c.lava
|
|
||||||
else
|
|
||||||
data[vi] = return_nether_ore(d_p_addp, false)
|
|
||||||
end
|
|
||||||
elseif r_shroom == 1
|
|
||||||
and r_structure ~= 1
|
|
||||||
and y == bottom+1 then
|
|
||||||
data[vi] = c.nether_shroom
|
|
||||||
elseif (y == top and r_glowstone == 1) then
|
|
||||||
data[vi] = c.glowstone
|
|
||||||
elseif y >= top then
|
|
||||||
data[vi] = return_nether_ore(d_p_addp, true)
|
|
||||||
elseif y <= top-1
|
|
||||||
and generate_vine
|
|
||||||
and y >= top-r_vine_length then
|
|
||||||
data[vi] = c.nether_vine
|
|
||||||
else
|
|
||||||
data[vi] = c.air
|
|
||||||
end
|
|
||||||
end
|
|
||||||
vi = vi + area.ystride
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
vm:set_data(data)
|
|
||||||
-- vm:set_lighting(12)
|
|
||||||
-- vm:calc_lighting()
|
|
||||||
-- vm:update_liquids()
|
|
||||||
vm:write_to_map(false)
|
|
||||||
|
|
||||||
nether:inform("nodes set", 2, t1)
|
|
||||||
|
|
||||||
local t2 = minetest.get_us_time()
|
|
||||||
local tr_bl_cnt = 0
|
|
||||||
|
|
||||||
if structures_enabled then -- Blood netherstructures
|
|
||||||
tr_bl_cnt = #tab
|
|
||||||
for i = 1,tr_bl_cnt do
|
|
||||||
nether.grow_netherstructure(tab[i], true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if forest_possible then -- Forest trees
|
|
||||||
tr_bl_cnt = tr_bl_cnt + #trees
|
|
||||||
for i = 1,#trees do
|
|
||||||
nether.grow_tree(trees[i], true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if tr_bl_cnt > 0 then
|
|
||||||
nether:inform(tr_bl_cnt .. " trees and blood structures set", 2, t2)
|
|
||||||
end
|
|
||||||
|
|
||||||
t2 = minetest.get_us_time()
|
|
||||||
minetest.fix_light(minp, maxp)
|
|
||||||
|
|
||||||
nether:inform("light fixed", 2, t2)
|
|
||||||
|
|
||||||
nether:inform("done", 1, t1)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
function nether.grow_netherstructure(pos, generated)
|
|
||||||
local t1 = minetest.get_us_time()
|
|
||||||
|
|
||||||
if not contents_defined then
|
|
||||||
define_contents()
|
|
||||||
contents_defined = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if not pos.x then print(dump(pos))
|
|
||||||
nether:inform("Error: "..dump(pos), 1)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local height = 6
|
|
||||||
local manip = minetest.get_voxel_manip()
|
|
||||||
local area = r_area(manip, 2, height, pos)
|
|
||||||
local nodes = manip:get_data()
|
|
||||||
|
|
||||||
local vi = area:indexp(pos)
|
|
||||||
for _ = 0, height-1 do
|
|
||||||
nodes[vi] = c.blood_stem
|
|
||||||
vi = vi + area.ystride
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = -1,1 do
|
|
||||||
for j = -1,1 do
|
|
||||||
nodes[area:index(pos.x+i, pos.y+height, pos.z+j)] = c.blood_top
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for k = -1, 1, 2 do
|
|
||||||
for l = -2+1, 2 do
|
|
||||||
local p1 = {pos.x+2*k, pos.y+height, pos.z-l*k}
|
|
||||||
local p2 = {pos.x+l*k, pos.y+height, pos.z+2*k}
|
|
||||||
local udat = c.blood_top
|
|
||||||
if math.random(2) == 1 then
|
|
||||||
nodes[area:index(p1[1], p1[2], p1[3])] = c.blood_top
|
|
||||||
nodes[area:index(p2[1], p2[2], p2[3])] = c.blood_top
|
|
||||||
udat = c.blood
|
|
||||||
end
|
|
||||||
nodes[area:index(p1[1], p1[2]-1, p1[3])] = udat
|
|
||||||
nodes[area:index(p2[1], p2[2]-1, p2[3])] = udat
|
|
||||||
end
|
|
||||||
for l = 0, 1 do
|
|
||||||
for _,p in ipairs({
|
|
||||||
{pos.x+k, pos.y+height-1, pos.z-l*k},
|
|
||||||
{pos.x+l*k, pos.y+height-1, pos.z+k},
|
|
||||||
}) do
|
|
||||||
if math.random(2) == 1 then
|
|
||||||
nodes[area:index(p[1], p[2], p[3])] = c.nether_apple
|
|
||||||
--elseif math.random(10) == 1 then
|
|
||||||
-- nodes[area:index(p[1], p[2], p[3])] = c.apple
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
set_vm_data(manip, nodes, pos, t1, "blood", generated)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local poshash = minetest.hash_node_position
|
|
||||||
local pos_from_hash = minetest.get_position_from_hash
|
|
||||||
|
|
||||||
local function soft_node(id)
|
|
||||||
return id == c.air or id == c.ignore
|
|
||||||
end
|
|
||||||
|
|
||||||
local function update_minmax(min, max, p)
|
|
||||||
min.x = math.min(min.x, p.x)
|
|
||||||
max.x = math.max(max.x, p.x)
|
|
||||||
min.z = math.min(min.z, p.z)
|
|
||||||
max.z = math.max(max.z, p.z)
|
|
||||||
end
|
|
||||||
|
|
||||||
local fruit_chances = {}
|
|
||||||
for y = -2,1 do --like a hyperbola
|
|
||||||
fruit_chances[y] = math.floor(-4/(y-2)+0.5)
|
|
||||||
end
|
|
||||||
|
|
||||||
local dirs = {
|
|
||||||
{-1, 0, 12, 19},
|
|
||||||
{1, 0, 12, 13},
|
|
||||||
{0, 1, 4},
|
|
||||||
{0, -1, 4, 10},
|
|
||||||
}
|
|
||||||
|
|
||||||
local h_max = 26
|
|
||||||
local h_stem_min = 3
|
|
||||||
local h_stem_max = 7
|
|
||||||
local h_arm_min = 2
|
|
||||||
local h_arm_max = 6
|
|
||||||
local r_arm_min = 1
|
|
||||||
local r_arm_max = 5
|
|
||||||
local fruit_rarity = 25 --a bigger number results in less fruits
|
|
||||||
local leaf_thickness = 3 --a bigger number results in more blank trees
|
|
||||||
|
|
||||||
local h_trunk_max = h_max-h_arm_max
|
|
||||||
|
|
||||||
function nether.grow_tree(pos, generated)
|
|
||||||
local t1 = minetest.get_us_time()
|
|
||||||
|
|
||||||
if not contents_defined then
|
|
||||||
define_contents()
|
|
||||||
contents_defined = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local min = vector.new(pos)
|
|
||||||
local max = vector.new(pos)
|
|
||||||
min.y = min.y-1
|
|
||||||
max.y = max.y+h_max
|
|
||||||
|
|
||||||
local trunks = {}
|
|
||||||
local trunk_corners = {}
|
|
||||||
local h_stem = math.random(h_stem_min, h_stem_max)
|
|
||||||
local todo,n = {{x=pos.x, y=pos.y+h_stem, z=pos.z}},1
|
|
||||||
while n do
|
|
||||||
local p = todo[n]
|
|
||||||
todo[n] = nil
|
|
||||||
n = next(todo)
|
|
||||||
|
|
||||||
local used_dirs,u = {},1
|
|
||||||
for _,dir in pairs(dirs) do
|
|
||||||
if math.random(1,2) == 1 then
|
|
||||||
used_dirs[u] = dir
|
|
||||||
u = u+1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not used_dirs[1] then
|
|
||||||
local dir1 = math.random(4)
|
|
||||||
local dir2 = math.random(3)
|
|
||||||
if dir1 <= dir2 then
|
|
||||||
dir2 = dir2+1
|
|
||||||
end
|
|
||||||
used_dirs[1] = dirs[dir1]
|
|
||||||
used_dirs[2] = dirs[dir2]
|
|
||||||
end
|
|
||||||
for _,dir in pairs(used_dirs) do
|
|
||||||
local p = vector.new(p)
|
|
||||||
local r = math.random(r_arm_min, r_arm_max)
|
|
||||||
for j = 1,r do
|
|
||||||
local x = p.x+j*dir[1]
|
|
||||||
local z = p.z+j*dir[2]
|
|
||||||
trunks[poshash{x=x, y=p.y, z=z}] = dir[3]
|
|
||||||
end
|
|
||||||
r = r+1
|
|
||||||
p.x = p.x+r*dir[1]
|
|
||||||
p.z = p.z+r*dir[2]
|
|
||||||
trunk_corners[poshash(p)] = dir[4] or dir[3]
|
|
||||||
local h = math.random(h_arm_min, h_arm_max)
|
|
||||||
for i = 1,h do
|
|
||||||
p.y = p.y + i
|
|
||||||
trunks[poshash(p)] = true
|
|
||||||
p.y = p.y - i
|
|
||||||
end
|
|
||||||
p.y = p.y+h
|
|
||||||
--n = #todo+1 -- caused small trees
|
|
||||||
todo[#todo+1] = p
|
|
||||||
end
|
|
||||||
if p.y > pos.y+h_trunk_max then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
n = n or next(todo)
|
|
||||||
end
|
|
||||||
local leaves = {}
|
|
||||||
local fruits = {}
|
|
||||||
local trunk_ps = {}
|
|
||||||
local count = 0
|
|
||||||
|
|
||||||
local ps = {}
|
|
||||||
local trunk_count = 0
|
|
||||||
for i,par2 in pairs(trunks) do
|
|
||||||
local pos = pos_from_hash(i)
|
|
||||||
update_minmax(min, max, pos)
|
|
||||||
local z,y,x = pos.z, pos.y, pos.x
|
|
||||||
trunk_count = trunk_count+1
|
|
||||||
ps[trunk_count] = {z,y,x, par2}
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,d in pairs(ps) do
|
|
||||||
if d[4] == true then
|
|
||||||
d[4] = nil
|
|
||||||
end
|
|
||||||
trunk_ps[#trunk_ps+1] = d
|
|
||||||
local pz, py, px = unpack(d)
|
|
||||||
count = count+1
|
|
||||||
if count > leaf_thickness then
|
|
||||||
count = 0
|
|
||||||
for y = -2,2 do
|
|
||||||
local fruit_chance = fruit_chances[y]
|
|
||||||
for z = -2,2 do
|
|
||||||
for x = -2,2 do
|
|
||||||
local distq = x*x+y*y+z*z
|
|
||||||
if distq ~= 0
|
|
||||||
and math.random(1, math.sqrt(distq)) == 1 then
|
|
||||||
local x = x+px
|
|
||||||
local y = y+py
|
|
||||||
local z = z+pz
|
|
||||||
local vi = poshash{x=x, y=y, z=z}
|
|
||||||
if not trunks[vi] then
|
|
||||||
if fruit_chance
|
|
||||||
and math.random(1, fruit_rarity) == 1
|
|
||||||
and math.random(1, fruit_chance) == 1 then
|
|
||||||
fruits[vi] = true
|
|
||||||
else
|
else
|
||||||
leaves[vi] = true
|
minetest.log("info", "nether mapgen running in main env")
|
||||||
|
dofile(path .. "/mapgen.lua")
|
||||||
end
|
end
|
||||||
update_minmax(min, max, {x=x, z=z})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--ps = nil
|
|
||||||
--collectgarbage()
|
|
||||||
|
|
||||||
for i = -1,h_stem+1 do
|
|
||||||
-- param2 explicitly set 0 due to possibly previous leaves node
|
|
||||||
trunk_ps[#trunk_ps+1] = {pos.z, pos.y+i, pos.x, 0}
|
|
||||||
end
|
|
||||||
|
|
||||||
local manip = minetest.get_voxel_manip()
|
|
||||||
local emerged_pos1, emerged_pos2 = manip:read_from_map(min, max)
|
|
||||||
local area = VoxelArea:new({MinEdge=emerged_pos1, MaxEdge=emerged_pos2})
|
|
||||||
local nodes = manip:get_data()
|
|
||||||
local param2s = manip:get_param2_data()
|
|
||||||
|
|
||||||
for i in pairs(leaves) do
|
|
||||||
local p = area:indexp(pos_from_hash(i))
|
|
||||||
if soft_node(nodes[p]) then
|
|
||||||
nodes[p] = c.nether_leaves
|
|
||||||
param2s[p] = math.random(0,179)
|
|
||||||
--param2s[p] = math.random(0,44)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i in pairs(fruits) do
|
|
||||||
local p = area:indexp(pos_from_hash(i))
|
|
||||||
if soft_node(nodes[p]) then
|
|
||||||
nodes[p] = c.nether_apple
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1,#trunk_ps do
|
|
||||||
local p = trunk_ps[i]
|
|
||||||
local par = p[4]
|
|
||||||
p = area:index(p[3], p[2], p[1])
|
|
||||||
if par then
|
|
||||||
param2s[p] = par
|
|
||||||
end
|
|
||||||
nodes[p] = c.nether_tree
|
|
||||||
end
|
|
||||||
|
|
||||||
for i,par2 in pairs(trunk_corners) do
|
|
||||||
local vi = area:indexp(pos_from_hash(i))
|
|
||||||
nodes[vi] = c.nether_tree_corner
|
|
||||||
param2s[vi] = par2
|
|
||||||
end
|
|
||||||
|
|
||||||
manip:set_data(nodes)
|
|
||||||
manip:set_param2_data(param2s)
|
|
||||||
manip:write_to_map(not generated)
|
|
||||||
nether:inform("a nether tree with " .. trunk_count ..
|
|
||||||
" branch trunk nodes grew at " .. minetest.pos_to_string(pos),
|
|
||||||
generated and 3 or 2, t1)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--abms
|
--abms
|
||||||
|
|
||||||
@ -923,8 +89,8 @@ minetest.register_abm({
|
|||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = {"nether:tree_sapling"},
|
nodenames = {"nether:tree_sapling"},
|
||||||
neighbors = {"group:nether_dirt"},
|
neighbors = {"group:nether_dirt"},
|
||||||
interval = abm_tree_interval,
|
interval = nether.v.abm_tree_interval,
|
||||||
chance = abm_tree_chance,
|
chance = nether.v.abm_tree_chance,
|
||||||
action = function(pos)
|
action = function(pos)
|
||||||
if minetest.get_node({x=pos.x, y=pos.y+2, z=pos.z}).name == "air"
|
if minetest.get_node({x=pos.x, y=pos.y+2, z=pos.z}).name == "air"
|
||||||
and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" then
|
and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" then
|
||||||
|
13
nether/init_emerge.lua
Normal file
13
nether/init_emerge.lua
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
-- This is run in mapgen env (see register_mapgen_script)
|
||||||
|
|
||||||
|
nether = {}
|
||||||
|
nether.env_type = "ssm_mapgen"
|
||||||
|
|
||||||
|
nether.path = minetest.get_modpath("nether")
|
||||||
|
local path = nether.path
|
||||||
|
|
||||||
|
dofile(path .. "/common.lua")
|
||||||
|
dofile(path .. "/grow_structures.lua")
|
||||||
|
|
||||||
|
dofile(path .. "/mapgen.lua")
|
@ -4,13 +4,19 @@ local nether_sound = default.node_sound_stone_defaults({
|
|||||||
footstep = {name="nether_footstep", gain=0.4}
|
footstep = {name="nether_footstep", gain=0.4}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- The fence registration function from fence_registration
|
||||||
local add_fence = minetest.register_fence
|
local add_fence = minetest.register_fence
|
||||||
|
local stairs_exist = minetest.global_exists("stairs")
|
||||||
|
|
||||||
|
-- A function which registers a fence and stairs nodes for a nether node if the
|
||||||
|
-- mods for these node registrations are available
|
||||||
local function add_more_nodes(name)
|
local function add_more_nodes(name)
|
||||||
local nd = "nether:"..name
|
local nd = "nether:"..name
|
||||||
if not string.find(name, "nether") then
|
if not string.find(name, "nether") then
|
||||||
name = "nether_"..name
|
name = "nether_"..name
|
||||||
end
|
end
|
||||||
local data = minetest.registered_nodes[nd]
|
local data = minetest.registered_nodes[nd]
|
||||||
|
if stairs_exist then
|
||||||
stairs.register_stair_and_slab(name, nd,
|
stairs.register_stair_and_slab(name, nd,
|
||||||
data.groups,
|
data.groups,
|
||||||
data.tiles,
|
data.tiles,
|
||||||
@ -18,6 +24,7 @@ local function add_more_nodes(name)
|
|||||||
data.description.." Slab",
|
data.description.." Slab",
|
||||||
data.sounds
|
data.sounds
|
||||||
)
|
)
|
||||||
|
end
|
||||||
if add_fence then
|
if add_fence then
|
||||||
add_fence({fence_of = nd})
|
add_fence({fence_of = nd})
|
||||||
end
|
end
|
||||||
@ -35,14 +42,11 @@ local function add_fence(name)
|
|||||||
end
|
end
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
local creative_installed = minetest.global_exists("creative")
|
|
||||||
|
|
||||||
local function digging_allowed(player, v)
|
local function digging_allowed(player, v)
|
||||||
if not player then
|
if not player then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if creative_installed
|
if minetest.is_creative_enabled(player:get_player_name()) then
|
||||||
and creative.is_enabled_for(player:get_player_name()) then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
local tool = player:get_wielded_item():get_name()
|
local tool = player:get_wielded_item():get_name()
|
||||||
|
519
nether/mapgen.lua
Normal file
519
nether/mapgen.lua
Normal file
@ -0,0 +1,519 @@
|
|||||||
|
|
||||||
|
local path = nether.path
|
||||||
|
local in_mapgen_env = nether.env_type == "ssm_mapgen"
|
||||||
|
|
||||||
|
-- vars
|
||||||
|
local v = nether.v
|
||||||
|
local nether_middle = v.nether_middle
|
||||||
|
local f_bottom_scale = v.f_bottom_scale
|
||||||
|
local f_h_min = v.f_h_min
|
||||||
|
local f_h_max = v.f_h_max
|
||||||
|
local tree_rarity = v.tree_rarity
|
||||||
|
local glowflower_rarity = v.glowflower_rarity
|
||||||
|
local grass_rarity = v.grass_rarity
|
||||||
|
local mushroom_rarity = v.mushroom_rarity
|
||||||
|
local nether_start = v.nether_start
|
||||||
|
local NETHER_HEIGHT = v.NETHER_HEIGHT
|
||||||
|
local NETHER_RANDOM = v.NETHER_RANDOM
|
||||||
|
local GLOWSTONE_FREQ_ROOF = v.GLOWSTONE_FREQ_ROOF
|
||||||
|
local LAVA_FREQ = v.LAVA_FREQ
|
||||||
|
local nether_structure_freq = v.nether_structure_freq
|
||||||
|
local NETHER_SHROOM_FREQ = v.NETHER_SHROOM_FREQ
|
||||||
|
local NETHER_BOTTOM = v.NETHER_BOTTOM
|
||||||
|
local nether_buildings = v.nether_buildings
|
||||||
|
|
||||||
|
local nether_weird_noise = dofile(path .. "/weird_mapgen_noise.lua")
|
||||||
|
|
||||||
|
-- Weierstrass function stuff from https://github.com/slemonide/gen
|
||||||
|
local get_ws_list
|
||||||
|
do
|
||||||
|
local SIZE = 1000
|
||||||
|
local ssize = math.ceil(math.abs(SIZE))
|
||||||
|
local function do_ws_func(depth, a, x)
|
||||||
|
local n = math.pi * x / (16 * SIZE)
|
||||||
|
local y = 0
|
||||||
|
for k=1,depth do
|
||||||
|
y = y + math.sin(k^a * n) / k^a
|
||||||
|
end
|
||||||
|
return SIZE * y / math.pi
|
||||||
|
end
|
||||||
|
|
||||||
|
local chunksize = minetest.settings:get"chunksize" or 5
|
||||||
|
local ws_lists = {}
|
||||||
|
get_ws_list = function(a,x)
|
||||||
|
ws_lists[a] = ws_lists[a] or {}
|
||||||
|
local v = ws_lists[a][x]
|
||||||
|
if v then
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
v = {}
|
||||||
|
for x=x,x + (chunksize*16 - 1) do
|
||||||
|
local y = do_ws_func(ssize, a, x)
|
||||||
|
v[x] = y
|
||||||
|
end
|
||||||
|
ws_lists[a][x] = v
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dif(z1, z2)
|
||||||
|
return math.abs(z1-z2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pymg(x1, x2, z1, z2)
|
||||||
|
return math.max(dif(x1, x2), dif(z1, z2))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Generated variables
|
||||||
|
--~ local NETHER_ROOF_ABS = (nether_middle - NETHER_RANDOM)
|
||||||
|
local f_yscale_top = (f_h_max-f_h_min)/2
|
||||||
|
local f_yscale_bottom = f_yscale_top/2
|
||||||
|
--HADES_THRONE_STARTPOS_ABS = {x=HADES_THRONE_STARTPOS.x, y=(NETHER_BOTTOM +
|
||||||
|
--HADES_THRONE_STARTPOS.y), z=HADES_THRONE_STARTPOS.z}
|
||||||
|
--LAVA_Y = (NETHER_BOTTOM + LAVA_HEIGHT)
|
||||||
|
--HADES_THRONE_ABS = {}
|
||||||
|
--HADES_THRONE_ENDPOS_ABS = {}
|
||||||
|
--HADES_THRONE_GENERATED = minetest.get_worldpath() .. "/netherhadesthrone.txt"
|
||||||
|
--NETHER_SPAWNPOS_ABS = {x=NETHER_SPAWNPOS.x, y=(NETHER_BOTTOM +
|
||||||
|
--NETHER_SPAWNPOS.y), z=NETHER_SPAWNPOS.z}
|
||||||
|
--[[for i,v in ipairs(HADES_THRONE) do
|
||||||
|
v.pos.x = v.pos.x + HADES_THRONE_STARTPOS_ABS.x
|
||||||
|
v.pos.y = v.pos.y + HADES_THRONE_STARTPOS_ABS.y
|
||||||
|
v.pos.z = v.pos.z + HADES_THRONE_STARTPOS_ABS.z
|
||||||
|
HADES_THRONE_ABS[i] = v
|
||||||
|
end
|
||||||
|
local htx = 0
|
||||||
|
local hty = 0
|
||||||
|
local htz = 0
|
||||||
|
for i,v in ipairs(HADES_THRONE_ABS) do
|
||||||
|
if v.pos.x > htx then
|
||||||
|
htx = v.pos.x
|
||||||
|
end
|
||||||
|
if v.pos.y > hty then
|
||||||
|
hty = v.pos.y
|
||||||
|
end
|
||||||
|
if v.pos.z > htz then
|
||||||
|
htz = v.pos.z
|
||||||
|
end
|
||||||
|
end
|
||||||
|
HADES_THRONE_ENDPOS_ABS = {x=htx, y=hty, z=htz}]]
|
||||||
|
|
||||||
|
local c, nether_tree_nodes, contents_defined
|
||||||
|
local function define_contents()
|
||||||
|
if not contents_defined then
|
||||||
|
c, nether_tree_nodes = nether.query_contents()
|
||||||
|
contents_defined = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local pr
|
||||||
|
|
||||||
|
local function return_nether_ore(id, glowstone)
|
||||||
|
if glowstone
|
||||||
|
and pr:next(0,GLOWSTONE_FREQ_ROOF) == 1 then
|
||||||
|
return c.glowstone
|
||||||
|
end
|
||||||
|
if id == c.coal then
|
||||||
|
return c.netherrack_tiled
|
||||||
|
end
|
||||||
|
if id == c.gravel then
|
||||||
|
return c.netherrack_black
|
||||||
|
end
|
||||||
|
if id == c.diamond then
|
||||||
|
return c.netherrack_blue
|
||||||
|
end
|
||||||
|
if id == c.mese then
|
||||||
|
return c.white
|
||||||
|
end
|
||||||
|
return c.netherrack
|
||||||
|
end
|
||||||
|
|
||||||
|
local f_perlins = {}
|
||||||
|
|
||||||
|
-- abs(v) < 1-(persistance^octaves))/(1-persistance) = amp
|
||||||
|
--local perlin1 = minetest.get_perlin(13,3, 0.5, 50) --Get map specific perlin
|
||||||
|
-- local perlin2 = minetest.get_perlin(133,3, 0.5, 10)
|
||||||
|
-- local perlin3 = minetest.get_perlin(112,3, 0.5, 5)
|
||||||
|
local tmp = f_yscale_top*4
|
||||||
|
local tmp2 = tmp/f_bottom_scale
|
||||||
|
local perlins = {
|
||||||
|
{ -- amp 1.75
|
||||||
|
seed = 13,
|
||||||
|
octaves = 3,
|
||||||
|
persist = 0.5,
|
||||||
|
spread = {x=50, y=50, z=50},
|
||||||
|
scale = 1,
|
||||||
|
offset = 0,
|
||||||
|
},
|
||||||
|
{-- amp 1.75
|
||||||
|
seed = 133,
|
||||||
|
octaves = 3,
|
||||||
|
persist = 0.5,
|
||||||
|
spread = {x=10, y=10, z=10},
|
||||||
|
scale = 1,
|
||||||
|
offset = 0,
|
||||||
|
},
|
||||||
|
{-- amp 1.75
|
||||||
|
seed = 112,
|
||||||
|
octaves = 3,
|
||||||
|
persist = 0.5,
|
||||||
|
spread = {x=5, y=5, z=5},
|
||||||
|
scale = 1,
|
||||||
|
offset = 0,
|
||||||
|
},
|
||||||
|
--[[forest_bottom = {
|
||||||
|
seed = 11,
|
||||||
|
octaves = 3,
|
||||||
|
persist = 0.8,
|
||||||
|
spread = {x=tmp2, y=tmp2, z=tmp2},
|
||||||
|
scale = 1,
|
||||||
|
offset = 0,
|
||||||
|
},]]
|
||||||
|
forest_top = {-- amp 2.44
|
||||||
|
seed = 21,
|
||||||
|
octaves = 3,
|
||||||
|
persist = 0.8,
|
||||||
|
spread = {x=tmp, y=tmp, z=tmp},
|
||||||
|
scale = 1,
|
||||||
|
offset = 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- buffers, see https://forum.minetest.net/viewtopic.php?f=18&t=16043
|
||||||
|
local pelin_maps
|
||||||
|
local pmap1 = {}
|
||||||
|
local pmap2 = {}
|
||||||
|
local pmap3 = {}
|
||||||
|
local pmap_f_top = {}
|
||||||
|
local data = {}
|
||||||
|
|
||||||
|
local structures_enabled = true
|
||||||
|
local vine_maxlength = math.floor(NETHER_HEIGHT/4+0.5)
|
||||||
|
-- Create the Nether
|
||||||
|
local function on_generated(minp, maxp, seed)
|
||||||
|
--avoid big map generation
|
||||||
|
if not (maxp.y >= NETHER_BOTTOM-100 and minp.y <= nether_start) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local t1 = minetest.get_us_time()
|
||||||
|
nether:inform("generates at: x=["..minp.x.."; "..maxp.x.."]; y=[" ..
|
||||||
|
minp.y.."; "..maxp.y.."]; z=["..minp.z.."; "..maxp.z.."]", 2)
|
||||||
|
|
||||||
|
define_contents()
|
||||||
|
|
||||||
|
local buildings = 0
|
||||||
|
if maxp.y <= NETHER_BOTTOM then
|
||||||
|
buildings = 1
|
||||||
|
elseif minp.y <= nether_buildings then
|
||||||
|
buildings = 2
|
||||||
|
end
|
||||||
|
|
||||||
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
|
vm:get_data(data)
|
||||||
|
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
|
||||||
|
|
||||||
|
pr = PseudoRandom(seed+33)
|
||||||
|
local tab,num = {},1
|
||||||
|
local trees,num_trees = {},1
|
||||||
|
|
||||||
|
--local perlin1 = minetest.get_perlin(13,3, 0.5, 50)
|
||||||
|
--local perlin2 = minetest.get_perlin(133,3, 0.5, 10)
|
||||||
|
--local perlin3 = minetest.get_perlin(112,3, 0.5, 5)
|
||||||
|
|
||||||
|
local side_length = maxp.x - minp.x + 1
|
||||||
|
local map_lengths_xyz = {x=side_length, y=side_length, z=side_length}
|
||||||
|
|
||||||
|
if not pelin_maps then
|
||||||
|
pelin_maps = {
|
||||||
|
a = minetest.get_perlin_map(perlins[1], map_lengths_xyz),
|
||||||
|
b = minetest.get_perlin_map(perlins[2], map_lengths_xyz),
|
||||||
|
c = minetest.get_perlin_map(perlins[3], map_lengths_xyz),
|
||||||
|
forest_top = minetest.get_perlin_map(perlins.forest_top,
|
||||||
|
map_lengths_xyz),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
pelin_maps.a:get_2d_map_flat({x=minp.x, y=minp.z}, pmap1)
|
||||||
|
pelin_maps.b:get_2d_map_flat({x=minp.x, y=minp.z}, pmap2)
|
||||||
|
pelin_maps.c:get_2d_map_flat({x=minp.x, y=minp.z}, pmap3)
|
||||||
|
|
||||||
|
local forest_possible = maxp.y > f_h_min and minp.y < f_h_max
|
||||||
|
|
||||||
|
--local pmap_f_bottom = minetest.get_perlin_map(perlins.forest_bottom,
|
||||||
|
-- map_lengths_xyz):get_2d_map_flat({x=minp.x, y=minp.z})
|
||||||
|
local perlin_f_bottom, strassx, strassz
|
||||||
|
if forest_possible then
|
||||||
|
perlin_f_bottom = minetest.get_perlin(11, 3, 0.8, tmp2)
|
||||||
|
pelin_maps.forest_top:get_2d_map_flat({x=minp.x, y=minp.z}, pmap_f_top)
|
||||||
|
strassx = get_ws_list(2, minp.x)
|
||||||
|
strassz = get_ws_list(2, minp.z)
|
||||||
|
end
|
||||||
|
|
||||||
|
local num2, tab2
|
||||||
|
if buildings >= 1 then
|
||||||
|
num2 = 1
|
||||||
|
tab2 = nether_weird_noise({x=minp.x, y=nether_buildings-79, z=minp.z},
|
||||||
|
pymg, 200, 8, 10, side_length-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local count = 0
|
||||||
|
for z=minp.z, maxp.z do
|
||||||
|
for x=minp.x, maxp.x do
|
||||||
|
|
||||||
|
count = count+1
|
||||||
|
|
||||||
|
local test = pmap1[count]+1
|
||||||
|
local test2 = pmap2[count]
|
||||||
|
local test3 = math.abs(pmap3[count])
|
||||||
|
|
||||||
|
local t = math.floor(test*3+0.5)
|
||||||
|
|
||||||
|
local h
|
||||||
|
if test2 < 0 then
|
||||||
|
h = math.floor(test2*3+0.5)-1
|
||||||
|
else
|
||||||
|
h = 3+t+pr:next(0,NETHER_RANDOM)
|
||||||
|
end
|
||||||
|
|
||||||
|
local generate_vine = false
|
||||||
|
if test3 >= 0.72+pr:next(0,NETHER_RANDOM)/10
|
||||||
|
and pr:next(0,NETHER_RANDOM) == 1 then
|
||||||
|
generate_vine = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local bottom = NETHER_BOTTOM+h
|
||||||
|
local top = nether_middle-pr:next(0,NETHER_RANDOM)+t
|
||||||
|
|
||||||
|
local py_h = 0
|
||||||
|
local difn, noisp, py_h_g
|
||||||
|
if buildings >= 1 then
|
||||||
|
py_h = tab2[num2].y
|
||||||
|
num2 = num2+1
|
||||||
|
|
||||||
|
difn = nether_buildings-py_h
|
||||||
|
if difn == 5 then
|
||||||
|
noisp = 1
|
||||||
|
elseif difn < 5 then
|
||||||
|
noisp = 2
|
||||||
|
end
|
||||||
|
py_h_g = nether_buildings-7
|
||||||
|
end
|
||||||
|
|
||||||
|
local vi = area:index(x, minp.y, z)
|
||||||
|
if buildings == 1
|
||||||
|
and noisp then
|
||||||
|
if noisp == 1 then
|
||||||
|
for _ = 1,side_length do
|
||||||
|
data[vi] = c.netherrack_brick
|
||||||
|
vi = vi + area.ystride
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for _ = 1,side_length do
|
||||||
|
data[vi] = c.lava
|
||||||
|
vi = vi + area.ystride
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
|
local r_structure = pr:next(1,nether_structure_freq)
|
||||||
|
local r_shroom = pr:next(1,NETHER_SHROOM_FREQ)
|
||||||
|
local r_glowstone = pr:next(0,GLOWSTONE_FREQ_ROOF)
|
||||||
|
local r_vine_length = pr:next(1,vine_maxlength)
|
||||||
|
|
||||||
|
local f_bottom, f_top, is_forest, f_h_dirt
|
||||||
|
if forest_possible then
|
||||||
|
local p = {x=math.floor(x/f_bottom_scale),
|
||||||
|
z=math.floor(z/f_bottom_scale)}
|
||||||
|
local pstr = p.x.." "..p.z
|
||||||
|
if not f_perlins[pstr] then
|
||||||
|
f_perlins[pstr] = math.floor(f_h_min + (math.abs(
|
||||||
|
perlin_f_bottom:get_2d{x=p.x, y=p.z} + 1))
|
||||||
|
* f_yscale_bottom + 0.5)
|
||||||
|
end
|
||||||
|
local top_noise = pmap_f_top[count]+1
|
||||||
|
if top_noise < 0 then
|
||||||
|
top_noise = -top_noise/10
|
||||||
|
--nether:inform("ERROR: (perlin noise) "..
|
||||||
|
-- pmap_f_top[count].." is not inside [-1; 1]", 1)
|
||||||
|
end
|
||||||
|
f_top = math.floor(f_h_max - top_noise*f_yscale_top + 0.5)
|
||||||
|
f_bottom = f_perlins[pstr]+pr:next(0,f_bottom_scale-1)
|
||||||
|
is_forest = f_bottom < f_top
|
||||||
|
f_h_dirt = f_bottom-pr:next(0,1)
|
||||||
|
end
|
||||||
|
|
||||||
|
for y=minp.y, maxp.y do
|
||||||
|
local d_p_addp = data[vi]
|
||||||
|
--if py_h >= maxp.y-4 then
|
||||||
|
if y <= py_h
|
||||||
|
and noisp then
|
||||||
|
if noisp == 1 then
|
||||||
|
data[vi] = c.netherrack_brick
|
||||||
|
elseif noisp == 2 then
|
||||||
|
if y == py_h then
|
||||||
|
data[vi] = c.netherrack_brick
|
||||||
|
elseif y == py_h_g
|
||||||
|
and pr:next(1,3) <= 2 then
|
||||||
|
data[vi] = c.netherrack
|
||||||
|
elseif y <= py_h_g then
|
||||||
|
data[vi] = c.lava
|
||||||
|
else
|
||||||
|
data[vi] = c.air
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif d_p_addp ~= c.air then
|
||||||
|
|
||||||
|
if is_forest
|
||||||
|
and y == f_bottom then
|
||||||
|
data[vi] = c.nether_dirt_top
|
||||||
|
elseif is_forest
|
||||||
|
and y < f_bottom
|
||||||
|
and y >= f_h_dirt then
|
||||||
|
data[vi] = c.nether_dirt
|
||||||
|
elseif is_forest
|
||||||
|
and y == f_h_dirt-1 then
|
||||||
|
data[vi] = c.nether_dirt_bottom
|
||||||
|
elseif is_forest
|
||||||
|
and y == f_h_dirt+1 then
|
||||||
|
if pr:next(1,tree_rarity) == 1 then
|
||||||
|
trees[num_trees] = {x=x, y=y, z=z}
|
||||||
|
num_trees = num_trees+1
|
||||||
|
elseif pr:next(1,mushroom_rarity) == 1 then
|
||||||
|
data[vi] = c.nether_shroom
|
||||||
|
elseif pr:next(1,glowflower_rarity) == 1 then
|
||||||
|
data[vi] = c.glowflower
|
||||||
|
elseif pr:next(1,grass_rarity) == 1 then
|
||||||
|
data[vi] = c.nether_grass[pr:next(1,3)]
|
||||||
|
else
|
||||||
|
data[vi] = c.air
|
||||||
|
end
|
||||||
|
elseif is_forest
|
||||||
|
and y > f_bottom
|
||||||
|
and y < f_top then
|
||||||
|
if not nether_tree_nodes[d_p_addp] then
|
||||||
|
data[vi] = c.air
|
||||||
|
end
|
||||||
|
elseif is_forest
|
||||||
|
and y == f_top then
|
||||||
|
local sel = math.floor(strassx[x]+strassz[z]+0.5)%10
|
||||||
|
if sel <= 5 then
|
||||||
|
data[vi] = return_nether_ore(d_p_addp, true)
|
||||||
|
elseif sel == 6 then
|
||||||
|
data[vi] = c.netherrack_black
|
||||||
|
elseif sel == 7 then
|
||||||
|
data[vi] = c.glowstone
|
||||||
|
else
|
||||||
|
data[vi] = c.air
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif y <= NETHER_BOTTOM then
|
||||||
|
if y <= bottom then
|
||||||
|
data[vi] = return_nether_ore(d_p_addp, true)
|
||||||
|
else
|
||||||
|
data[vi] = c.lava
|
||||||
|
end
|
||||||
|
elseif r_structure == 1
|
||||||
|
and y == bottom then
|
||||||
|
tab[num] = {x=x, y=y-1, z=z}
|
||||||
|
num = num+1
|
||||||
|
elseif y <= bottom then
|
||||||
|
if pr:next(1,LAVA_FREQ) == 1 then
|
||||||
|
data[vi] = c.lava
|
||||||
|
else
|
||||||
|
data[vi] = return_nether_ore(d_p_addp, false)
|
||||||
|
end
|
||||||
|
elseif r_shroom == 1
|
||||||
|
and r_structure ~= 1
|
||||||
|
and y == bottom+1 then
|
||||||
|
data[vi] = c.nether_shroom
|
||||||
|
elseif (y == top and r_glowstone == 1) then
|
||||||
|
data[vi] = c.glowstone
|
||||||
|
elseif y >= top then
|
||||||
|
data[vi] = return_nether_ore(d_p_addp, true)
|
||||||
|
elseif y <= top-1
|
||||||
|
and generate_vine
|
||||||
|
and y >= top-r_vine_length then
|
||||||
|
data[vi] = c.nether_vine
|
||||||
|
else
|
||||||
|
data[vi] = c.air
|
||||||
|
end
|
||||||
|
end
|
||||||
|
vi = vi + area.ystride
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
nether:inform("most stuff set", 2, t1)
|
||||||
|
|
||||||
|
local t2 = minetest.get_us_time()
|
||||||
|
local bl_cnt = 0
|
||||||
|
local tr_cnt = 0
|
||||||
|
local tr_snd_cnt = 0
|
||||||
|
|
||||||
|
if structures_enabled then -- Blood netherstructures
|
||||||
|
bl_cnt = #tab
|
||||||
|
for i = 1, #tab do
|
||||||
|
nether.grow_netherstructure_into(area, data, tab[i], true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if bl_cnt > 0 then
|
||||||
|
nether:inform(bl_cnt .. " blood structures set", 2, t2)
|
||||||
|
end
|
||||||
|
|
||||||
|
t2 = minetest.get_us_time()
|
||||||
|
vm:set_data(data)
|
||||||
|
-- vm:set_lighting(12)
|
||||||
|
-- vm:calc_lighting()
|
||||||
|
-- vm:update_liquids()
|
||||||
|
if not in_mapgen_env then
|
||||||
|
vm:write_to_map(false)
|
||||||
|
end
|
||||||
|
nether:inform("data written", 2, t2)
|
||||||
|
|
||||||
|
t2 = minetest.get_us_time()
|
||||||
|
if forest_possible then -- Forest trees
|
||||||
|
if in_mapgen_env then
|
||||||
|
-- Trees can get too big (>16 nodes in one direction) for usual
|
||||||
|
-- overgeneration onion layer. nether.grow_tree will make new vmanips
|
||||||
|
-- to emerge blank (= ignore-filled) blocks to overcome this. But the
|
||||||
|
-- main server thread needs to do this.
|
||||||
|
tr_snd_cnt = #trees
|
||||||
|
local trees_hashed = {}
|
||||||
|
for i = 1, #trees do
|
||||||
|
trees_hashed[i] = minetest.hash_node_position(trees[i])
|
||||||
|
end
|
||||||
|
assert(minetest.save_gen_notify("nether:please_grow_trees", trees_hashed))
|
||||||
|
else
|
||||||
|
tr_cnt = #trees
|
||||||
|
for i = 1, #trees do
|
||||||
|
nether.grow_tree(trees[i], true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if tr_cnt + tr_snd_cnt > 0 then
|
||||||
|
nether:inform(string.format("%s trees set, %s trees sent",
|
||||||
|
tr_cnt, tr_snd_cnt), 2, t2)
|
||||||
|
end
|
||||||
|
|
||||||
|
if in_mapgen_env then
|
||||||
|
assert(minetest.save_gen_notify("nether:please_fix_light", {minp, maxp}))
|
||||||
|
else
|
||||||
|
t2 = minetest.get_us_time()
|
||||||
|
minetest.fix_light(minp, maxp)
|
||||||
|
|
||||||
|
nether:inform("light fixed", 2, t2)
|
||||||
|
end
|
||||||
|
|
||||||
|
nether:inform("done", 1, t1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if in_mapgen_env then
|
||||||
|
minetest.register_on_generated(function(_, minp, maxp, blockseed)
|
||||||
|
return on_generated(minp, maxp, blockseed)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
minetest.register_on_generated(on_generated)
|
||||||
|
end
|
@ -1,3 +1,3 @@
|
|||||||
name = nether
|
name = nether
|
||||||
depends = default,glow,riesenpilz,stairs,vector_extras
|
depends = default,glow,riesenpilz
|
||||||
optional_depends = creative,fence_registration,function_delayer,watershed
|
optional_depends = creative,fence_registration,function_delayer,stairs,watershed
|
||||||
|
@ -4,8 +4,8 @@ local function throw_pearl(item, player)
|
|||||||
playerpos.y = playerpos.y+1.625
|
playerpos.y = playerpos.y+1.625
|
||||||
local obj = minetest.add_entity(playerpos, "nether:pearl_entity")
|
local obj = minetest.add_entity(playerpos, "nether:pearl_entity")
|
||||||
local dir = player:get_look_dir()
|
local dir = player:get_look_dir()
|
||||||
obj:setvelocity(vector.multiply(dir, 30))
|
obj:set_velocity(vector.multiply(dir, 30))
|
||||||
obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
|
obj:set_acceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
obj:get_luaentity().player = pname
|
obj:get_luaentity().player = pname
|
||||||
if not minetest.is_creative_enabled(pname) then
|
if not minetest.is_creative_enabled(pname) then
|
||||||
@ -56,7 +56,7 @@ local function teleport_player(pos, player)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
pos.y = pos.y+0.05
|
pos.y = pos.y+0.05
|
||||||
player:moveto(pos)
|
player:move_to(pos)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
--code copied from Pilzadam's nether mod and edited
|
--code copied from Pilzadam's nether mod and edited
|
||||||
|
|
||||||
|
local nether_start = nether.v.nether_start
|
||||||
|
local nether_bottom = nether.v.nether_bottom
|
||||||
|
local nether_buildings = nether.v.nether_buildings
|
||||||
|
|
||||||
-- kills the player if he uses PilzAdam portal
|
-- kills the player if he uses PilzAdam portal
|
||||||
local portal_target = nether.buildings+1
|
local portal_target = nether_buildings+1
|
||||||
local damage_enabled = minetest.settings:get_bool"enable_damage"
|
local damage_enabled = minetest.settings:get_bool"enable_damage"
|
||||||
local mclike_portal = false
|
local mclike_portal = false
|
||||||
|
|
||||||
@ -11,7 +15,7 @@ minetest.after(5, function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
local save_path = minetest.get_worldpath() .. "/nether_players"
|
local save_path = minetest.get_worldpath() .. "/nether_players"
|
||||||
local players_in_nether = {}
|
local players_trapped_in_nether = {}
|
||||||
|
|
||||||
-- Load the list of players which are trapped in the nether
|
-- Load the list of players which are trapped in the nether
|
||||||
-- (or would be trapped if nether.trap_players was true)
|
-- (or would be trapped if nether.trap_players was true)
|
||||||
@ -23,7 +27,7 @@ do
|
|||||||
if contents then
|
if contents then
|
||||||
local playernames = string.split(contents, " ")
|
local playernames = string.split(contents, " ")
|
||||||
for i = 1,#playernames do
|
for i = 1,#playernames do
|
||||||
players_in_nether[playernames[i]] = true
|
players_trapped_in_nether[playernames[i]] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -31,7 +35,7 @@ end
|
|||||||
|
|
||||||
local function save_nether_players()
|
local function save_nether_players()
|
||||||
local playernames,n = {},1
|
local playernames,n = {},1
|
||||||
for name in pairs(players_in_nether) do
|
for name in pairs(players_trapped_in_nether) do
|
||||||
playernames[n] = name
|
playernames[n] = name
|
||||||
n = n+1
|
n = n+1
|
||||||
end
|
end
|
||||||
@ -41,6 +45,17 @@ local function save_nether_players()
|
|||||||
io.close(f)
|
io.close(f)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Nether aware mods will need to know if a player is in the nether.
|
||||||
|
function nether.is_player_in_nether(player)
|
||||||
|
local pos = player:get_pos()
|
||||||
|
return (pos.y < nether_start) and (pos.y >= nether_bottom)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- For testing nether trap state tracking.
|
||||||
|
function nether.is_player_trapped_in_nether(player)
|
||||||
|
return players_trapped_in_nether[player:get_player_name()]
|
||||||
|
end
|
||||||
|
|
||||||
local update_background
|
local update_background
|
||||||
if nether.trap_players then
|
if nether.trap_players then
|
||||||
function update_background(player, down)
|
function update_background(player, down)
|
||||||
@ -54,6 +69,36 @@ else
|
|||||||
function update_background()end
|
function update_background()end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Nether aware mods may have other means of moving players between the Nether
|
||||||
|
-- and Overworld, and if so, they should tell us about it so we can keep track
|
||||||
|
-- of the player state.
|
||||||
|
function nether.external_nether_teleport(player, pos)
|
||||||
|
if not nether.trap_players then
|
||||||
|
player:set_pos(pos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local destination_in_nether = (pos.y < nether_start) and (pos.y >= nether_bottom)
|
||||||
|
update_background(player, destination_in_nether)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
players_trapped_in_nether[pname] = destination_in_nether or nil
|
||||||
|
player:set_pos(pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Has the player dug their way out of the nether?
|
||||||
|
-- Has nether.trap_players been disabled?
|
||||||
|
function nether.registry_update(player)
|
||||||
|
local pos = player:get_pos()
|
||||||
|
local in_nether = (pos.y < nether_start) and (pos.y >= nether_bottom)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
if nether.trap_players then
|
||||||
|
players_trapped_in_nether[pname] = in_nether or nil
|
||||||
|
update_background(player, in_nether)
|
||||||
|
elseif players_trapped_in_nether[pname] then
|
||||||
|
players_trapped_in_nether[pname] = nil
|
||||||
|
update_background(player, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- returns nodename if area is generated, else calls generation function
|
-- returns nodename if area is generated, else calls generation function
|
||||||
local function generated_or_generate(pos)
|
local function generated_or_generate(pos)
|
||||||
local node = minetest.get_node_or_nil(pos)
|
local node = minetest.get_node_or_nil(pos)
|
||||||
@ -79,11 +124,12 @@ end
|
|||||||
|
|
||||||
-- used for obsidian portal
|
-- used for obsidian portal
|
||||||
local function obsidian_teleport(player, pname, target)
|
local function obsidian_teleport(player, pname, target)
|
||||||
minetest.chat_send_player(pname, "For any reason you arrived here. Type " ..
|
minetest.chat_send_player(pname, "For some reason you arrived here. Type " ..
|
||||||
"/nether_help to find out things like craft recipes.")
|
"/nether_help to find out things like craft recipes.")
|
||||||
players_in_nether[pname] = true
|
players_trapped_in_nether[pname] = true
|
||||||
save_nether_players()
|
save_nether_players()
|
||||||
update_background(player, true)
|
update_background(player, true)
|
||||||
|
|
||||||
if target then
|
if target then
|
||||||
player:set_pos(target)
|
player:set_pos(target)
|
||||||
else
|
else
|
||||||
@ -94,14 +140,14 @@ end
|
|||||||
-- teleports players to nether or helps it
|
-- teleports players to nether or helps it
|
||||||
local function player_to_nether(player, pos)
|
local function player_to_nether(player, pos)
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
players_in_nether[pname] = true
|
players_trapped_in_nether[pname] = true
|
||||||
save_nether_players()
|
save_nether_players()
|
||||||
update_background(player, true)
|
update_background(player, true)
|
||||||
if pos then
|
if pos then
|
||||||
player:set_pos(pos)
|
player:set_pos(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
minetest.chat_send_player(pname, "For any reason you arrived here. " ..
|
minetest.chat_send_player(pname, "For some reason you arrived here. " ..
|
||||||
"Type /nether_help to find out things like craft recipes.")
|
"Type /nether_help to find out things like craft recipes.")
|
||||||
if nether.trap_players then
|
if nether.trap_players then
|
||||||
player:set_hp(0)
|
player:set_hp(0)
|
||||||
@ -113,8 +159,8 @@ end
|
|||||||
|
|
||||||
local function player_from_nether(player, pos)
|
local function player_from_nether(player, pos)
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
if players_in_nether[pname] then
|
if players_trapped_in_nether[pname] then
|
||||||
players_in_nether[pname] = nil
|
players_trapped_in_nether[pname] = nil
|
||||||
save_nether_players()
|
save_nether_players()
|
||||||
end
|
end
|
||||||
update_background(player, false)
|
update_background(player, false)
|
||||||
@ -176,13 +222,98 @@ minetest.register_chatcommand("from_hell", {
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Useful for debugging Nether player state tracking. Written by Deathwing777
|
||||||
|
minetest.register_chatcommand("in_hell", {
|
||||||
|
params = "[<player_name>]",
|
||||||
|
description = "Is the player in hell?",
|
||||||
|
func = function(name, pname)
|
||||||
|
if not minetest.check_player_privs(name, {nether=true}) then
|
||||||
|
return false,
|
||||||
|
"You need the nether priv to execute this chatcommand."
|
||||||
|
end
|
||||||
|
if not player_exists(pname) then
|
||||||
|
pname = name
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if not player then
|
||||||
|
return false, "Something went wrong."
|
||||||
|
end
|
||||||
|
|
||||||
|
local status = pname.." is in the "
|
||||||
|
if nether.is_player_in_nether(player) then
|
||||||
|
status = status.."NETHER!"
|
||||||
|
else
|
||||||
|
status = status.."OVERWORLD!"
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, status
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Useful for debugging Nether player state tracking. Written by Deathwing777
|
||||||
|
minetest.register_chatcommand("trapped_in_hell", {
|
||||||
|
params = "[<player_name>]",
|
||||||
|
description = "Is the player trapped in hell?",
|
||||||
|
func = function(name, pname)
|
||||||
|
if not minetest.check_player_privs(name, {nether=true}) then
|
||||||
|
return false,
|
||||||
|
"You need the nether priv to execute this chatcommand."
|
||||||
|
end
|
||||||
|
if not player_exists(pname) then
|
||||||
|
pname = name
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if not player then
|
||||||
|
return false, "Something went wrong."
|
||||||
|
end
|
||||||
|
|
||||||
|
local status = pname
|
||||||
|
if nether.is_player_trapped_in_nether(player) then
|
||||||
|
status = status.." is TRAPPED in nether!"
|
||||||
|
else
|
||||||
|
status = status.." is NOT trapped in nether!"
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, status
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Useful for debugging Nether player state tracking. Written by Deathwing777
|
||||||
|
minetest.register_chatcommand("update_hells_registry", {
|
||||||
|
params = "[<player_name>]",
|
||||||
|
description = "Update player state if they got to or from the nether in another way.",
|
||||||
|
func = function(name, pname)
|
||||||
|
if not minetest.check_player_privs(name, {nether=true}) then
|
||||||
|
return false,
|
||||||
|
"You need the nether priv to execute this chatcommand."
|
||||||
|
end
|
||||||
|
if not player_exists(pname) then
|
||||||
|
pname = name
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if not player then
|
||||||
|
return false, "Something went wrong."
|
||||||
|
end
|
||||||
|
|
||||||
|
nether.registry_update(player)
|
||||||
|
local status = pname
|
||||||
|
if nether.is_player_trapped_in_nether(player) then
|
||||||
|
status = status.." is TRAPPED in nether!"
|
||||||
|
else
|
||||||
|
status = status.." is NOT trapped in nether!"
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, status
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
-- Disallow teleportation and change spawn positions if the nether traps players
|
-- Disallow teleportation and change spawn positions if the nether traps players
|
||||||
if nether.trap_players then
|
if nether.trap_players then
|
||||||
-- randomly set player position when he/she dies in nether
|
-- randomly set player position when he/she dies in nether
|
||||||
minetest.register_on_respawnplayer(function(player)
|
minetest.register_on_respawnplayer(function(player)
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
if not players_in_nether[pname] then
|
if not players_trapped_in_nether[pname] then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local target = get_player_died_target(player)
|
local target = get_player_died_target(player)
|
||||||
@ -191,23 +322,23 @@ if nether.trap_players then
|
|||||||
-- fixes respawn bug
|
-- fixes respawn bug
|
||||||
local player = minetest.get_player_by_name(pname)
|
local player = minetest.get_player_by_name(pname)
|
||||||
if player then
|
if player then
|
||||||
player:moveto(target)
|
player:move_to(target)
|
||||||
end
|
end
|
||||||
end, pname, target)
|
end, pname, target)
|
||||||
return true
|
return true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- override set_pos etc. to disallow player teleportion by e.g. travelnet
|
-- override set_pos etc, to disallow player teleportion by e.g. travelnet
|
||||||
local function can_teleport(player, pos)
|
local function can_teleport(player, pos)
|
||||||
if not player:is_player() then
|
if not player:is_player() then
|
||||||
-- the same metatable is used for entities
|
-- the same metatable is used for entities
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
local in_nether = players_in_nether[pname] == true
|
local in_nether = players_trapped_in_nether[pname] == true
|
||||||
|
|
||||||
-- test if the target is valid
|
-- test if the target is valid
|
||||||
if pos.y < nether.start then
|
if pos.y < nether_start then
|
||||||
if in_nether then
|
if in_nether then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -217,7 +348,7 @@ if nether.trap_players then
|
|||||||
|
|
||||||
-- test if the current position is valid
|
-- test if the current position is valid
|
||||||
local current_pos = player:get_pos()
|
local current_pos = player:get_pos()
|
||||||
local now_in_nether = current_pos.y < nether.start
|
local now_in_nether = current_pos.y < nether_start
|
||||||
if now_in_nether ~= in_nether then
|
if now_in_nether ~= in_nether then
|
||||||
if in_nether then
|
if in_nether then
|
||||||
minetest.log("action", "Player \"" .. pname ..
|
minetest.log("action", "Player \"" .. pname ..
|
||||||
@ -245,7 +376,7 @@ if nether.trap_players then
|
|||||||
local metatable_overridden
|
local metatable_overridden
|
||||||
minetest.register_on_joinplayer(function(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
-- set the background when the player joins
|
-- set the background when the player joins
|
||||||
if player:get_pos().y < nether.start then
|
if player:get_pos().y < nether_start then
|
||||||
update_background(player, true)
|
update_background(player, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -299,7 +430,7 @@ local particledef = {
|
|||||||
-- teleports player to neter (obsidian portal)
|
-- teleports player to neter (obsidian portal)
|
||||||
local function obsi_teleport_player(player, pos, target)
|
local function obsi_teleport_player(player, pos, target)
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
if players_in_nether[pname] then
|
if players_trapped_in_nether[pname] then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -310,7 +441,7 @@ local function obsi_teleport_player(player, pos, target)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local has_teleported
|
local has_teleported
|
||||||
if damage_enabled then
|
if (damage_enabled and nether.trap_players) then
|
||||||
obsidian_teleport(player, pname)
|
obsidian_teleport(player, pname)
|
||||||
has_teleported = true
|
has_teleported = true
|
||||||
elseif not mclike_portal then
|
elseif not mclike_portal then
|
||||||
@ -432,7 +563,7 @@ local function make_portal(pos)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local in_nether = p1.y < nether.start
|
local in_nether = p1.y < nether_start
|
||||||
|
|
||||||
if in_nether
|
if in_nether
|
||||||
and not mclike_portal then
|
and not mclike_portal then
|
||||||
@ -558,10 +689,11 @@ minetest.after(0.1, function()
|
|||||||
and minetest.get_node(pt.under).name == "default:obsidian" then
|
and minetest.get_node(pt.under).name == "default:obsidian" then
|
||||||
local done = make_portal(pt.under)
|
local done = make_portal(pt.under)
|
||||||
if done then
|
if done then
|
||||||
minetest.chat_send_player(player:get_player_name(),
|
local pname = player:get_player_name()
|
||||||
|
minetest.chat_send_player(pname,
|
||||||
"Warning: If you are in the nether you may not be " ..
|
"Warning: If you are in the nether you may not be " ..
|
||||||
"able to find the way out!")
|
"able to find the way out!")
|
||||||
if not minetest.settings:get_bool("creative_mode") then
|
if not minetest.is_creative_enabled(pname) then
|
||||||
stack:take_item()
|
stack:take_item()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -572,13 +704,13 @@ minetest.after(0.1, function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
-- a not filled square
|
-- Get positions for an empty square around the origin
|
||||||
local function vector_square(r)
|
local function vector_square(r)
|
||||||
local tab, n = {}, 1
|
local tab, n = {}, 1
|
||||||
for i = -r+1, r do
|
for i = -r+1, r do
|
||||||
for j = -1, 1, 2 do
|
for j = -1, 1, 2 do
|
||||||
local a, b = r*j, i*j
|
local a, b = r*j, i*j
|
||||||
tab[n] = {a, b}
|
tab[n] = {a, -b}
|
||||||
tab[n+1] = {b, a}
|
tab[n+1] = {b, a}
|
||||||
n=n+2
|
n=n+2
|
||||||
end
|
end
|
||||||
@ -660,7 +792,7 @@ function nether.teleport_player(player)
|
|||||||
end
|
end
|
||||||
minetest.sound_play("nether_teleporter", {pos=pos})
|
minetest.sound_play("nether_teleporter", {pos=pos})
|
||||||
local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z})
|
local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z})
|
||||||
if pos.y < nether.start then
|
if pos.y < nether_start then
|
||||||
set_portal(known_portals_d, pos.z,pos.x, pos.y)
|
set_portal(known_portals_d, pos.z,pos.x, pos.y)
|
||||||
|
|
||||||
local my = tonumber(meta:get_string("y"))
|
local my = tonumber(meta:get_string("y"))
|
||||||
|
@ -2,9 +2,10 @@ local default_settings = {
|
|||||||
trap_players = true,
|
trap_players = true,
|
||||||
log_to_chat = false,
|
log_to_chat = false,
|
||||||
log_level = 2,
|
log_level = 2,
|
||||||
|
overworld_help = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
nether.settings = {}
|
nether.settings = {} -- FIXME: unused field. store settings in here?
|
||||||
|
|
||||||
for name,dv in pairs(default_settings) do
|
for name,dv in pairs(default_settings) do
|
||||||
local setting
|
local setting
|
||||||
|
@ -17,3 +17,7 @@ nether.log_to_chat (Log messages to chat) bool false
|
|||||||
# 2: Acceptable amount of information
|
# 2: Acceptable amount of information
|
||||||
# 3: Lots of text
|
# 3: Lots of text
|
||||||
nether.log_level (Log level) int 2 0 3
|
nether.log_level (Log level) int 2 0 3
|
||||||
|
|
||||||
|
# If disabled, players cannot view the nether guide with /nether_help
|
||||||
|
# in the overworld.
|
||||||
|
nether.overworld_help (Overworld help) bool true
|
||||||
|
Reference in New Issue
Block a user