Most dungeon features working.

This commit is contained in:
Duane 2016-08-02 04:18:20 -05:00
parent 5abe211fb6
commit 61c3cb0edd
7 changed files with 570 additions and 710 deletions

385
dungeon.lua Normal file
View file

@ -0,0 +1,385 @@
local max_depth = 31000
local cells = 10
local cell_size = 60 / cells
local dungeon_depth = -1 -- close to y / 80
local dungeon_noise = {offset = 0, scale = 1, seed = -4082, spread = {x = 7, y = 7, z = 7}, octaves = 4, persist = 1, lacunarity = 2}
if fun_caves.path then
dofile(fun_caves.path .. "/trophies.lua")
dofile(fun_caves.path .. "/tesseract.lua")
end
-- dungeon floor, rooms
newnode = fun_caves.clone_node("default:cobble")
newnode.description = "Dungeon Stone"
newnode.legacy_mineral = false
newnode.groups = {dungeon = 1}
minetest.register_node("fun_caves:dungeon_floor_1", newnode)
-- dungeon floor, halls
newnode = fun_caves.clone_node("default:cobble")
newnode.description = "Dungeon Stone"
newnode.legacy_mineral = false
newnode.groups = {dungeon = 1}
minetest.register_node("fun_caves:dungeon_floor_2", newnode)
-- dungeon walls, basic
newnode = fun_caves.clone_node("default:cobble")
newnode.description = "Dungeon Stone"
newnode.groups = {dungeon = 1}
minetest.register_node("fun_caves:dungeon_wall_1", newnode)
-- dungeon walls, type 2
newnode = fun_caves.clone_node("default:cobble")
newnode.description = "Dungeon Stone"
newnode.groups = {dungeon = 1}
minetest.register_node("fun_caves:dungeon_wall_2", newnode)
newnode = fun_caves.clone_node("default:glass")
newnode.description = "Dungeon Stone"
newnode.groups = {dungeon = 1}
minetest.register_node("fun_caves:dungeon_wall_transparent", newnode)
newnode = fun_caves.clone_node("default:glass")
newnode.description = "Dungeon Stone"
newnode.groups = {dungeon = 1}
newnode.tiles = {'fun_caves_blank.png'}
newnode.pointable = false
minetest.register_node("fun_caves:dungeon_wall_invisible", newnode)
newnode = fun_caves.clone_node("default:meselamp")
newnode.description = "Dungeon Light"
newnode.light_source = 10
newnode.groups = {dungeon = 1}
minetest.register_node("fun_caves:dungeon_light", newnode)
local treasures = {
{'fun_caves:aquamarine', 'fun_caves:garnet', 'fun_caves:zoisite', 'fun_caves:coral_gem', 'fun_caves:moonstone', 'fun_caves:pure_copper', 'fun_caves:sky_iron', 'fun_caves:sky_iron', 'fun_caves:sky_iron', 'fun_caves:sky_iron', 'default:obsidian'},
{'fun_caves:aquamarine', 'fun_caves:garnet', 'fun_caves:zoisite', 'fun_caves:coral_gem', 'fun_caves:moonstone', 'fun_caves:pure_copper', 'fun_caves:metallic_ice', 'fun_caves:metallic_ice', 'fun_caves:metallic_ice', 'fun_caves:metallic_ice', 'default:obsidian'},
{'fun_caves:aquamarine', 'fun_caves:garnet', 'fun_caves:zoisite', 'fun_caves:coral_gem', 'fun_caves:moonstone', 'default:obsidian'},
{'fun_caves:aquamarine', 'fun_caves:garnet', 'fun_caves:zoisite', 'fun_caves:coral_gem', 'fun_caves:moonstone', 'default:obsidian'},
{'fun_caves:aquamarine', 'fun_caves:garnet', 'fun_caves:zoisite', 'fun_caves:coral_gem', 'fun_caves:moonstone', 'default:obsidian'},
{'fun_caves:aquamarine', 'fun_caves:garnet', 'fun_caves:zoisite', 'fun_caves:coral_gem', 'fun_caves:moonstone', 'default:obsidian'},
}
local filler = {'default:apple 50', 'default:coal_lump 99', 'default:wood 99', 'default:obsidian_shard', 'default:steel_ingot 10', 'default:mese_crystal', 'default:copper_ingot 10', 'default:bronze_ingot 10', 'default:diamond 10', 'fun_caves:silver_ingot 10', 'default:gold_ingot 10', 'fun_caves:moon_glass 25', 'fun_caves:moon_juice 50', 'default:sword_mese', 'default:pick_mese', 'default:sword_diamond', 'default:pick_diamond', 'fun_caves:constant_flame'}
if minetest.registered_entities['mobs_monster:stone_monster'] then
filler[#filler+1] = 'mobs_monster:stone_monster'
end
if minetest.registered_entities['mobs_monster:dungeon_master'] then
filler[#filler+1] = 'mobs_monster:dungeon_master'
end
local trophies = {
{'fun_caves:unobtainium', 'fun_caves:philosophers_stone'},
{'fun_caves:unobtainium', 'fun_caves:philosophers_stone'},
{'fun_caves:unobtainium', 'fun_caves:philosophers_stone'},
{'fun_caves:unobtainium', 'fun_caves:philosophers_stone'},
{'fun_caves:unobtainium', 'fun_caves:philosophers_stone'},
{'fun_caves:unobtainium', 'fun_caves:philosophers_stone'},
}
local chest_formspec =
"size[8,9]" ..
default.gui_bg ..
default.gui_bg_img ..
default.gui_slots ..
"list[current_name;main;0,0.3;8,4;]" ..
"list[current_player;main;0,4.85;8,1;]" ..
"list[current_player;main;0,6.08;8,3;8]" ..
"listring[current_name;main]" ..
"listring[current_player;main]" ..
default.get_hotbar_bg(0,4.85)
local newnode = fun_caves.clone_node("default:chest")
newnode.description = "Treasure Chest"
newnode.on_construct = nil
newnode.drop = 'default:chest'
newnode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if not pos then
return
end
local meta = minetest.get_meta(pos)
if not meta then
return
end
local ready = meta:get_string('formspec')
if ready == '' then
local level = math.max(6, math.ceil(pos.y / math.floor(max_depth / 6)))
local big_item = treasures[level][math.random(#treasures[level])]
meta:set_string("formspec", chest_formspec)
local inv = meta:get_inventory()
inv:set_size("main", 8*4)
inv:add_item('main', big_item)
for i = 1, math.random(12) do
inv:add_item('main', filler[math.random(#filler)])
end
if math.random(70) == 1 then
inv:add_item('main', trophies[level][math.random(#trophies[level])])
end
end
end
minetest.register_node("fun_caves:coffer", newnode)
fun_caves.dungeon = function(minp_in, maxp_in, data, p2data, area, node, heightmap)
if not (minp_in and maxp_in and data and area and node and heightmap and type(data) == 'table' and type(heightmap) == 'table') then
return
end
local n = minetest.get_perlin(dungeon_noise):get2d({x=minp_in.x, y=minp_in.z})
if not (n and type(n) == 'number') then
return
end
if math.floor((n * 10000) % 13) ~= 1 then
return
end
if minp_in.y > -100 then
local minp, maxp = minp_in, maxp_in
local stair, avg, count = nil, 0, 0
local index = 0
for z = minp.z, maxp.z do
for x = minp.x, maxp.x do
index = index + 1
if not heightmap[index] or type(heightmap[index]) ~= 'number' then
return
end
if x > minp.x + 34 and x < minp.x + 45 and z > minp.z + 34 and z < minp.z + 45 and heightmap[index] >= minp.y and heightmap[index] < maxp.y - 2 then
stair = true
avg = avg + heightmap[index]
count = count + 1
end
end
end
avg = math.ceil(avg / count)
if stair then
for z = -1, 12 do
for y = minp.y - 2, avg do
local ivm = area:index(minp.x + 34 - 1, y, z + minp.z + 34)
for x = -1, 12 do
if x == -1 or x == 12 or z == -1 or z == 12 then
data[ivm] = node['default:cobble']
elseif ((x == 2 or x == 9) and z > 1 and z < 10) or ((z == 2 or z == 9) and x > 1 and x < 10) then
data[ivm] = node['default:cobble']
else
local t
if z < 2 then
t = x
elseif x > 9 then
t = z + 11
elseif z > 9 then
t = 33 - x
else
t = 44 - z
end
t = math.floor(t / 44 * 22)
if x < 2 or x > 9 or z < 2 or z > 9 then
if math.floor((y - minp.y) % 22) == t then
data[ivm] = node['default:cobble']
else
data[ivm] = node['air']
end
end
end
ivm = ivm + 1
end
end
end
end
return true, true
end
if minp_in.y > 0 then
return
end
minp = table.copy(minp_in)
minp.x = minp.x + 10
minp.z = minp.z + 10
maxp = table.copy(maxp_in)
maxp.x = maxp.x - 9
maxp.z = maxp.z - 9
local level = math.min(6, math.ceil(maxp.y / math.floor(max_depth / -6)))
local inner_floor = node['fun_caves:dungeon_floor_1']
local outer_wall = node['fun_caves:dungeon_wall_2']
local inner_wall = node['fun_caves:dungeon_wall_1']
local treasure_count = 0
for z = minp.z - 1, maxp.z + 1 do
for y = minp.y, maxp.y - 2 do
local ivm = area:index(minp.x - 1, y, z)
for x = minp.x - 1, maxp.x + 1 do
data[ivm] = node['fun_caves:dungeon_wall_1']
ivm = ivm + 1
end
end
end
local content = {}
for cx = 0, 9 do
content[cx] = {}
for cy = 0, 12 do
content[cx][cy] = {}
for cz = 0, 9 do
if cy == 12 and (cz == 4 or cz == 5) and (cx == 4 or cx == 5) then
content[cx][cy][cz] = 'room'
else
content[cx][cy][cz] = '4way'
end
end
end
end
for cy = 0, 12 do
local x, z = math.random(1,8), math.random(0,9)
while cy == 12 and (z == 4 or z == 5) and (x == 4 or x == 5) do
x, z = math.random(1,8), math.random(0,9)
end
content[x][cy][z] = 'stair1'
content[x - 1][cy][z] = 'room'
if cy < 12 then
content[x][cy + 1][z] = 'room'
content[x + 1][cy + 1][z] = 'room'
end
x, z = math.random(0,9), math.random(1,8)
while cy == 12 and (z == 4 or z == 5) and (x == 4 or x == 5) do
x, z = math.random(0,9), math.random(1,8)
end
content[x][cy][z] = 'stair0'
content[x][cy][z - 1] = 'room'
if cy < 12 then
content[x][cy + 1][z] = 'room'
content[x][cy + 1][z + 1] = 'room'
end
end
for cx = 0, 9 do
for cy = 0, 12 do
for cz = 0, 9 do
if content[cx][cy][cz] == '4way' and math.random(2) == 1 then
content[cx][cy][cz] = 'room'
end
end
end
end
for cz = 0, 9 do
local oz = minp.z + cz * 6
for cy = 0, 12 do
local oy = minp.y + cy * 6
for cx = 0, 9 do
local ox = minp.x + cx * 6
if content[cx][cy][cz] == 'stair1' then
for rz = 0, 5 do
for ry = 0, 9 do
local ivm = area:index(ox, oy + ry, oz + rz)
local bx = 0
if cy == 0 then
bx = -1
end
for rx = bx, 6 do
if ry == rx + 1 and (rz == 2 or rz == 3) and (cy == 12 or rx < 6) then
data[ivm] = node['stairs:stair_stone']
p2data[ivm] = 1
elseif (ry >= rx + 1 and ry <= rx + 5) and (rz == 2 or rz == 3) then
data[ivm] = 'stairway'
elseif ry == rx and (rz == 2 or rz == 3) then
data[ivm] = node['fun_caves:dungeon_floor_1']
elseif rx < 6 and ry == 0 then
data[ivm] = node['fun_caves:dungeon_floor_1']
elseif ry < 6 and rx < 6 then
data[ivm] = node['fun_caves:dungeon_wall_1']
end
ivm = ivm + 1
end
end
end
elseif content[cx][cy][cz] == 'stair0' then
for rz = -1, 6 do
for ry = 0, 9 do
if cy ~= 0 and rz == -1 then
rz = 0
end
local ivm = area:index(ox, oy + ry, oz + rz)
for rx = 0, 5 do
if ry == rz + 1 and (rx == 2 or rx == 3) and (cy == 12 or rz < 6) then
data[ivm] = node['stairs:stair_cobble']
p2data[ivm] = 0
elseif (ry >= rz + 1 and ry <= rz + 5) and (rx == 2 or rx == 3) then
data[ivm] = 'stairway'
elseif ry == rz and (rx == 2 or rx == 3) then
data[ivm] = node['fun_caves:dungeon_floor_1']
elseif rz < 6 and ry == 0 then
data[ivm] = node['fun_caves:dungeon_floor_1']
elseif ry < 6 and rz < 6 then
data[ivm] = node['fun_caves:dungeon_wall_1']
end
ivm = ivm + 1
end
end
end
else
for rz = 0, 5 do
for ry = 0, 5 do
local ivm = area:index(ox, oy + ry, oz + rz)
for rx = 0, 5 do
if data[ivm] ~= 'stairway' and data[ivm] ~= node['stairs:stair_cobble'] then
if cy > 0 and ry == 0 then
if content[cx][cy][cz] == 'room' then
data[ivm] = node['fun_caves:dungeon_floor_1']
else
data[ivm] = node['fun_caves:dungeon_floor_2']
end
elseif content[cx][cy][cz] == 'room' and (cy < 12 or cx < 4 or cx > 5 or cz < 4 or cz > 5) and ry == 5 then
data[ivm] = node['fun_caves:dungeon_floor_1']
elseif content[cx][cy][cz] == 'room' then
data[ivm] = node['air']
elseif content[cx][cy][cz] == '4way' and ry <= 2 and (rz == 2 or rz == 3 or rx == 2 or rx == 3) and (ox + rx >= minp.x + 2 and ox + rx <= maxp.x - 3 and oz + rz >= minp.z + 2 and oz + rz <= maxp.z - 3) then
data[ivm] = node['air']
elseif ry > 0 and content[cx][cy][cz] == '4way' then
data[ivm] = node['fun_caves:dungeon_wall_1']
end
end
ivm = ivm + 1
end
end
end
end
end
end
end
for i = 0, #data do
if data[i] == 'stairway' then
data[i] = node['air']
end
end
return true, true
end