diff --git a/data/mapgen.lua b/data/mapgen.lua index 27ba9b2..57389c9 100644 --- a/data/mapgen.lua +++ b/data/mapgen.lua @@ -6,13 +6,13 @@ local random = math.random local randomseed = math.randomseed -- CONSTANTS -UP = 1 -LEFT = 2 -RIGHT = 3 -DOWN = 4 +local UP = 1 +local LEFT = 2 +local RIGHT = 3 +local DOWN = 4 -- BEGIN FUNCTIONS -function matrix_coverage (matrix) +local function matrix_coverage (matrix) local cov = 0 for i=1,10 do for j=1,10 do @@ -22,7 +22,7 @@ function matrix_coverage (matrix) return cov end -function reverse_direction(dir) +local function reverse_direction(dir) if dir == UP then return DOWN elseif dir == DOWN then return UP elseif dir == LEFT then return RIGHT @@ -30,7 +30,7 @@ function reverse_direction(dir) end end -function generate_path () +local function generate_path () local map_matrix = {} for i=1,10 do map_matrix[i] = {} @@ -43,16 +43,31 @@ function generate_path () local seed = time(); print("[**] Map generation seed: " .. seed) randomseed(seed) - local direction = 0; - local lastDirection = 0; - while matrix_coverage(map_matrix) < 10 do + local direction = 0 + local lastDirection = 0 + local coridoor_count = 0 + local coverage = 10 + + while matrix_coverage(map_matrix) < coverage do local direction = random(4) if lastDirection > 0 then - if random(24) <= 8 then direction = lastDirection end + if random(24) <= 6 then direction = lastDirection end + end + + while lastDirection == reverse_direction(direction) do + direction = random(4) end map_matrix[cx][cy].active = true + + if coridoor_count < coverage/3 then + if random(3) == 1 and (cx > 1 or cy > 1) then + map_matrix[cx][cy].type = "coridoor" + coridoor_count = coridoor_count + 1 + end + end + if direction == UP and cy > 1 then -- UP table.insert(map_matrix[cx][cy].exits, direction) map_matrix[cx][cy].path_dir = direction @@ -76,11 +91,27 @@ function generate_path () end lastDirection = direction end - map_matrix[cx][cy].active = true -- Last room - map_matrix[cx][cy].goal = true -- Last room + + -- Last room rules + map_matrix[cx][cy].active = true + map_matrix[cx][cy].goal = true + map_matrix[cx][cy].type = "room" return map_matrix; end + +local function print_matrix(matrix) + for i=1,10 do + for j=1,10 do + if not map_matrix[j][i].goal then + io.write(map_matrix[j][i].path_dir .. " ") + else + io.write("G ") + end + end + io.write("\n") + end +end -- END FUNCTIONS -- BEGIN SCRIPT @@ -89,25 +120,17 @@ load_textures(map) local map_matrix = generate_path() -- Print path [Debug] ---for i=1,10 do - --for j=1,10 do - --if not map_matrix[j][i].goal then - --io.write(map_matrix[j][i].path_dir .. " ") - --else - --io.write("G ") - --end - --end - --io.write("\n") ---end +-- print_matrix(map_matrix) for i=1,10 do for j=1,10 do - if map_matrix[i][j].active then + local room = map_matrix[i][j] + if room.active then set_current_room(map, i-1, j-1); - add_tiles_to_room(map); - add_walls_to_room(map); - for exit=1, #map_matrix[i][j].exits do - add_exit(map, map_matrix[i][j].exits[exit]); + if room.type == "room" then + build_square_room(map, room) + elseif room.type == "coridoor" then + build_coridoor_room(map, room) end end end diff --git a/data/maproombuilder.lua b/data/maproombuilder.lua index bd2797d..0ec40f0 100644 --- a/data/maproombuilder.lua +++ b/data/maproombuilder.lua @@ -1,134 +1,239 @@ -- CONSTANTS -UP = 1 -LEFT = 2 -RIGHT = 3 -DOWN = 4 +local UP = 1 +local LEFT = 2 +local RIGHT = 3 +local DOWN = 4 -- Textures -local floorTexture = nil -local wallTexture = nil +local textures = { + floorTexture = nil, + wallTexture = nil +} -local floor_center -local floor_top -local floor_bottom -local floor_left -local floor_right -local floor_topleft -local floor_topright -local floor_bottomleft -local floor_bottomright +local floor = { + center = nil, + top = nil, + bottom = nil, + left = nil, + right = nil, + topleft = nil, + topright = nil, + bottomleft = nil, + bottomright = nil, +} -local wall_topleft -local wall_topright -local wall_bottomleft -local wall_bottomright -local wall_vertical -local wall_horizontal +local wall = { + topleft = nil, + topright = nil, + bottomleft = nil, + bottomright = nil, + vertical = nil, + horizontal = nil +} function load_textures(map) - floorTexture = add_texture(map, "assets/Objects/Floor.png") - wallTexture = add_texture(map, "assets/Objects/Wall.png") + textures.floorTexture = add_texture(map, "assets/Objects/Floor.png") + textures.wallTexture = add_texture(map, "assets/Objects/Wall.png") local xo = 0 local yo = 48 - floor_center = { floorTexture, xo + 16, yo + 16, false } - floor_top = { floorTexture, xo + 16, yo + 0, false } - floor_bottom = { floorTexture, xo + 16, yo + 32, false } - floor_left = { floorTexture, xo + 0, yo + 16, false } - floor_right = { floorTexture, xo + 32, yo + 16, false } - floor_topleft = { floorTexture, xo + 0, yo + 0, false } - floor_topright = { floorTexture, xo + 32, yo + 0, false } - floor_bottomleft = { floorTexture, xo + 0, yo + 32, false } - floor_bottomright = { floorTexture, xo + 32, yo + 32, false } + floor.center = { textures.floorTexture, xo + 16, yo + 16, false } + floor.top = { textures.floorTexture, xo + 16, yo + 0, false } + floor.bottom = { textures.floorTexture, xo + 16, yo + 32, false } + floor.left = { textures.floorTexture, xo + 0, yo + 16, false } + floor.right = { textures.floorTexture, xo + 32, yo + 16, false } + floor.topleft = { textures.floorTexture, xo + 0, yo + 0, false } + floor.topright = { textures.floorTexture, xo + 32, yo + 0, false } + floor.bottomleft = { textures.floorTexture, xo + 0, yo + 32, false } + floor.bottomright = { textures.floorTexture, xo + 32, yo + 32, false } - wall_topleft = { wallTexture, xo + 0, yo + 0, true } - wall_topright = { wallTexture, xo + 32, yo + 0, true } - wall_bottomleft = { wallTexture, xo + 0, yo + 32, true } - wall_bottomright = { wallTexture, xo + 32, yo + 32, true } - wall_vertical = { wallTexture, xo + 0, yo + 16, true } - wall_horizontal = { wallTexture, xo + 16, yo + 0, true } + wall.topleft = { textures.wallTexture, xo + 0, yo + 0, true } + wall.topright = { textures.wallTexture, xo + 32, yo + 0, true } + wall.bottomleft = { textures.wallTexture, xo + 0, yo + 32, true } + wall.bottomright = { textures.wallTexture, xo + 32, yo + 32, true } + wall.vertical = { textures.wallTexture, xo + 0, yo + 16, true } + wall.horizontal = { textures.wallTexture, xo + 16, yo + 0, true } end function create_room () - local room = {} - room.exits = {} - room.active = false - room.goal = false - room.path_dir = 0 - return room; + return { + exits = {}, + active = false, + goal = false, + path_dir = 0, + type = "room" + } end -function add_tiles_to_room (map) +local function add_tiles_to_room (map) 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 - add_tile(map, i, j, unpack(floor_topleft)) + add_tile(map, i, j, unpack(floor.topleft)) elseif (i == 14 and j == 1) then - add_tile(map, i, j, unpack(floor_topright)) + add_tile(map, i, j, unpack(floor.topright)) elseif (i == 1 and j == 10) then - add_tile(map, i, j, unpack(floor_bottomleft)) + add_tile(map, i, j, unpack(floor.bottomleft)) elseif (i == 14 and j == 10) then - add_tile(map, i, j, unpack(floor_bottomright)) + add_tile(map, i, j, unpack(floor.bottomright)) elseif (i == 1) then - add_tile(map, i, j, unpack(floor_left)) + add_tile(map, i, j, unpack(floor.left)) elseif (i == 14) then - add_tile(map, i, j, unpack(floor_right)) + add_tile(map, i, j, unpack(floor.right)) elseif (j == 1) then - add_tile(map, i, j, unpack(floor_top)) + add_tile(map, i, j, unpack(floor.top)) elseif (j == 10) then - add_tile(map, i, j, unpack(floor_bottom)) + add_tile(map, i, j, unpack(floor.bottom)) else - add_tile(map, i, j, unpack(floor_center)) + add_tile(map, i, j, unpack(floor.center)) end end end end end -function add_walls_to_room (map) +local function add_walls_to_room (map) for i=0,15 do for j=0,11 do if (i == 0 and j == 0) then - add_tile(map, i, j, unpack(wall_topleft)) + add_tile(map, i, j, unpack(wall.topleft)) elseif (i == 15 and j == 0) then - add_tile(map, i, j, unpack(wall_topright)) + add_tile(map, i, j, unpack(wall.topright)) elseif (i == 0 and j == 11) then - add_tile(map, i, j, unpack(wall_bottomleft)) + add_tile(map, i, j, unpack(wall.bottomleft)) elseif (i == 15 and j == 11) then - add_tile(map, i, j, unpack(wall_bottomright)) + add_tile(map, i, j, unpack(wall.bottomright)) elseif (i == 0 or i == 15) then - add_tile(map, i, j, unpack(wall_vertical)) + add_tile(map, i, j, unpack(wall.vertical)) elseif (j == 0 or j == 11) then - add_tile(map, i, j, unpack(wall_horizontal)) + add_tile(map, i, j, unpack(wall.horizontal)) end end end end -function add_exit(map, direction) +local function add_exit(map, direction) if direction > 4 then return end if direction == UP then - add_tile(map, 6, 0, unpack(wall_bottomright)) - add_tile(map, 7, 0, unpack(floor_center)) - add_tile(map, 8, 0, unpack(floor_center)) - add_tile(map, 9, 0, unpack(wall_bottomleft)) + add_tile(map, 6, 0, unpack(wall.bottomright)) + add_tile(map, 7, 0, unpack(floor.center)) + add_tile(map, 8, 0, unpack(floor.center)) + add_tile(map, 9, 0, unpack(wall.bottomleft)) elseif direction == LEFT then - add_tile(map, 0, 4, unpack(wall_bottomright)) - add_tile(map, 0, 5, unpack(floor_center)) - add_tile(map, 0, 6, unpack(floor_center)) - add_tile(map, 0, 7, unpack(wall_topright)) + add_tile(map, 0, 4, unpack(wall.bottomright)) + add_tile(map, 0, 5, unpack(floor.center)) + add_tile(map, 0, 6, unpack(floor.center)) + add_tile(map, 0, 7, unpack(wall.topright)) elseif direction == RIGHT then - add_tile(map, 15, 4, unpack(wall_bottomleft)) - add_tile(map, 15, 5, unpack(floor_center)) - add_tile(map, 15, 6, unpack(floor_center)) - add_tile(map, 15, 7, unpack(wall_topleft)) + add_tile(map, 15, 4, unpack(wall.bottomleft)) + add_tile(map, 15, 5, unpack(floor.center)) + add_tile(map, 15, 6, unpack(floor.center)) + add_tile(map, 15, 7, unpack(wall.topleft)) elseif direction == DOWN then - add_tile(map, 6, 11, unpack(wall_topright)) - add_tile(map, 7, 11, unpack(floor_center)) - add_tile(map, 8, 11, unpack(floor_center)) - add_tile(map, 9, 11, unpack(wall_topleft)) + add_tile(map, 6, 11, unpack(wall.topright)) + add_tile(map, 7, 11, unpack(floor.center)) + add_tile(map, 8, 11, unpack(floor.center)) + add_tile(map, 9, 11, unpack(wall.topleft)) end end + +function build_square_room(map, room) + add_tiles_to_room(map); + add_walls_to_room(map); + for exit=1, #room.exits do + add_exit(map, room.exits[exit]); + end +end + +local function build_vert_center_coridoor(map, offset) + for j=0,4 do + add_tile(map, 6, offset+j, unpack(wall.vertical)); + add_tile(map, 7, offset+j, unpack(floor.center)); + add_tile(map, 8, offset+j, unpack(floor.center)); + add_tile(map, 9, offset+j, unpack(wall.vertical)); + end +end + +local function build_horiz_center_coridoor(map, offset) + for i=0,6 do + add_tile(map, offset+i, 4, unpack(wall.horizontal)); + add_tile(map, offset+i, 5, unpack(floor.center)); + add_tile(map, offset+i, 6, unpack(floor.center)); + add_tile(map, offset+i, 7, unpack(wall.horizontal)); + end +end + +local function build_center_corner_walls(map, exits) + if exits.down then + if exits.left then + add_tile(map, 6, 7, unpack(wall.topright)) + end + if exits.right then + add_tile(map, 9, 7, unpack(wall.topleft)) + end + else + if not exits.left then + add_tile(map, 6, 7, unpack(wall.bottomleft)) + end + if not exits.right then + add_tile(map, 9, 7, unpack(wall.bottomright)) + end + end + if exits.up then + if exits.left then + add_tile(map, 6, 4, unpack(wall.bottomright)) + end + if exits.right then + add_tile(map, 9, 4, unpack(wall.bottomleft)) + end + else + if not exits.left then + add_tile(map, 6, 4, unpack(wall.topleft)) + end + if not exits.right then + add_tile(map, 9, 4, unpack(wall.topright)) + end + end +end + +function build_coridoor_room(map, 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 + add_tile(map, 6, 5, unpack(wall.vertical)) + add_tile(map, 6, 6, unpack(wall.vertical)) + add_tile(map, 7, 4, unpack(wall.horizontal)) + add_tile(map, 7, 5, unpack(floor.center)) + add_tile(map, 7, 6, unpack(floor.center)) + add_tile(map, 7, 7, unpack(wall.horizontal)) + add_tile(map, 8, 4, unpack(wall.horizontal)) + add_tile(map, 8, 5, unpack(floor.center)) + add_tile(map, 8, 6, unpack(floor.center)) + add_tile(map, 8, 7, unpack(wall.horizontal)) + add_tile(map, 9, 5, unpack(wall.vertical)) + add_tile(map, 9, 6, unpack(wall.vertical)) + + -- Build the coridoors + if exits.down then build_vert_center_coridoor(map, 7) end + if exits.up then build_vert_center_coridoor(map, 0) end + if exits.left then build_horiz_center_coridoor(map, 0) end + if exits.right then build_horiz_center_coridoor(map, 9) end + + build_center_corner_walls(map, exits) +end diff --git a/linkedlist/linkedlist.c b/linkedlist/linkedlist.c index c8a7450..52b2bc8 100644 --- a/linkedlist/linkedlist.c +++ b/linkedlist/linkedlist.c @@ -35,6 +35,11 @@ static void copy_data(void *dest, void *src, unsigned int size) *(char*)(dest + i) = *(char*)(src + i); } +/** + * Warning! This can get a bit wonky if you append/push a complex struct that + * contains pointers. The pointers will be copied and not duplicated in that + * case. Be careful. + */ void linkedlist_push(LinkedList **head, void *value, unsigned int size) { @@ -59,6 +64,11 @@ void* linkedlist_pop(LinkedList **head) return data; } +/** + * Warning! This can get a bit wonky if you append/push a complex struct that + * contains pointers. The pointers will be copied and not duplicated in that + * case. Be careful. + */ void linkedlist_append(LinkedList **head, void *value, unsigned int size) { if (*head == NULL) { diff --git a/src/map.c b/src/map.c index cecccb4..773b494 100644 --- a/src/map.c +++ b/src/map.c @@ -50,6 +50,14 @@ int map_add_texture(Map *map, const char *path, SDL_Renderer *renderer) { Texture *t = texture_create(path, renderer); linkedlist_append(&map->textures, t, sizeof(*t)); + + /* Freeing the texture preserves the underlying SDL_Texture* which + * isn't duplicated when it's being added to the list. + * texture_destroy() would destroy that too and break rendering. + * Unstable solution. Might cause problems if Texture is ever extended + * with more data. + */ + free(t); return linkedlist_size(map->textures) - 1; } @@ -149,7 +157,7 @@ void map_destroy(Map *map) } } while (map->textures != NULL) { - SDL_DestroyTexture(linkedlist_poplast(&map->textures)); + texture_destroy(linkedlist_poplast(&map->textures)); } free(map); } diff --git a/src/roommatrix.c b/src/roommatrix.c index 13dd2a1..8777acd 100644 --- a/src/roommatrix.c +++ b/src/roommatrix.c @@ -14,11 +14,15 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m) int i, j; Room *r; + roommatrix_reset(rm); + rm->roomPos = m->currentRoom; r = m->rooms[rm->roomPos.x][rm->roomPos.y]; for (i = 0; i < MAP_ROOM_WIDTH; ++i) { for (j = 0; j < MAP_ROOM_HEIGHT; ++j) { + if (!r->tiles[i][j]) + continue; rm->spaces[i][j].occupied = r->tiles[i][j]->collider; } }