Squelched a bug, fixed a memory leak and wrote a lot of ugly lua.

The lua is map-gen code. It's allowed to be ugly. That is why map-gen
code is in lua. Because it's quick to write and not as crucial if it
gets ugly.
This commit is contained in:
Linus Probert 2017-12-07 23:58:29 +01:00
parent 31ca087a1e
commit 577165a0f6
5 changed files with 257 additions and 107 deletions

View File

@ -6,13 +6,13 @@ local random = math.random
local randomseed = math.randomseed local randomseed = math.randomseed
-- CONSTANTS -- CONSTANTS
UP = 1 local UP = 1
LEFT = 2 local LEFT = 2
RIGHT = 3 local RIGHT = 3
DOWN = 4 local DOWN = 4
-- BEGIN FUNCTIONS -- BEGIN FUNCTIONS
function matrix_coverage (matrix) local function matrix_coverage (matrix)
local cov = 0 local cov = 0
for i=1,10 do for i=1,10 do
for j=1,10 do for j=1,10 do
@ -22,7 +22,7 @@ function matrix_coverage (matrix)
return cov return cov
end end
function reverse_direction(dir) local function reverse_direction(dir)
if dir == UP then return DOWN if dir == UP then return DOWN
elseif dir == DOWN then return UP elseif dir == DOWN then return UP
elseif dir == LEFT then return RIGHT elseif dir == LEFT then return RIGHT
@ -30,7 +30,7 @@ function reverse_direction(dir)
end end
end end
function generate_path () local function generate_path ()
local map_matrix = {} local map_matrix = {}
for i=1,10 do for i=1,10 do
map_matrix[i] = {} map_matrix[i] = {}
@ -43,16 +43,31 @@ function generate_path ()
local seed = time(); local seed = time();
print("[**] Map generation seed: " .. seed) print("[**] Map generation seed: " .. seed)
randomseed(seed) randomseed(seed)
local direction = 0; local direction = 0
local lastDirection = 0; local lastDirection = 0
while matrix_coverage(map_matrix) < 10 do local coridoor_count = 0
local coverage = 10
while matrix_coverage(map_matrix) < coverage do
local direction = random(4) local direction = random(4)
if lastDirection > 0 then 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 end
map_matrix[cx][cy].active = true 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 if direction == UP and cy > 1 then -- UP
table.insert(map_matrix[cx][cy].exits, direction) table.insert(map_matrix[cx][cy].exits, direction)
map_matrix[cx][cy].path_dir = direction map_matrix[cx][cy].path_dir = direction
@ -76,11 +91,27 @@ function generate_path ()
end end
lastDirection = direction lastDirection = direction
end 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; return map_matrix;
end 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 -- END FUNCTIONS
-- BEGIN SCRIPT -- BEGIN SCRIPT
@ -89,25 +120,17 @@ load_textures(map)
local map_matrix = generate_path() local map_matrix = generate_path()
-- Print path [Debug] -- Print path [Debug]
--for i=1,10 do -- print_matrix(map_matrix)
--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
for i=1,10 do for i=1,10 do
for j=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); set_current_room(map, i-1, j-1);
add_tiles_to_room(map); if room.type == "room" then
add_walls_to_room(map); build_square_room(map, room)
for exit=1, #map_matrix[i][j].exits do elseif room.type == "coridoor" then
add_exit(map, map_matrix[i][j].exits[exit]); build_coridoor_room(map, room)
end end
end end
end end

View File

