-- FUNCTIONS local random = map_random local layoutparser = require "layoutparser" -- CONSTANTS local UP = 1 local LEFT = 2 local RIGHT = 3 local DOWN = 4 local floor = { center = nil, top = nil, bottom = nil, left = nil, right = nil, topleft = nil, topright = nil, bottomleft = nil, bottomright = nil } local wall = { topleft = nil, topright = nil, bottomleft = nil, bottomright = nil, vertical = nil, horizontal = nil } local special = { level_exit = nil } local floorDecor = { } local blockingFloorDecor = { } local lightDecor = { } local function load_decor_textures() td0 = add_texture(map, "Objects/Decor0.png") td1 = add_texture(map, "Objects/Decor1.png") -- Skulls table.insert(floorDecor, { td0, td1, 0, 12 * 16, false, false }) table.insert(floorDecor, { td0, td1, 32, 12 * 16, false, false }) table.insert(floorDecor, { td0, td1, 0, 13 * 16, false, false }) table.insert(floorDecor, { td0, td1, 32, 13 * 16, false, false }) table.insert(floorDecor, { td0, td1, 64, 12 * 16, false, true }) table.insert(floorDecor, { td0, td1, 64, 13 * 16, false, true }) -- Bones table.insert(floorDecor, { td0, td1, 16, 12 * 16, false, false }) table.insert(floorDecor, { td0, td1, 48, 12 * 16, false, false }) table.insert(floorDecor, { td0, td1, 16, 13 * 16, false, false }) table.insert(floorDecor, { td0, td1, 48, 13 * 16, false, false }) -- Webs --table.insert(floorDecor, { td0, td1, 0 * 16, 19 * 16, false }) --table.insert(floorDecor, { td0, td1, 1 * 16, 19 * 16, false }) --table.insert(floorDecor, { td0, td1, 2 * 16, 19 * 16, false }) --table.insert(floorDecor, { td0, td1, 3 * 16, 19 * 16, false }) --table.insert(floorDecor, { td0, td1, 4 * 16, 19 * 16, false }) -- Urns table.insert(floorDecor, { td0, td1, 6 * 16, 48, false, false }) table.insert(floorDecor, { td0, td1, 7 * 16, 48, false, false }) -- Urns --table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 48, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 48, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 48, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 48, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 48, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 5 * 16, 48, true, false }) -- Racks --table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 11 * 16, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 11 * 16, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 11 * 16, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 11 * 16, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 11 * 16, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 5 * 16, 11 * 16, true, false }) --table.insert(blockingFloorDecor, { td0, td1, 6 * 16, 11 * 16, true, false }) -- Headstones table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 17 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 17 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 17 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 17 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 17 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 18 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 18 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 18 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 18 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 18 * 16, true, false }) -- Altars table.insert(blockingFloorDecor, { td0, td1, 0 * 16, 20 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 1 * 16, 20 * 16, true, false }) table.insert(blockingFloorDecor, { td0, td1, 2 * 16, 20 * 16, true, false }) -- Statues --table.insert(blockingFloorDecor, { td0, td1, 3 * 16, 20 * 16, true }) --table.insert(blockingFloorDecor, { td0, td1, 4 * 16, 20 * 16, true }) lightDecor.candle0 = { td0, td1, 0, 8 * 16, false, true } lightDecor.candle1 = { td0, td1, 16, 8 * 16, false, true } lightDecor.candle2 = { td0, td1, 32, 8 * 16, true, true } end local function load_special_tiles() tt = add_texture(map, "Objects/Tile.png") special.level_exit = { tt, -1, 16, 16, false, true, true } end local function repack(data) return { textureIndex0 = data[1], textureIndex1 = data[2] or -1, tileClipX = data[3], tileClipY = data[4], isCollider = data[5] or false, isLightSource = data[6] or false, isLevelExit = data[7] or false, isLethal = data[8] or false, lockType = data[9] or 0 } end local function room_tile_available(room, rx, ry) return not room.chests[rx][ry] and not room.traps[rx][ry] and not room.walls[rx][ry] and not room.doors[rx][ry] and not room.monsters[rx][ry] and not room.decor[rx][ry] and (room.tiles[rx][ry] and not room.tiles[rx][ry][5] and not room.tiles[rx][ry][7] and not room.tiles[rx][ry][8]) end local function add_random_decor_to_room(room, blockingDecor) local decor_count = random(8) if blockingDecor then decor_count = random(4) end for i=1,decor_count do local success = false while not success do x = random(11) + 1 y = random(8) + 1 if room_tile_available(room, x, y) then room.decor[x][y] = floorDecor[random(#floorDecor)] success = true end end end if blockingDecor then decor_count = random(4) for i=1,decor_count do local success = false while not success do x = random(11) + 1 y = random(8) + 1 if room_tile_available(room, x, y) then room.decor[x][y] = blockingFloorDecor[random(#blockingFloorDecor)] success = true end end end end if blockingDecor then if random(2) == 1 and room_tile_available(room, 4, 3) then room.decor[4][3] = lightDecor.candle2 end if random(2) == 1 and room_tile_available(room, 11, 3) then room.decor[11][3] = lightDecor.candle2 end if random(2) == 1 and room_tile_available(room, 4, 9) then room.decor[4][9] = lightDecor.candle2 end if random(2) == 1 and room_tile_available(room, 11, 9) then room.decor[11][9] = lightDecor.candle2 end end end local function add_tiles_to_room (room, singletile) for i=0,15 do for j=0,11 do if (i >= 1 and i <= 14 and j >= 1 and j <= 10) then if (i == 1 and j == 1) then room.tiles[i][j] = singletile and floor.single or floor.topleft elseif (i == 14 and j == 1) then room.tiles[i][j] = singletile and floor.single or floor.topright elseif (i == 1 and j == 10) then room.tiles[i][j] = singletile and floor.single or floor.bottomleft elseif (i == 14 and j == 10) then room.tiles[i][j] = singletile and floor.single or floor.bottomright elseif (i == 1) then room.tiles[i][j] = singletile and floor.single or floor.left elseif (i == 14) then room.tiles[i][j] = singletile and floor.single or floor.right elseif (j == 1) then room.tiles[i][j] = singletile and floor.single or floor.top elseif (j == 10) then room.tiles[i][j] = singletile and floor.single or floor.bottom else room.tiles[i][j] = singletile and floor.single or floor.center end else room.tiles[i][j] = floor.single end end end end local function add_walls_to_room (room) for i=0,15 do for j=0,11 do if (i == 0 and j == 0) then room.walls[i][j] = wall.topleft elseif (i == 15 and j == 0) then room.walls[i][j] = wall.topright elseif (i == 0 and j == 11) then room.walls[i][j] = wall.bottomleft elseif (i == 15 and j == 11) then room.walls[i][j] = wall.bottomright elseif (i == 0 or i == 15) then room.walls[i][j] = wall.vertical elseif (j == 0 or j == 11) then room.walls[i][j] = wall.horizontal end end end end local function build_vert_center_coridoor(room, offset) for i=0,4 do room.walls[6][offset+i] = wall.vertical room.tiles[7][offset+i] = floor.center room.tiles[8][offset+i] = floor.center room.walls[7][offset+i] = nil room.walls[8][offset+i] = nil room.walls[9][offset+i] = wall.vertical end if random(2) == 1 then room.decor[6][offset+2] = lightDecor.candle1 end if random(2) == 1 then room.decor[6][offset+2] = lightDecor.candle1 end end local function build_horiz_center_coridoor(room, offset) for i=0,6 do room.walls[offset+i][4] = wall.horizontal room.tiles[offset+i][5] = floor.center room.tiles[offset+i][6] = floor.center room.walls[offset+i][5] = nil room.walls[offset+i][6] = nil room.walls[offset+i][7] = wall.horizontal end if random(2) == 1 then room.decor[offset+3][4] = lightDecor.candle1 end if random(2) == 1 then room.decor[offset+3][7] = lightDecor.candle1 end end local function build_center_corner_walls(room, exits) if exits.down then if exits.left then room.walls[6][7] = wall.topright end if exits.right then room.walls[9][7] = wall.topleft end else if not exits.left then room.walls[6][7] = wall.bottomleft end if not exits.right then room.walls[9][7] = wall.bottomright end end if exits.up then if exits.left then room.walls[6][4] = wall.bottomright end if exits.right then room.walls[9][4] = wall.bottomleft end else if not exits.left then room.walls[6][4] = wall.topleft end if not exits.right then room.walls[9][4] = wall.topright end end end local function add_exits_to_room(room) for _,direction in ipairs(room.exits) do if direction == UP then room.walls[6][0] = wall.bottomright room.tiles[7][0] = floor.singleleft room.tiles[8][0] = floor.singleright room.walls[7][0] = nil room.walls[8][0] = nil room.walls[9][0] = wall.bottomleft elseif direction == LEFT then room.walls[0][4] = wall.bottomright room.tiles[0][5] = floor.singletop room.tiles[0][6] = floor.singlebottom room.walls[0][5] = nil room.walls[0][6] = nil room.walls[0][7] = wall.topright elseif direction == RIGHT then room.walls[15][4] = wall.bottomleft room.tiles[15][5] = floor.singletop room.tiles[15][6] = floor.singlebottom room.walls[15][5] = nil room.walls[15][6] = nil room.walls[15][7] = wall.topleft elseif direction == DOWN then room.walls[6][11] = wall.topright room.tiles[7][11] = floor.singleleft room.tiles[8][11] = floor.singleright room.walls[7][11] = nil room.walls[8][11] = nil room.walls[9][11] = wall.topleft end end end local function build_coridoor_room(room) local exits = { up = false, down = false, left = false, right = false } for _,exit in ipairs(room.exits) do if UP == exit then exits.up = true elseif DOWN == exit then exits.down = true elseif LEFT == exit then exits.left = true elseif RIGHT == exit then exits.right = true end end -- Fill the center room.tiles[7][5] = floor.center room.tiles[7][6] = floor.center room.tiles[8][5] = floor.center room.tiles[8][6] = floor.center room.walls[6][5] = wall.vertical room.walls[6][6] = wall.vertical room.walls[7][4] = wall.horizontal room.walls[7][7] = wall.horizontal room.walls[8][4] = wall.horizontal room.walls[8][7] = wall.horizontal room.walls[9][5] = wall.vertical room.walls[9][6] = wall.vertical -- Build the coridoors if exits.down then build_vert_center_coridoor(room, 7) end if exits.up then build_vert_center_coridoor(room, 0) end if exits.left then build_horiz_center_coridoor(room, 0) end if exits.right then build_horiz_center_coridoor(room, 9) end build_center_corner_walls(room, exits) end local function add_level_exit(room) local success = false while not success do x = random(14) y = random(10) if room_tile_available(room, x, y) then success = true room.tiles[x][y] = special.level_exit end end end local function build_shop_room(room, roomx, roomy) add_tiles_to_room(room, false) add_walls_to_room(room) add_exits_to_room(room) layoutparser.add_shop_layout(room, roomx, roomy) return room end local function build_locked_room(room, roomx, roomy) add_tiles_to_room(room, false) add_walls_to_room(room) add_exits_to_room(room) layoutparser.add_locked_room_layout(room, roomx, roomy) return room end local function build_normal_room(room) local crumbling = (CURRENT_LEVEL > 3 or QUICK_MODE) and random(8) == 1 local pitsAdded = false; local interiorWallsAdded = false add_tiles_to_room(room, crumbling) add_walls_to_room(room) add_exits_to_room(room) if not crumbling then pitsAdded = layoutparser.add_pits_to_room(room) end if not pitsAdded and (not crumbling or CURRENT_LEVEL > 3) then interiorWallsAdded = layoutparser.add_walls_to_room(room) end add_random_decor_to_room(room, not interiorWallsAdded) if room.goal then add_level_exit(room) end if crumbling then room.modifier.type = "CRUMBLING" room.modifier.arg = "" elseif (CURRENT_LEVEL > 3 or QUICK_MODE) and random(8) == 1 then room.modifier.type = "FIRE" room.modifier.arg = "" elseif ((not pitsAdded and not crumbling and (CURRENT_LEVEL > 1 or QUICK_MODE)) or CURRENT_LEVEL > 3) and random(8) == 1 then directions = { "LEFT", "RIGHT", "UP", "DOWN" } room.modifier.type = "WINDY" room.modifier.arg = directions[random(#directions)] end return room end local module = {} function module.add_exit(room, direction) if direction > 4 then return end table.insert(room.exits, direction) end function module.add_full_lighting(room) room.decor[4][3] = lightDecor.candle2 room.decor[11][3] = lightDecor.candle2 room.decor[4][9] = lightDecor.candle2 room.decor[11][9] = lightDecor.candle2 end function module.is_tile_avilable(room, rx, ry) return room_tile_available(room, rx, ry); end function module.create_empty_room() room = { exits = {}, active = false, goal = false, path_dir = 0, type = "room", tiles = {}, walls = {}, doors = {}, decor = {}, modifier = { type = nil, arg = nil }, monsters = {}, chests = {}, traps = {} } for i=0,15 do room.tiles[i] = {} room.walls[i] = {} room.doors[i] = {} room.decor[i] = {} room.monsters[i] = {} room.traps[i] = {} room.chests[i] = {} for j=0,11 do room.tiles[i][j] = nil room.walls[i][j] = nil room.doors[i][j] = nil room.decor[i][j] = nil room.monsters[i][j] = nil room.traps[i][j] = nil room.chests[i][j] = nil end end return room end function module.build_room(room, roomx, roomy) if room.type == "coridoor" then build_coridoor_room(room) elseif room.type == "shop" then build_shop_room(room, roomx, roomy) elseif room.type == "locked" then build_locked_room(room, roomx, roomy) else build_normal_room(room) --build_locked_room(room, roomx, roomy) end end function module.load_room(map, room) for i=0, 15 do for j=0, 11 do if room.tiles[i][j] then add_tile(map, i, j, repack(room.tiles[i][j])) end if room.walls[i][j] then add_wall(map, i, j, repack(room.walls[i][j])) end if room.doors[i][j] then add_door(map, i, j, repack(room.doors[i][j])) end if room.decor[i][j] then add_decoration(map, i, j, repack(room.decor[i][j])) end end end if room.modifier.type then set_modifier(map, room.modifier.type, room.modifier.arg) end end function module.load_textures(map) t_floor = add_texture(map, "Objects/Floor.png") t_wall = add_texture(map, "Objects/Wall.png") local seed = get_random_seed(CURRENT_LEVEL); info("Map room random seed: " .. seed) map_randomseed(seed) local xo = (random(3) - 1) * 112 local yo = (random(8)) * 48 layoutparser.load_textures(map, xo, yo) floor.center = { t_floor, -1, xo + 16, yo + 16, false } floor.top = { t_floor, -1, xo + 16, yo + 0, false } floor.bottom = { t_floor, -1, xo + 16, yo + 32, false } floor.left = { t_floor, -1, xo + 0, yo + 16, false } floor.right = { t_floor, -1, xo + 32, yo + 16, false } floor.topleft = { t_floor, -1, xo + 0, yo + 0, false } floor.topright = { t_floor, -1, xo + 32, yo + 0, false } floor.bottomleft = { t_floor, -1, xo + 0, yo + 32, false } floor.bottomright = { t_floor, -1, xo + 32, yo + 32, false } floor.singletop = { t_floor, -1, xo + 48, yo + 0, false } floor.singlebottom = { t_floor, -1, xo + 48, yo + 32, false } floor.singleleft = { t_floor, -1, xo + 64, yo + 16, false } floor.singleright = { t_floor, -1, xo + 96, yo + 16, false } floor.single = { t_floor, -1, xo + 80, yo + 0, false } wall.topleft = { t_wall, -1, xo + 0, yo + 0, true } wall.topright = { t_wall, -1, xo + 32, yo + 0, true } wall.bottomleft = { t_wall, -1, xo + 0, yo + 32, true } wall.bottomright = { t_wall, -1, xo + 32, yo + 32, true } wall.vertical = { t_wall, -1, xo + 0, yo + 16, true } wall.horizontal = { t_wall, -1, xo + 16, yo + 0, true } load_decor_textures() load_special_tiles() end return module