nether-pack/nether/init.lua

454 lines
10 KiB
Lua
Raw Normal View History

2012-04-19 21:55:39 +02:00
-- Nether Mod (based on Nyanland by Jeija, Catapult by XYZ, and Livehouse by neko259)
-- lkjoel (main developer, code, ideas, textures)
-- == CONTRIBUTERS ==
-- jordan4ibanez (code, ideas, textures)
-- Gilli (code, ideas, textures, mainly for the Glowstone)
-- Death Dealer (code, ideas, textures)
-- LolManKuba (ideas, textures)
-- IPushButton2653 (ideas, textures)
-- Menche (textures)
-- sdzen (ideas)
-- godkiller447 (ideas)
-- If I didn't list you, please let me know!
2012-04-16 23:27:29 +02:00
2017-12-26 09:58:32 +01:00
local load_time_start = minetest.get_us_time()
2015-08-05 10:35:32 +02:00
2015-02-18 18:34:03 +01:00
if not rawget(_G, "nether") then
nether = {}
end
2024-03-14 16:12:36 +01:00
nether.path = minetest.get_modpath"nether"
local path = nether.path
2012-04-16 23:27:29 +02:00
2024-03-14 16:12:36 +01:00
dofile(path .. "/common.lua")
2015-02-18 18:34:03 +01:00
dofile(path .. "/items.lua")
--dofile(path .. "/furnace.lua")
dofile(path .. "/pearl.lua")
2013-11-17 21:04:15 +01:00
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
2015-02-18 18:34:03 +01:00
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)
2013-11-17 21:04:15 +01:00
end
2024-03-14 16:12:36 +01:00
local c, contents_defined
2015-02-18 18:34:03 +01:00
local function define_contents()
if not contents_defined then
2024-03-14 16:12:36 +01:00
c = nether.query_contents()
2015-02-18 18:34:03 +01:00
contents_defined = true
end
2024-03-14 16:12:36 +01:00
end
2015-02-18 18:34:03 +01:00
2024-03-14 16:12:36 +01:00
dofile(path .. "/mapgen.lua")
2012-04-19 21:55:39 +02:00
2015-02-18 18:34:03 +01:00
function nether.grow_netherstructure(pos, generated)
2017-12-26 09:58:32 +01:00
local t1 = minetest.get_us_time()
2012-04-19 21:55:39 +02:00
2024-03-14 16:12:36 +01:00
define_contents()
2012-04-19 21:55:39 +02:00
2015-02-18 18:34:03 +01:00
if not pos.x then print(dump(pos))
nether:inform("Error: "..dump(pos), 1)
return
end
2013-11-17 21:04:15 +01:00
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
2013-11-17 21:04:15 +01:00
end
for i = -1,1 do
for j = -1,1 do
2015-02-18 18:34:03 +01:00
nodes[area:index(pos.x+i, pos.y+height, pos.z+j)] = c.blood_top
2013-11-17 21:04:15 +01:00
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}
2015-02-18 18:34:03 +01:00
local udat = c.blood_top
2013-11-17 21:04:15 +01:00
if math.random(2) == 1 then
2015-02-18 18:34:03 +01:00
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
2013-11-17 21:04:15 +01:00
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
2015-02-18 18:34:03 +01:00
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
2013-11-17 21:04:15 +01:00
end
end
end
end
2015-02-18 18:34:03 +01:00
set_vm_data(manip, nodes, pos, t1, "blood", generated)
2013-11-17 21:04:15 +01:00
end
2015-02-18 18:34:03 +01:00
2017-12-25 21:22:32 +01:00
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
2015-02-18 18:34:03 +01:00
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)
2017-12-26 09:58:32 +01:00
local t1 = minetest.get_us_time()
2015-02-18 18:34:03 +01:00
2024-03-14 16:12:36 +01:00
define_contents()
2015-02-18 18:34:03 +01:00
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
2012-04-16 23:27:29 +02:00
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
2015-02-18 18:34:03 +01:00
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]
2017-12-25 21:22:32 +01:00
trunks[poshash{x=x, y=p.y, z=z}] = dir[3]
2015-02-18 18:34:03 +01:00
end
r = r+1
p.x = p.x+r*dir[1]
p.z = p.z+r*dir[2]
2017-12-25 21:22:32 +01:00
trunk_corners[poshash(p)] = dir[4] or dir[3]
local h = math.random(h_arm_min, h_arm_max)
for i = 1,h do
2017-12-25 21:22:32 +01:00
p.y = p.y + i
trunks[poshash(p)] = true
p.y = p.y - i
2015-02-18 18:34:03 +01:00
end
p.y = p.y+h
--n = #todo+1 -- caused small trees
todo[#todo+1] = p
2012-04-16 23:27:29 +02:00
end
if p.y > pos.y+h_trunk_max then
break
end
n = n or next(todo)
2012-04-16 23:27:29 +02:00
end
2015-02-18 18:34:03 +01:00
local leaves = {}
local fruits = {}
local trunk_ps = {}
local count = 0
2017-12-25 21:22:32 +01:00
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
2015-02-18 18:34:03 +01:00
end
trunk_ps[#trunk_ps+1] = d
local pz, py, px = unpack(d)
2015-02-18 18:34:03 +01:00
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
2017-12-25 21:22:32 +01:00
local vi = poshash{x=x, y=y, z=z}
if not trunks[vi] then
if fruit_chance
and math.random(1, fruit_rarity) == 1
2015-02-18 18:34:03 +01:00
and math.random(1, fruit_chance) == 1 then
2017-12-25 21:22:32 +01:00
fruits[vi] = true
2015-02-18 18:34:03 +01:00
else
2017-12-25 21:22:32 +01:00
leaves[vi] = true
2015-02-18 18:34:03 +01:00
end
update_minmax(min, max, {x=x, z=z})
2015-02-18 18:34:03 +01:00
end
end
end
end
end
2012-04-19 01:42:46 +02:00
end
2012-04-19 00:11:38 +02:00
end
2016-02-06 12:04:17 +01:00
--ps = nil
--collectgarbage()
2015-02-18 18:34:03 +01:00
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}
2012-04-19 00:11:38 +02:00
end
2015-02-18 18:34:03 +01:00
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()
2015-05-29 12:08:27 +02:00
local param2s = manip:get_param2_data()
2015-02-18 18:34:03 +01:00
2017-12-25 21:22:32 +01:00
for i in pairs(leaves) do
local p = area:indexp(pos_from_hash(i))
if soft_node(nodes[p]) then
2015-02-18 18:34:03 +01:00
nodes[p] = c.nether_leaves
param2s[p] = math.random(0,179)
--param2s[p] = math.random(0,44)
end
2012-04-19 00:11:38 +02:00
end
2017-12-25 21:22:32 +01:00
for i in pairs(fruits) do
local p = area:indexp(pos_from_hash(i))
if soft_node(nodes[p]) then
2015-02-18 18:34:03 +01:00
nodes[p] = c.nether_apple
end
2012-04-19 00:11:38 +02:00
end
2017-12-25 21:22:32 +01:00
for i = 1,#trunk_ps do
local p = trunk_ps[i]
local par = p[4]
p = area:index(p[3], p[2], p[1])
2015-02-18 18:34:03 +01:00
if par then
param2s[p] = par
end
2015-02-18 18:34:03 +01:00
nodes[p] = c.nether_tree
end
2017-12-25 21:22:32 +01:00
for i,par2 in pairs(trunk_corners) do
local vi = area:indexp(pos_from_hash(i))
nodes[vi] = c.nether_tree_corner
2017-12-25 21:22:32 +01:00
param2s[vi] = par2
2015-02-18 18:34:03 +01:00
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)
2012-04-19 00:11:38 +02:00
end
2015-02-18 18:34:03 +01:00
--abms
minetest.register_abm({
nodenames = {"nether:sapling"},
neighbors = {"nether:blood_top"},
interval = 20,
chance = 8,
action = function(pos)
local under = {x=pos.x, y=pos.y-1, z=pos.z}
if minetest.get_node_light(pos) < 4
and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air"
and minetest.get_node(under).name == "nether:blood_top" then
nether.grow_netherstructure(under)
2012-04-19 00:11:38 +02:00
end
end
2015-02-18 18:34:03 +01:00
})
2012-04-19 00:11:38 +02:00
2015-02-18 18:34:03 +01:00
minetest.register_abm({
nodenames = {"nether:tree_sapling"},
neighbors = {"group:nether_dirt"},
2024-03-14 16:12:36 +01:00
interval = nether.v.abm_tree_interval,
chance = nether.v.abm_tree_chance,
2015-02-18 18:34:03 +01:00
action = function(pos)
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
local udata = minetest.registered_nodes[
minetest.get_node{x=pos.x, y=pos.y-1, z=pos.z}.name]
2015-02-18 18:34:03 +01:00
if udata
and udata.groups
and udata.groups.nether_dirt then
nether.grow_tree(pos)
2012-04-19 00:11:38 +02:00
end
end
end
2015-02-18 18:34:03 +01:00
})
2012-04-19 00:11:38 +02:00
2015-02-18 18:34:03 +01:00
minetest.register_abm({
nodenames = {"nether:netherrack_soil"},
neighbors = {"air"},
interval = 20,
chance = 20,
action = function(pos, node)
local par2 = node.param2
if par2 == 0 then
return
2012-04-19 00:11:38 +02:00
end
2015-02-18 18:34:03 +01:00
pos.y = pos.y+1
--mushrooms grow at dark places
if (minetest.get_node_light(pos) or 16) > 7 then
2015-02-18 18:34:03 +01:00
return
2012-04-19 00:11:38 +02:00
end
2015-02-18 18:34:03 +01:00
if minetest.get_node(pos).name == "air" then
minetest.set_node(pos, {name="riesenpilz:nether_shroom"})
pos.y = pos.y-1
minetest.set_node(pos,
{name="nether:netherrack_soil", param2=par2-1})
2012-04-19 00:11:38 +02:00
end
end
2015-02-18 18:34:03 +01:00
})
2012-04-19 00:11:38 +02:00
2015-02-18 18:34:03 +01:00
local function grass_allowed(pos)
local nd = minetest.get_node(pos).name
if nd == "air" then
return true
end
if nd == "ignore" then
return 0
end
local data = minetest.registered_nodes[nd]
if not data then
-- unknown node
return false
end
2015-02-18 18:34:03 +01:00
local drawtype = data.drawtype
if drawtype
and drawtype ~= "normal"
and drawtype ~= "liquid"
and drawtype ~= "flowingliquid" then
return true
end
local light = data.light_source
if light
and light > 0 then
return true
end
2015-02-18 18:34:03 +01:00
return false
end
2015-02-18 18:34:03 +01:00
minetest.register_abm({
nodenames = {"nether:dirt"},
interval = 20,
chance = 9,
action = function(pos)
local allowed = grass_allowed({x=pos.x, y=pos.y+1, z=pos.z})
if allowed == 0 then
return
end
if allowed then
minetest.set_node(pos, {name="nether:dirt_top"})
end
end
2015-02-18 18:34:03 +01:00
})
2012-04-19 00:11:38 +02:00
minetest.register_abm({
2015-02-18 18:34:03 +01:00
nodenames = {"nether:dirt_top"},
interval = 30,
chance = 9,
action = function(pos)
2015-02-18 18:34:03 +01:00
local allowed = grass_allowed({x=pos.x, y=pos.y+1, z=pos.z})
if allowed == 0 then
return
end
if not allowed then
minetest.set_node(pos, {name="nether:dirt"})
end
2012-04-19 00:11:38 +02:00
end
})
minetest.register_privilege("nether",
"Allows sending players to nether and extracting them")
2012-04-19 00:11:38 +02:00
2015-02-18 18:34:03 +01:00
dofile(path.."/crafting.lua")
dofile(path.."/portal.lua")
dofile(path.."/guide.lua")
2015-08-05 10:35:32 +02:00
2017-12-26 09:58:32 +01:00
local time = (minetest.get_us_time() - load_time_start) / 1000000
local msg = ("[nether] loaded after ca. %g seconds."):format(time)
if time > 0.01 then
2015-08-05 10:35:32 +02:00
print(msg)
else
minetest.log("info", msg)
end