@ -1,134 +1,239 @@
-- CONSTANTS -- CONSTANTS
UP = 1 local UP = 1
LEFT = 2 local LEFT = 2
RIGHT = 3 local RIGHT = 3
DOWN = 4 local DOWN = 4
-- Textures -- Textures
local floorTexture = nil local textures = {
local wallTexture = nil floorTexture = nil,
wallTexture = nil
}
local floor_center local floor = {
local floor_top center = nil,
local floor_bottom top = nil,
local floor_left bottom = nil,
local floor_right left = nil,
local floor_topleft right = nil,
local floor_topright topleft = nil,
local floor_bottomleft topright = nil,
local floor_bottomright bottomleft = nil,
bottomright = nil,
}
local wall_topleft local wall = {
local wall_topright topleft = nil,
local wall_bottomleft topright = nil,
local wall_bottomright bottomleft = nil,
local wall_vertical bottomright = nil,
local wall_horizontal vertical = nil,
horizontal = nil
}
function load_textures(map) function load_textures(map)
floorTexture = add_texture(map, "assets/Objects/Floor.png") textures.floorTexture = add_texture(map, "assets/Objects/Floor.png")
wallTexture = add_texture(map, "assets/Objects/Wall.png") textures.wallTexture = add_texture(map, "assets/Objects/Wall.png")
local xo = 0 local xo = 0
local yo = 48 local yo = 48
floor_center = { floorTexture, xo + 16, yo + 16, false } floor.center = { textures.floorTexture, xo + 16, yo + 16, false }
floor_top = { floorTexture, xo + 16, yo + 0, false } floor.top = { textures.floorTexture, xo + 16, yo + 0, false }
floor_bottom = { floorTexture, xo + 16, yo + 32, false } floor.bottom = { textures.floorTexture, xo + 16, yo + 32, false }
floor_left = { floorTexture, xo + 0, yo + 16, false } floor.left = { textures.floorTexture, xo + 0, yo + 16, false }
floor_right = { floorTexture, xo + 32, yo + 16, false } floor.right = { textures.floorTexture, xo + 32, yo + 16, false }
floor_topleft = { floorTexture, xo + 0, yo + 0, false } floor.topleft = { textures.floorTexture, xo + 0, yo + 0, false }
floor_topright = { floorTexture, xo + 32, yo + 0, false } floor.topright = { textures.floorTexture, xo + 32, yo + 0, false }
floor_bottomleft = { floorTexture, xo + 0, yo + 32, false } floor.bottomleft = { textures.floorTexture, xo + 0, yo + 32, false }
floor_bottomright = { floorTexture, xo + 32, yo + 32, false } floor.bottomright = { textures.floorTexture, xo + 32, yo + 32, false }
wall_topleft = { wallTexture, xo + 0, yo + 0, true } wall.topleft = { textures.wallTexture, xo + 0, yo + 0, true }
wall_topright = { wallTexture, xo + 32, yo + 0, true } wall.topright = { textures.wallTexture, xo + 32, yo + 0, true }
wall_bottomleft = { wallTexture, xo + 0, yo + 32, true } wall.bottomleft = { textures.wallTexture, xo + 0, yo + 32, true }
wall_bottomright = { wallTexture, xo + 32, yo + 32, true } wall.bottomright = { textures.wallTexture, xo + 32, yo + 32, true }
wall_vertical = { wallTexture, xo + 0, yo + 16, true } wall.vertical = { textures.wallTexture, xo + 0, yo + 16, true }
wall_horizontal = { wallTexture, xo + 16, yo + 0, true } wall.horizontal = { textures.wallTexture, xo + 16, yo + 0, true }
end end
function create_room () function create_room ()
local room = {} return {
room.exits = {} exits = {},
room.active = false active = false,
room.goal = false goal = false,
room.path_dir = 0 path_dir = 0,
return room; type = "room"
}
end end
function add_tiles_to_room (map) local function add_tiles_to_room (map)
for i=0,15 do for i=0,15 do
for j=0,11 do for j=0,11 do
if (i >= 1 and i <= 14 and j >= 1 and j <= 10) then if (i >= 1 and i <= 14 and j >= 1 and j <= 10) then
if (i == 1 and j == 1) 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 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 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 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 elseif (i == 1) then
add_tile(map, i, j, unpack(floor_left)) add_tile(map, i, j, unpack(floor.left))
elseif (i == 14) then elseif (i == 14) then
add_tile(map, i, j, unpack(floor_right)) add_tile(map, i, j, unpack(floor.right))
elseif (j == 1) then elseif (j == 1) then
add_tile(map, i, j, unpack(floor_top)) add_tile(map, i, j, unpack(floor.top))
elseif (j == 10) then elseif (j == 10) then
add_tile(map, i, j, unpack(floor_bottom)) add_tile(map, i, j, unpack(floor.bottom))
else else
add_tile(map, i, j, unpack(floor_center)) add_tile(map, i, j, unpack(floor.center))
end end
end end
end end
end end
end end
function add_walls_to_room (map) local function add_walls_to_room (map)
for i=0,15 do for i=0,15 do
for j=0,11 do for j=0,11 do
if (i == 0 and j == 0) then 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 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 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 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 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 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
end end
end end
function add_exit(map, direction) local function add_exit(map, direction)
if direction > 4 then return end if direction > 4 then return end
if direction == UP then if direction == UP then
add_tile(map, 6, 0, unpack(wall_bottomright)) add_tile(map, 6, 0, unpack(wall.bottomright))
add_tile(map, 7, 0, unpack(floor_center)) add_tile(map, 7, 0, unpack(floor.center))
add_tile(map, 8, 0, unpack(floor_center)) add_tile(map, 8, 0, unpack(floor.center))
add_tile(map, 9, 0, unpack(wall_bottomleft)) add_tile(map, 9, 0, unpack(wall.bottomleft))
elseif direction == LEFT then elseif direction == LEFT then
add_tile(map, 0, 4, unpack(wall_bottomright)) add_tile(map, 0, 4, unpack(wall.bottomright))
add_tile(map, 0, 5, unpack(floor_center)) add_tile(map, 0, 5, unpack(floor.center))
add_tile(map, 0, 6, unpack(floor_center)) add_tile(map, 0, 6, unpack(floor.center))
add_tile(map, 0, 7, unpack(wall_topright)) add_tile(map, 0, 7, unpack(wall.topright))
elseif direction == RIGHT then elseif direction == RIGHT then
add_tile(map, 15, 4, unpack(wall_bottomleft)) add_tile(map, 15, 4, unpack(wall.bottomleft))
add_tile(map, 15, 5, unpack(floor_center)) add_tile(map, 15, 5, unpack(floor.center))
add_tile(map, 15, 6, unpack(floor_center)) add_tile(map, 15, 6, unpack(floor.center))
add_tile(map, 15, 7, unpack(wall_topleft)) add_tile(map, 15, 7, unpack(wall.topleft))
elseif direction == DOWN then elseif direction == DOWN then
add_tile(map, 6, 11, unpack(wall_topright)) add_tile(map, 6, 11, unpack(wall.topright))
add_tile(map, 7, 11, unpack(floor_center)) add_tile(map, 7, 11, unpack(floor.center))
add_tile(map, 8, 11, unpack(floor_center)) add_tile(map, 8, 11, unpack(floor.center))
add_tile(map, 9, 11, unpack(wall_topleft)) add_tile(map, 9, 11, unpack(wall.topleft))
end end
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

