Most dungeon features working.
This commit is contained in:
parent
5abe211fb6
commit
61c3cb0edd
7 changed files with 570 additions and 710 deletions
159
abms.lua
159
abms.lua
|
@ -10,8 +10,6 @@ local cold_delay = 5
|
|||
local monster_delay = 3
|
||||
local hunger_delay = 60
|
||||
local dps_count = hunger_delay
|
||||
-- maximum number of mobs near player in fortresses
|
||||
local fortress_mob_count = 5
|
||||
local players_in_orbit = {}
|
||||
|
||||
local mushrooms = {"flowers:mushroom_brown", "flowers:mushroom_red"}
|
||||
|
@ -63,7 +61,6 @@ local cold_stuff = {"group:surface_cold"}
|
|||
local poison_stuff = {"group:poison"}
|
||||
local gravity_off = {gravity = 0.1}
|
||||
local gravity_on = {gravity = 1}
|
||||
local fortress_floor = {x = 30, y = 2, z = 30}
|
||||
local fortress_group = {'group:fortress'}
|
||||
|
||||
local firework_active = false
|
||||
|
@ -131,20 +128,11 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
|
||||
-- Promote mobs based on spawn position
|
||||
local is_fortress = fun_caves.is_fortress
|
||||
if not is_fortress then
|
||||
return
|
||||
end
|
||||
|
||||
for _, mob in pairs(minetest.luaentities) do
|
||||
if not mob.initial_promotion then
|
||||
local pos = mob.object:getpos()
|
||||
if mob.hp_max and mob.object and mob.health and mob.damage then
|
||||
local factor = 1 + (math.max(math.abs(pos.x), math.abs(pos.y), math.abs(pos.z)) / 6200)
|
||||
if is_fortress(pos) then
|
||||
mob.started_in_fortress = true
|
||||
factor = factor * 1.5
|
||||
end
|
||||
mob.hp_max = math.floor(mob.hp_max * factor)
|
||||
mob.damage = math.floor(mob.damage * factor)
|
||||
mob.object:set_hp(mob.hp_max)
|
||||
|
@ -155,53 +143,17 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
end
|
||||
|
||||
-- Spawn mobs in fortresses -- only when a player is near
|
||||
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
|
||||
local players = minetest.get_connected_players()
|
||||
if not (players and type(players) == 'table') then
|
||||
return
|
||||
end
|
||||
|
||||
--local do_fortress_spawns = (fun_caves.fortress_spawns and #fun_caves.fortress_spawns > 0)
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local pos = player:getpos()
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
--if do_fortress_spawns and is_fortress(pos) and dps_count % monster_delay == 0 then
|
||||
-- -- How many mobs are up at the moment? This is a rough check.
|
||||
-- local mob_count = 0
|
||||
-- for _, mob in pairs(minetest.luaentities) do
|
||||
-- if mob.health and mob.started_in_fortress then
|
||||
-- local dist = vector.subtract(pos, mob.object:getpos())
|
||||
-- local dist2 = math.max(math.abs(dist.x), math.abs(dist.y * 5), math.abs(dist.z))
|
||||
-- if dist2 < 30 then
|
||||
-- mob_count = mob_count + 1
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- -- If we need more, spawn them.
|
||||
-- if mob_count < fortress_mob_count then
|
||||
-- local f1 = vector.subtract(pos, fortress_floor)
|
||||
-- local f2 = vector.add(pos, fortress_floor)
|
||||
-- local floor_nodes = minetest.find_nodes_in_area_under_air(f1, f2, fortress_group)
|
||||
-- if not (floor_nodes and type(floor_nodes) == 'table') then
|
||||
-- return
|
||||
-- end
|
||||
|
||||
-- if #floor_nodes > 0 then
|
||||
-- local new_mob_pos = floor_nodes[math.random(#floor_nodes)]
|
||||
-- new_mob_pos.y = new_mob_pos.y + 2
|
||||
-- --------------------------------------
|
||||
-- -- Mobs are treated exacty the same. Spawn harder ones differently?
|
||||
-- --------------------------------------
|
||||
-- local name = fun_caves.fortress_spawns[math.random(#fun_caves.fortress_spawns)]
|
||||
-- minetest.add_entity(new_mob_pos, name)
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
|
||||
if pos.y >= 11168 and pos.y <= 15168 then
|
||||
if not players_in_orbit[player_name] then
|
||||
player:set_physics_override(gravity_off)
|
||||
|
@ -421,10 +373,121 @@ minetest.register_abm({
|
|||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fun_caves:coffer"},
|
||||
interval = time_factor,
|
||||
chance = 10,
|
||||
action = function(p0, node, _, _)
|
||||
minetest.remove_node(p0)
|
||||
end,
|
||||
})
|
||||
|
||||
------------------------------------------------------------
|
||||
-- creation
|
||||
------------------------------------------------------------
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fun_caves:dungeon_floor_1"},
|
||||
interval = 20 * time_factor,
|
||||
chance = 250,
|
||||
catch_up = false,
|
||||
action = function(pos, node, aoc, active_object_count_wider)
|
||||
if not (pos and node) or active_object_count_wider > 10 then
|
||||
return
|
||||
end
|
||||
|
||||
for i = 1, 2 do
|
||||
pos.y = pos.y + 1
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node or node.name ~= "air" then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------
|
||||
-- Mobs are treated exacty the same. Spawn harder ones differently?
|
||||
--------------------------------------
|
||||
local name = fun_caves.fortress_spawns[math.random(#fun_caves.fortress_spawns)]
|
||||
local mob = minetest.add_entity(pos, name)
|
||||
if not mob then
|
||||
return
|
||||
end
|
||||
print('spawning '..name)
|
||||
|
||||
if mob.hp_max and mob.object and mob.health and mob.damage then
|
||||
local factor = 1 + (math.max(math.abs(pos.x), math.abs(pos.y), math.abs(pos.z)) / 6200)
|
||||
mob.started_in_fortress = true
|
||||
factor = factor * 1.5
|
||||
mob.hp_max = math.floor(mob.hp_max * factor)
|
||||
mob.damage = math.floor(mob.damage * factor)
|
||||
mob.object:set_hp(mob.hp_max)
|
||||
mob.health = mob.hp_max
|
||||
mob.initial_promotion = true
|
||||
check_for_death(mob)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fun_caves:dungeon_floor_1"},
|
||||
interval = 20 * time_factor,
|
||||
chance = 1000,
|
||||
catch_up = false,
|
||||
action = function(pos, node)
|
||||
if not (pos and node) then
|
||||
return
|
||||
end
|
||||
|
||||
pos.y = pos.y + 1
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node or node.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.set_node(pos, {name = 'fun_caves:coffer'})
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fun_caves:dungeon_wall_1"},
|
||||
interval = time_factor,
|
||||
chance = 100,
|
||||
catch_up = false,
|
||||
action = function(pos, node)
|
||||
if not (pos and node) then
|
||||
return
|
||||
end
|
||||
|
||||
pos = vector.round(pos)
|
||||
|
||||
local dir = math.random(4)
|
||||
local p2 = 3
|
||||
if dir == 1 then
|
||||
pos.x = pos.x + 1
|
||||
elseif dir == 2 then
|
||||
pos.x = pos.x - 1
|
||||
p2 = 2
|
||||
elseif dir == 3 then
|
||||
pos.z = pos.z + 1
|
||||
p2 = 5
|
||||
elseif dir == 4 then
|
||||
pos.z = pos.z - 1
|
||||
p2 = 4
|
||||
end
|
||||
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
if not node or node.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
if (minetest.get_node_light(pos, nil) or 99) > 0 then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.set_node(pos, {name = 'default:torch', param2 = p2})
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"fun_caves:tree"},
|
||||
neighbors = {'fire:basic_flame'},
|
||||
|
|
|
@ -3,6 +3,7 @@ flowers
|
|||
wool
|
||||
bucket
|
||||
beds
|
||||
stairs
|
||||
farming?
|
||||
hunger?
|
||||
mobs?
|
||||
|
|
385
dungeon.lua
Normal file
385
dungeon.lua
Normal 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
|
600
fortress.lua
600
fortress.lua
|
@ -1,600 +0,0 @@
|
|||
local max_depth = 31000
|
||||
local cells = 10
|
||||
local cell_size = 60 / cells
|
||||
local fortress_depth = -1 -- close to y / 80
|
||||
|
||||
|
||||
if fun_caves.path then
|
||||
dofile(fun_caves.path .. "/trophies.lua")
|
||||
dofile(fun_caves.path .. "/tesseract.lua")
|
||||
end
|
||||
|
||||
|
||||
fun_caves.is_fortress = function(pos, cs)
|
||||
if not pos then
|
||||
return
|
||||
end
|
||||
|
||||
-- Fix this to get csize, somehow.
|
||||
-- Remember that this function may be called
|
||||
-- before any chunks are generated.
|
||||
|
||||
pos = vector.round(pos)
|
||||
local cs = cs or {x=80, y=80, z=80}
|
||||
local offset = math.floor(cs.y / 2) - 8 + 1
|
||||
|
||||
local x = math.floor((pos.x + offset) / cs.x)
|
||||
local z = math.floor((pos.z + offset) / cs.z)
|
||||
|
||||
return true
|
||||
|
||||
--local n = minetest.get_perlin(fortress_noise):get3d({x=x, y=y, z=z})
|
||||
--if not (n and type(n) == 'number') then
|
||||
-- return
|
||||
--end
|
||||
|
||||
--if math.floor((n * 10000) % 13) == 1 then
|
||||
-- return true
|
||||
--end
|
||||
|
||||
--return false
|
||||
end
|
||||
|
||||
--fun_caves.is_fortress = function(pos, cs)
|
||||
-- if not pos then
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- -- Fix this to get csize, somehow.
|
||||
-- -- Remember that this function may be called
|
||||
-- -- before any chunks are generated.
|
||||
--
|
||||
-- pos = vector.round(pos)
|
||||
-- local cs = cs or {x=80, y=80, z=80}
|
||||
-- local offset = math.floor(cs.y / 2) - 8 + 1
|
||||
--
|
||||
-- local y = math.floor((pos.y + offset) / cs.y)
|
||||
--
|
||||
-- -- Fortresses show up below ground.
|
||||
-- if y > fortress_depth then
|
||||
-- return false
|
||||
-- end
|
||||
--
|
||||
-- local x = math.floor((pos.x + offset) / cs.x)
|
||||
-- local z = math.floor((pos.z + offset) / cs.z)
|
||||
--
|
||||
-- local n = minetest.get_perlin(fortress_noise):get3d({x=x, y=y, z=z})
|
||||
-- if not (n and type(n) == 'number') then
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- if math.floor((n * 10000) % 13) == 1 then
|
||||
-- return true
|
||||
-- end
|
||||
--
|
||||
-- return false
|
||||
--end
|
||||
|
||||
|
||||
-- dungeon floor, basic
|
||||
newnode = fun_caves.clone_node("default:cobble")
|
||||
newnode.description = "Dungeon Stone"
|
||||
newnode.legacy_mineral = false
|
||||
newnode.groups = {fortress = 1}
|
||||
minetest.register_node("fun_caves:dungeon_floor_1", newnode)
|
||||
|
||||
-- dungeon walls, basic
|
||||
newnode = fun_caves.clone_node("default:cobble")
|
||||
newnode.description = "Dungeon Stone"
|
||||
newnode.groups = {fortress = 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 = {fortress = 1}
|
||||
minetest.register_node("fun_caves:dungeon_wall_2", newnode)
|
||||
|
||||
newnode = fun_caves.clone_node("default:glass")
|
||||
newnode.description = "Dungeon Stone"
|
||||
newnode.groups = {fortress = 1}
|
||||
minetest.register_node("fun_caves:dungeon_wall_transparent", newnode)
|
||||
|
||||
newnode = fun_caves.clone_node("default:glass")
|
||||
newnode.description = "Dungeon Stone"
|
||||
newnode.groups = {fortress = 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 = {fortress = 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)
|
||||
|
||||
|
||||
-- All arrays in the maze functions are zero-based.
|
||||
local floor_noise_1 = {offset = 0, scale = 1, seed = 1587, spread = {x = 30, y = 30, z = 30}, octaves = 3, persist = 1, lacunarity = 2}
|
||||
|
||||
function table.shuffle(self)
|
||||
local j
|
||||
local t = self
|
||||
|
||||
for i = #t, 1, -1 do
|
||||
j = math.random(0, i)
|
||||
t[i], t[j] = t[j], t[i]
|
||||
end
|
||||
end
|
||||
|
||||
function unionfind(max)
|
||||
if not (max and type(max) == 'number') then
|
||||
return
|
||||
end
|
||||
|
||||
local u = { _parent = {}, _rank = {} }
|
||||
|
||||
for i = 0, max-1 do
|
||||
u._parent[i] = i
|
||||
u._rank[i] = 0
|
||||
end
|
||||
|
||||
u.find = function(self, i)
|
||||
local p = self._parent[i]
|
||||
if i == p then
|
||||
return i
|
||||
end
|
||||
self._parent[i] = self:find(p)
|
||||
return self._parent[i]
|
||||
end
|
||||
|
||||
u.union = function(self, i, j)
|
||||
i = i or 0
|
||||
j = j or 0
|
||||
local root1 = self:find(i)
|
||||
local root2 = self:find(j)
|
||||
|
||||
if root1 == root2 then
|
||||
return
|
||||
end
|
||||
|
||||
if self._rank[root1] > self._rank[root2] then
|
||||
self._parent[root2] = root1
|
||||
elseif self._rank[root2] > self._rank[root1] then
|
||||
self._parent[root1] = root2
|
||||
else
|
||||
self._parent[root2] = root1
|
||||
self._rank[root1] = self._rank[root1] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return u
|
||||
end
|
||||
|
||||
|
||||
local function maze_floor(y2, minp, maxp, data, area, node)
|
||||
if not (y2 and minp and maxp and data and area and node and type(y2) == 'number' and type(data) == 'table') then
|
||||
return
|
||||
end
|
||||
|
||||
-- walls is zero-based.
|
||||
local walls = {}
|
||||
for i = 0, 2 * cells * cells - 1 do
|
||||
walls[i] = i
|
||||
end
|
||||
table.shuffle(walls)
|
||||
|
||||
local set = unionfind(cells * cells)
|
||||
|
||||
-- Remove walls in a continuous path.
|
||||
for m = 0, #walls-1 do
|
||||
local c = walls[m]
|
||||
local a = math.floor(c / 2)
|
||||
local i = a % cells
|
||||
local j = math.floor(a / cells)
|
||||
local u = c % 2 == 0 and 1 or 0
|
||||
local v = c % 2 == 1 and 1 or 0
|
||||
local b = a + u + cells * v
|
||||
if i < cells - u and j < cells - v and set:find(a) ~= set:find(b) then
|
||||
set:union(a, b)
|
||||
local x = (i + u) * cell_size + minp.x
|
||||
local y = minp.y + y2 * cell_size
|
||||
local z = (j + v) * cell_size + minp.z
|
||||
|
||||
for z1 = z + (1-v), z + (1-v) * (cell_size - 1) do
|
||||
for y1 = y + 1, y + (cell_size - 1) do
|
||||
local ivm = area:index(x + (1-u), y1, z1)
|
||||
for x1 = x + (1-u), x + (1-u) * (cell_size - 1) do
|
||||
if x1 < maxp.x and z1 < maxp.z and x1 > minp.x and z1 > minp.z then
|
||||
data[ivm] = node["air"]
|
||||
end
|
||||
ivm = ivm + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local designs = {
|
||||
{
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0},
|
||||
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
|
||||
{1,1,0,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,1,0},
|
||||
{1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
|
||||
{1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0},
|
||||
{0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0},
|
||||
{0,1,1,1,0,1,1,1,0,1,0,1,1,1,1,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
},
|
||||
{
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
},
|
||||
{
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0},
|
||||
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
|
||||
{0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0},
|
||||
{0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,1,1,1,1,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,0},
|
||||
{0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0},
|
||||
{0,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,1,0},
|
||||
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
|
||||
{0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
},
|
||||
{
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
{0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0},
|
||||
},
|
||||
}
|
||||
|
||||
local function design_floor(y2, minp, maxp, data, area, node)
|
||||
if not (y2 and minp and maxp and data and area and node and type(y2) == 'number' and type(data) == 'table') then
|
||||
return
|
||||
end
|
||||
|
||||
local design = designs[math.random(#designs)]
|
||||
|
||||
local py = minp.y + y2 * cell_size
|
||||
for z = 1, 10 do
|
||||
for x = 1, 9 do
|
||||
if design[z * 2 - 1][x * 2] == 0 then
|
||||
local px = minp.x + x * cell_size
|
||||
local pz = minp.z + (z - 1) * cell_size
|
||||
for z1 = pz + 1, pz + cell_size - 1 do
|
||||
local ivm = area:index(px, py + 1, z1)
|
||||
for y1 = py + 1, py + cell_size - 1 do
|
||||
data[ivm] = node['air']
|
||||
ivm = ivm + area.ystride
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for z = 1, 9 do
|
||||
for x = 1, 10 do
|
||||
if design[z * 2][x * 2 - 1] == 0 then
|
||||
local px = minp.x + (x - 1) * cell_size
|
||||
local pz = minp.z + z * cell_size
|
||||
for x1 = px + 1, px + cell_size - 1 do
|
||||
local ivm = area:index(x1, py + 1, pz)
|
||||
for y1 = py + 1, py + cell_size - 1 do
|
||||
data[ivm] = node['air']
|
||||
ivm = ivm + area.ystride
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for z = 1, 9 do
|
||||
for x = 1, 9 do
|
||||
if design[z * 2][x * 2] == 0 then
|
||||
local px = minp.x + x * cell_size
|
||||
local pz = minp.z + z * cell_size
|
||||
local ivm = area:index(px, py + 1, pz)
|
||||
for y1 = py + 1, py + cell_size - 1 do
|
||||
data[ivm] = node['air']
|
||||
ivm = ivm + area.ystride
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
fun_caves.fortress = function(minp_in, maxp_in, data, area, node)
|
||||
if not (minp_in and maxp_in and data and area and node and type(data) == 'table') then
|
||||
return
|
||||
end
|
||||
|
||||
local minp = table.copy(minp_in)
|
||||
minp.x = minp.x + 10
|
||||
minp.z = minp.z + 10
|
||||
local 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
|
||||
local csize = vector.add(vector.subtract(maxp_in, minp_in), 1)
|
||||
|
||||
for z = minp.z - 1, maxp.z + 1 do
|
||||
for y = minp.y - 1, maxp.y + 1 do
|
||||
local ivm = area:index(minp.x - 1, y, z)
|
||||
for x = minp.x - 1, maxp.x + 1 do
|
||||
data[ivm] = node['default:cobble']
|
||||
ivm = ivm + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for cz = 0, 9 do
|
||||
local oz = minp.z + cz * 6
|
||||
for cy = 0, 13 do
|
||||
local oy = minp.y + cy * 6
|
||||
for cx = 0, 9 do
|
||||
local ox = minp.x + cx * 6
|
||||
local room = math.random(2)
|
||||
|
||||
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 room == 1 and (ry == 0 or ry == 5) then
|
||||
data[ivm] = node['fun_caves:dungeon_floor_1']
|
||||
elseif room == 1 then
|
||||
data[ivm] = node['air']
|
||||
elseif room == 2 and (ry == 1 or 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 room == 2 then
|
||||
data[ivm] = node['fun_caves:dungeon_wall_1']
|
||||
end
|
||||
|
||||
ivm = ivm + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--fun_caves.fortress = function(minp_in, maxp_in, data, area, node)
|
||||
-- if not (minp_in and maxp_in and data and area and node and type(data) == 'table') then
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- -- hungry maze
|
||||
-- -- chests (w traps)
|
||||
-- -- step traps (math based)
|
||||
-- -- hidden doors/downs
|
||||
-- -- hot/ice floors
|
||||
-- -- torches
|
||||
-- --
|
||||
-- local minp = vector.add(minp_in, 10)
|
||||
-- local maxp = vector.subtract(maxp_in, 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
|
||||
-- local csize = vector.add(vector.subtract(maxp_in, minp_in), 1)
|
||||
-- local floor_1 = minetest.get_perlin_map(floor_noise_1, {x=csize.x, y=csize.z}):get2dMap_flat({x=minp_in.x, y=minp_in.z})
|
||||
-- if not floor_1 then
|
||||
-- return
|
||||
-- end
|
||||
--
|
||||
-- for y2 = 0, cells-1 do
|
||||
-- local floor_type = math.random(20)
|
||||
--
|
||||
-- local dox, doz = math.random(0, cells-1), math.random(0, cells-1)
|
||||
-- for z = minp.z, maxp.z do
|
||||
-- for y = minp.y + y2 * cell_size, minp.y + y2 * cell_size + (cell_size - 1) do
|
||||
-- local ivm = area:index(minp.x, y, z)
|
||||
-- for x = minp.x, maxp.x do
|
||||
-- if x == minp.x or z == minp.z or x == maxp.x or z == maxp.z then
|
||||
-- data[ivm] = outer_wall
|
||||
-- elseif (y - minp.y) % cell_size == 0 then
|
||||
-- if math.floor((z - minp.z) / cell_size) == doz and math.floor((x - minp.x) / cell_size) == dox and (z - minp.z) % cell_size ~= 0 and (x - minp.x) % cell_size ~= 0 and y ~= minp.y then
|
||||
-- data[ivm] = node["air"]
|
||||
-- else
|
||||
-- data[ivm] = inner_floor
|
||||
-- end
|
||||
-- elseif floor_type ~= 3 and ((z - minp.z) % cell_size == 0 or (x - minp.x) % cell_size == 0) then
|
||||
-- if y == minp.y + y2 * cell_size + 3 and ((z - minp.z) % cell_size == 3 or (x - minp.x) % cell_size == 3) and math.random(5) == 1 then
|
||||
-- data[ivm] = node['fun_caves:dungeon_light']
|
||||
-- elseif floor_type == 1 and level > 3 then
|
||||
-- data[ivm] = node['fun_caves:dungeon_wall_invisible']
|
||||
-- elseif floor_type == 1 then
|
||||
-- data[ivm] = node['fun_caves:dungeon_wall_transparent']
|
||||
-- elseif floor_type ~= 3 then
|
||||
-- data[ivm] = inner_wall
|
||||
-- end
|
||||
-- else
|
||||
-- if y2 == 0 and y == minp.y + y2 * cell_size + 1 and data[ivm - area.ystride] ~= node['air'] and math.random(200) == 1 then
|
||||
-- treasure_count = treasure_count + 1
|
||||
-- data[ivm] = node['fun_caves:coffer']
|
||||
-- else
|
||||
-- data[ivm] = node["air"]
|
||||
-- end
|
||||
-- end
|
||||
-- ivm = ivm + 1
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- if floor_type ~= 3 then
|
||||
-- local wall_type = math.random(#designs + 1)
|
||||
--
|
||||
-- if wall_type == 1 then
|
||||
-- maze_floor(y2, minp, maxp, data, area, node)
|
||||
-- else
|
||||
-- design_floor(y2, minp, maxp, data, area, node)
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- local index = 0
|
||||
-- for z = minp.z + 1, maxp.z - 1 do
|
||||
-- for x = minp.x + 1, maxp.x - 1 do
|
||||
-- local ivm = area:index(x, minp.y + y2 * cell_size, z)
|
||||
--
|
||||
-- if floor_type == 2 then
|
||||
-- if data[ivm] ~= node['air'] and data[ivm + area.ystride] == node['air'] then
|
||||
-- if level > 3 then
|
||||
-- data[ivm + area.ystride] = node['default:lava_source']
|
||||
-- else
|
||||
-- data[ivm + area.ystride] = node['fun_caves:hot_cobble']
|
||||
-- end
|
||||
-- end
|
||||
-- elseif floor_type == 3 then
|
||||
-- if (y2 < 9 or (z - minp_in.z) > 16 or (x - minp_in.x) > 16) and data[ivm] ~= node['air'] then
|
||||
-- local index = (z - minp_in.z) * csize.x + x - minp_in.x
|
||||
-- for i = 1, math.min((cell_size - 1), math.floor((cell_size - 1) * math.abs(floor_1[index]))) do
|
||||
-- if data[ivm + area.ystride * i] == node['air'] then
|
||||
-- data[ivm + area.ystride * i] = node['default:dirt']
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- elseif floor_type == 4 then
|
||||
-- for i = 1, (cell_size - 1) do
|
||||
-- if data[ivm + area.ystride * i] == node['air'] then
|
||||
-- data[ivm + area.ystride * i] = node['default:water_source']
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--end
|
101
mapgen.lua
101
mapgen.lua
|
@ -1,6 +1,5 @@
|
|||
local max_depth = 31000
|
||||
local seed_noise = {offset = 0, scale = 32768, seed = 5202, spread = {x = 80, y = 80, z = 80}, octaves = 2, persist = 0.4, lacunarity = 2}
|
||||
local fortress_noise = {offset = 0, scale = 1, seed = -4082, spread = {x = 7, y = 7, z = 7}, octaves = 4, persist = 1, lacunarity = 2}
|
||||
|
||||
|
||||
-- This tables looks up nodes that aren't already stored.
|
||||
|
@ -409,40 +408,76 @@ local function generate(p_minp, p_maxp, seed)
|
|||
end
|
||||
|
||||
local aster = false
|
||||
if minp.y > 17200 then
|
||||
-- nop
|
||||
elseif minp.y > 11000 and fun_caves.asteroids then
|
||||
write = fun_caves.asteroids(minp, maxp, data, p2data, area, node)
|
||||
aster = true
|
||||
elseif minp.y > 8400 and fun_caves.skysea then
|
||||
write = fun_caves.skysea(minp, maxp, data, p2data, area, node)
|
||||
elseif minp.y > 4000 and fun_caves.cloudgen then
|
||||
write = fun_caves.cloudgen(minp, maxp, data, p2data, area, node)
|
||||
elseif not underzone and fun_caves.is_fortress(minp, csize) and fun_caves.fortress then
|
||||
fun_caves.fortress(minp, maxp, data, area, node)
|
||||
write = true
|
||||
elseif fun_caves.cavegen and fun_caves.decogen and fun_caves.treegen then
|
||||
local write_cave, write_deco, write_tree, write_pyr, write_vill, h2
|
||||
write_cave, h2 = fun_caves.cavegen(minp, maxp, data, area, node, heightmap, underzone, ground_nodes)
|
||||
if h2 then
|
||||
heightmap = h2
|
||||
for fake_loop = 1, 1 do
|
||||
if minp.y > 17200 then
|
||||
break
|
||||
end
|
||||
|
||||
local biomemap
|
||||
if fun_caves.use_bi_hi then
|
||||
biomemap = minetest.get_mapgen_object("biomemap")
|
||||
if minp.y > 11000 and fun_caves.asteroids then
|
||||
write = fun_caves.asteroids(minp, maxp, data, p2data, area, node)
|
||||
aster = true
|
||||
break
|
||||
end
|
||||
|
||||
write_deco, write_p2 = fun_caves.decogen(minp, maxp, data, p2data, area, node, heightmap, biomemap, biome_ids, underzone)
|
||||
write_tree = fun_caves.treegen(minp, maxp, data, p2data, area, node)
|
||||
if not write_tree and fun_caves.pyramid then
|
||||
write_pyr, write_p4 = fun_caves.pyramid(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap)
|
||||
if minp.y > 8400 and fun_caves.skysea then
|
||||
write = fun_caves.skysea(minp, maxp, data, p2data, area, node)
|
||||
break
|
||||
end
|
||||
if fun_caves.use_villages and biomemap and not (write_tree or write_pyr) and fun_caves.village then
|
||||
local biome = biome_ids[biomemap[40*80+40]]
|
||||
write_vill = fun_caves.village(minp, maxp, data, p2data, area, node, biome, heightmap)
|
||||
|
||||
if minp.y > 4000 and fun_caves.cloudgen then
|
||||
write = fun_caves.cloudgen(minp, maxp, data, p2data, area, node)
|
||||
break
|
||||
end
|
||||
|
||||
if fun_caves.dungeon then
|
||||
write, write_p2 = fun_caves.dungeon(minp, maxp, data, p2data, area, node, heightmap)
|
||||
if write then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if fun_caves.cavegen and fun_caves.decogen then
|
||||
local h2
|
||||
write, h2 = fun_caves.cavegen(minp, maxp, data, area, node, heightmap, underzone, ground_nodes)
|
||||
if h2 then
|
||||
heightmap = h2
|
||||
end
|
||||
|
||||
local biomemap
|
||||
if fun_caves.use_bi_hi then
|
||||
biomemap = minetest.get_mapgen_object("biomemap")
|
||||
end
|
||||
|
||||
local write_deco
|
||||
write_deco, write_p2 = fun_caves.decogen(minp, maxp, data, p2data, area, node, heightmap, biomemap, biome_ids, underzone)
|
||||
write = write or write_deco
|
||||
|
||||
if fun_caves.treegen then
|
||||
local write_tree = fun_caves.treegen(minp, maxp, data, p2data, area, node)
|
||||
if write_tree then
|
||||
write = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if fun_caves.pyramid then
|
||||
local write_pyr, write_p4 = fun_caves.pyramid(minp, maxp, data, p2data, area, biomemap, biome_ids, node, heightmap)
|
||||
if write_pyr then
|
||||
write = true
|
||||
write_p2 = write_p2 or write_p4
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if fun_caves.use_villages and biomemap and fun_caves.village then
|
||||
local biome = biome_ids[biomemap[40*80+40]]
|
||||
local write_vill = fun_caves.village(minp, maxp, data, p2data, area, node, biome, heightmap)
|
||||
if write_vill then
|
||||
write = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
write = write_cave or write_deco or write_tree or write_pyr or write_vill
|
||||
end
|
||||
|
||||
|
||||
|
@ -452,7 +487,7 @@ local function generate(p_minp, p_maxp, seed)
|
|||
vm:set_param2_data(p2data)
|
||||
end
|
||||
|
||||
if true or fun_caves.DEBUG then
|
||||
if fun_caves.DEBUG then
|
||||
vm:set_lighting({day = 15, night = 15})
|
||||
else
|
||||
-- set_lighting causes lighting artifacts,
|
||||
|
@ -473,7 +508,7 @@ if fun_caves.path then
|
|||
dofile(fun_caves.path .. "/cavegen.lua")
|
||||
dofile(fun_caves.path .. "/cloudgen.lua")
|
||||
dofile(fun_caves.path .. "/decogen.lua")
|
||||
dofile(fun_caves.path .. "/fortress.lua")
|
||||
dofile(fun_caves.path .. "/dungeon.lua")
|
||||
dofile(fun_caves.path .. "/pyramid.lua")
|
||||
dofile(fun_caves.path .. "/treegen.lua")
|
||||
dofile(fun_caves.path .. "/village.lua")
|
||||
|
@ -482,7 +517,9 @@ end
|
|||
|
||||
|
||||
local function pgenerate(...)
|
||||
local status, err = pcall(generate, ...)
|
||||
--local status, err = pcall(generate, ...)
|
||||
local status, err = true
|
||||
generate(...)
|
||||
if not status then
|
||||
print('Fun Caves: Could not generate terrain:')
|
||||
print(dump(err))
|
||||
|
|
4
mobs.lua
4
mobs.lua
|
@ -851,7 +851,7 @@ local t_mobs = {
|
|||
}
|
||||
for _, mob in pairs(t_mobs) do
|
||||
if minetest.registered_entities[mob] then
|
||||
mobs:register_spawn(mob, {"fun_caves:dungeon_floor_1"}, 20, 0, 2000, 5, 31000)
|
||||
--fun_caves.fortress_spawns[#fun_caves.fortress_spawns+1] = mob
|
||||
--mobs:register_spawn(mob, {"fun_caves:dungeon_floor_1"}, 20, 0, 2000, 5, 31000)
|
||||
fun_caves.fortress_spawns[#fun_caves.fortress_spawns+1] = mob
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
local max_depth = 31000
|
||||
|
||||
local function teleporter(user, area, power)
|
||||
if not (user and area and power and type(power) == 'number' and fun_caves.world and fun_caves.db and fun_caves.db.teleport_data and fun_caves.underzones and fun_caves.is_fortress and fun_caves.cave_noise_1 and fun_caves.cave_noise_2 and fun_caves.cave_width) then
|
||||
if not (user and area and power and type(power) == 'number' and fun_caves.world and fun_caves.db and fun_caves.db.teleport_data and fun_caves.underzones and fun_caves.cave_noise_1 and fun_caves.cave_noise_2 and fun_caves.cave_width) then
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -43,32 +43,6 @@ local function teleporter(user, area, power)
|
|||
y = ({4368, 8768, 13168, 4368, 4368, 4368})[power+1]+76,
|
||||
z = pos.z + (math.random(5) - math.random(5)) * 80,
|
||||
}
|
||||
elseif area == 'dungeon' then
|
||||
newpos = {}
|
||||
local base_pos = table.copy(pos)
|
||||
base_pos.x = base_pos.x - (base_pos.x + 32) % 80 + 12
|
||||
base_pos.z = base_pos.z - (base_pos.z + 32) % 80 + 12
|
||||
if power > 0 then
|
||||
base_pos.y = fun_caves.underzones[({'Caina','Phlegethos','Dis','Minauros', 'Phlegethos','Styx'})[power]].lower_bound
|
||||
end
|
||||
|
||||
base_pos.y = base_pos.y - (base_pos.y + 32) % 80 - 15
|
||||
|
||||
for i = 1, 8000 do
|
||||
newpos = {
|
||||
x = base_pos.x + (math.random(5) - math.random(5)) * 80,
|
||||
y = base_pos.y - math.random(50) * 80,
|
||||
z = base_pos.z + (math.random(5) - math.random(5)) * 80,
|
||||
}
|
||||
|
||||
if fun_caves.is_fortress(newpos) then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not fun_caves.is_fortress(newpos) then
|
||||
return
|
||||
end
|
||||
elseif area == 'underworld' then
|
||||
local good = false
|
||||
local base_pos = table.copy(pos)
|
||||
|
@ -128,7 +102,7 @@ local gems = {
|
|||
{gem = 'Moonstone', teleport = 'sky', ore = true},
|
||||
{gem = 'Garnet', teleport = 'underworld', ore = true},
|
||||
{gem = 'Coral Gem', teleport = 'hell'},
|
||||
{gem = 'Zoisite', teleport = 'dungeon', ore = true},
|
||||
--{gem = 'Zoisite', teleport = 'dungeon', ore = true},
|
||||
{gem = 'Aquamarine', teleport = 'overworld', ore = true},
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue