diff --git a/init.lua b/init.lua index 2848caa..61fbcc6 100644 --- a/init.lua +++ b/init.lua @@ -99,21 +99,46 @@ local function make_foundation_part(pos, set_to_stone) end end -local function make_entrance(pos, brick, sand, flood_sand) - local gang = {x=pos.x+10,y=pos.y, z=pos.z} +local function make_entrance(pos, rot, brick, sand, flood_sand) + local roffset_arr = { + { x=0, y=0, z=1 }, -- front + { x=-1, y=0, z=0 }, -- left + { x=0, y=0, z=-1 }, -- back + { x=1, y=0, z=0 }, -- right + } + local roffset = roffset_arr[rot + 1] + local way + if rot == 0 then + way = vector.add(pos, {x=11, y=0, z=0}) + elseif rot == 1 then + way = vector.add(pos, {x=22, y=0, z=11}) + elseif rot == 2 then + way = vector.add(pos, {x=11, y=0, z=22}) + else + way = vector.add(pos, {x=0, y=0, z=11}) + end local max_sand_height = math.random(1,3) - for iz=0,6,1 do + for ie=0,6,1 do local sand_height = math.random(1,max_sand_height) for iy=2,3,1 do - if flood_sand and iy <= sand_height and iz >= 3 then - minetest.set_node({x=gang.x+1,y=gang.y+iy,z=gang.z+iz}, {name=sand}) + -- dig hallway + local way_dir = vector.add(vector.add(way, {x=0,y=iy,z=0}), vector.multiply(roffset, ie)) + if flood_sand and iy <= sand_height and ie >= 3 then + minetest.set_node(way_dir, {name=sand}) else - minetest.remove_node({x=gang.x+1,y=gang.y+iy,z=gang.z+iz}) + minetest.remove_node(way_dir) end - if iz >=3 and iy == 3 then - minetest.set_node({x=gang.x,y=gang.y+iy+1,z=gang.z+iz}, {name=brick}) - minetest.set_node({x=gang.x+1,y=gang.y+iy+1,z=gang.z+iz}, {name=brick}) - minetest.set_node({x=gang.x+2,y=gang.y+iy+1,z=gang.z+iz}, {name=brick}) + -- build decoration above entrance + if ie >=3 and iy == 3 then + local deco = {x=way_dir.x, y=way_dir.y+1,z=way_dir.z} + minetest.set_node(deco, {name=brick}) + if rot == 0 or rot == 2 then + minetest.set_node(vector.add(deco, {x=-1, y=0, z=0}), {name=brick}) + minetest.set_node(vector.add(deco, {x=1, y=0, z=0}), {name=brick}) + else + minetest.set_node(vector.add(deco, {x=0, y=0, z=-1}), {name=brick}) + minetest.set_node(vector.add(deco, {x=0, y=0, z=1}), {name=brick}) + end end end end @@ -148,22 +173,28 @@ end local function make(pos, brick, sandstone, stone, sand, ptype, room_id) -- Build pyramid make_pyramid(pos, brick, sandstone, stone, sand) + + local rot = math.random(0, 3) -- Build room - local ok, msg, flood_sand = tsm_pyramids.make_room(pos, ptype, room_id) + local ok, msg, flood_sand = tsm_pyramids.make_room(pos, ptype, room_id, rot) -- Place mummy spawner local r = math.random(1,3) - if r == 1 then + -- 4 possible spawner positions + local spawner_posses = { -- front - add_spawner({x=pos.x+11,y=pos.y+2, z=pos.z+17}, {x=0, y=0, z=-2}) - elseif r == 2 then - -- right - add_spawner({x=pos.x+17,y=pos.y+2, z=pos.z+11}, {x=-2, y=0, z=0}) - else + {{x=pos.x+11,y=pos.y+2, z=pos.z+5}, {x=0, y=0, z=2}}, -- left - add_spawner({x=pos.x+5,y=pos.y+2, z=pos.z+11}, {x=2, y=0, z=0}) - end + {{x=pos.x+17,y=pos.y+2, z=pos.z+11}, {x=-2, y=0, z=0}}, + -- back + {{x=pos.x+11,y=pos.y+2, z=pos.z+17}, {x=0, y=0, z=-2}}, + -- right + {{x=pos.x+5,y=pos.y+2, z=pos.z+11}, {x=2, y=0, z=0}}, + } + -- Delete the spawner position in which the entrance will be placed + table.remove(spawner_posses, (rot % 4) + 1) + add_spawner(spawner_posses[r][1], spawner_posses[r][2]) -- Build entrance - make_entrance({x=pos.x,y=pos.y, z=pos.z}, brick, sand, flood_sand) + make_entrance(pos, rot, brick, sand, flood_sand) -- Done minetest.log("action", "Created pyramid at ("..pos.x..","..pos.y..","..pos.z..")") return ok, msg diff --git a/room.lua b/room.lua index 1a7ffd0..7648d8d 100644 --- a/room.lua +++ b/room.lua @@ -2,6 +2,8 @@ local S = minetest.get_translator("tsm_pyramids") -- ROOM LAYOUTS +local ROOM_WIDTH = 9 + local room_types = { -- Pillar room { @@ -587,7 +589,45 @@ local function replace2(str, iy, code_table) return out..code_table[str] end -function tsm_pyramids.make_room(pos, stype, room_id) +local function get_flat_index(x, y, width) + return 1 + x + y * width +end + +local function rotate_layout_single(layout, width) + local size = width*width + local new_layout = {} + for x=0, width-1 do + for y=0, width-1 do + local symbol = layout[get_flat_index((width-1) - y, x, width)] + -- Rotate chest + if symbol == "^" then + symbol = "<" + elseif symbol == "<" then + symbol = "v" + elseif symbol == "v" then + symbol = ">" + elseif symbol == ">" then + symbol = "^" + end + new_layout[get_flat_index(x, y, width)] = symbol + end + end + return new_layout +end + +local function rotate_layout(layout, width, rotations) + local new_layout = table.copy(layout) + for r=1, rotations do + new_layout = rotate_layout_single(new_layout, width) + end + return new_layout +end + +-- pos: Position to spawn pyramid +-- stype: Sand type ("sandstone" or "desert") +-- room_id: Room layout identified (see list of rooms above) +-- rotations: Number of times to rotate the room (0-3) +function tsm_pyramids.make_room(pos, stype, room_id, rotations) local code_table = code_sandstone if stype == "desert" then code_table = code_desert @@ -608,14 +648,15 @@ function tsm_pyramids.make_room(pos, stype, room_id) if room_id < 1 or room_id > #room_types then return false, S("Incorrect room type ID: @1", room_id) end - local room = room_types[room_id] + local room = table.copy(room_types[room_id]) local chests = {} local column_style = math.random(0,4) + local layout = rotate_layout(room.layout, ROOM_WIDTH, rotations) if room.style == "yrepeat" then for iy=0,4,1 do for ix=0,8,1 do for iz=0,8,1 do - local n_str = room.layout[tonumber(ix*9+iz+1)] + local n_str = layout[tonumber(ix*9+iz+1)] local p2 = 0 if n_str == "<" then p2 = 0 @@ -650,7 +691,7 @@ function tsm_pyramids.make_room(pos, stype, room_id) end end if room.traps then - tsm_pyramids.make_traps(pos, stype) + tsm_pyramids.make_traps(pos, stype, rotations) end if sanded then tsm_pyramids.flood_sand(pos, stype) @@ -671,17 +712,18 @@ local shuffle_traps = function(chance) end end -function tsm_pyramids.make_traps(pos, stype) +function tsm_pyramids.make_traps(pos, stype, rotations) local code_table = code_sandstone if stype == "desert" then code_table = code_desert end shuffle_traps(math.random(10,100)) local hole = {x=pos.x+7,y=pos.y, z=pos.z+7} + local layout = rotate_layout(layout_traps, ROOM_WIDTH, rotations) for iy=0,4,1 do for ix=0,8,1 do for iz=0,8,1 do - local n_str = layout_traps[tonumber(ix*9+iz+1)] + local n_str = layout[tonumber(ix*9+iz+1)] local p2 = 0 minetest.set_node({x=hole.x+ix,y=hole.y-iy,z=hole.z+iz}, {name=replace2(n_str, iy, code_table), param2=p2}) end