View File

@ -35,6 +35,11 @@ static void copy_data(void *dest, void *src, unsigned int size)
*(char*)(dest + i) = *(char*)(src + i); *(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) void linkedlist_push(LinkedList **head, void *value, unsigned int size)
{ {
@ -59,6 +64,11 @@ void* linkedlist_pop(LinkedList **head)
return data; 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) void linkedlist_append(LinkedList **head, void *value, unsigned int size)
{ {
if (*head == NULL) { if (*head == NULL) {

View File

@ -50,6 +50,14 @@ int map_add_texture(Map *map, const char *path, SDL_Renderer *renderer)
{ {
Texture *t = texture_create(path, renderer); Texture *t = texture_create(path, renderer);
linkedlist_append(&map->textures, t, sizeof(*t)); 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; return linkedlist_size(map->textures) - 1;
} }
@ -149,7 +157,7 @@ void map_destroy(Map *map)
} }
} }
while (map->textures != NULL) { while (map->textures != NULL) {
SDL_DestroyTexture(linkedlist_poplast(&map->textures)); texture_destroy(linkedlist_poplast(&map->textures));
} }
free(map); free(map);
} }

View File

@ -14,11 +14,15 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
int i, j; int i, j;
Room *r; Room *r;
roommatrix_reset(rm);
rm->roomPos = m->currentRoom; rm->roomPos = m->currentRoom;
r = m->rooms[rm->roomPos.x][rm->roomPos.y]; r = m->rooms[rm->roomPos.x][rm->roomPos.y];
for (i = 0; i < MAP_ROOM_WIDTH; ++i) { for (i = 0; i < MAP_ROOM_WIDTH; ++i) {
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) { for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
if (!r->tiles[i][j])
continue;
rm->spaces[i][j].occupied = r->tiles[i][j]->collider; rm->spaces[i][j].occupied = r->tiles[i][j]->collider;
} }
} }