From c486724efa49fdf2bae37f856d16250f9504000b Mon Sep 17 00:00:00 2001 From: Lohikar Date: Fri, 30 Jun 2017 05:11:11 -0500 Subject: [PATCH] Speed up asteroid generation a bunch (#2872) Shaves 10-20 seconds off of asteroid generation time, bringing it down to 20 seconds, as well as renames some macros so their function is more clear. --- code/modules/random_map/_random_map_setup.dm | 10 +- code/modules/random_map/automata/automata.dm | 105 +++++++--------- code/modules/random_map/automata/caves.dm | 34 +---- code/modules/random_map/noise/noise.dm | 126 +++++++++---------- code/modules/random_map/noise/ore.dm | 2 +- 5 files changed, 119 insertions(+), 158 deletions(-) diff --git a/code/modules/random_map/_random_map_setup.dm b/code/modules/random_map/_random_map_setup.dm index 8c4106ebdfc..d2bf20c68ac 100644 --- a/code/modules/random_map/_random_map_setup.dm +++ b/code/modules/random_map/_random_map_setup.dm @@ -21,9 +21,11 @@ #define ARTIFACT_TURF_CHAR 6 #define ARTIFACT_CHAR 7 -#define GET_MAP_CELL(X,Y) ((((Y) - 1) * limit_x) + (X)) -#define PREPARE_CELL(X,Y) \ - tmp_cell = GET_MAP_CELL(X,Y);\ - if (tmp_cell < 1 || tmp_cell > map.len) {\ +#define TRANSLATE_COORD(X,Y) ((((Y) - 1) * limit_x) + (X)) +#define TRANSLATE_AND_VERIFY_COORD(X,Y) TRANSLATE_AND_VERIFY_COORD_MLEN(X,Y,map.len) + +#define TRANSLATE_AND_VERIFY_COORD_MLEN(X,Y,LEN) \ + tmp_cell = TRANSLATE_COORD(X,Y);\ + if (tmp_cell < 1 || tmp_cell > LEN) {\ tmp_cell = null;\ } diff --git a/code/modules/random_map/automata/automata.dm b/code/modules/random_map/automata/automata.dm index a2a6320e409..48d919541d2 100644 --- a/code/modules/random_map/automata/automata.dm +++ b/code/modules/random_map/automata/automata.dm @@ -12,75 +12,60 @@ // Automata-specific procs and processing. /datum/random_map/automata/generate_map() - for(var/i=1;i<=iterations;i++) - iterate(i) + for(var/iter = 1 to iterations) + var/list/next_map[limit_x*limit_y] + var/count + var/is_not_border_left + var/is_not_border_right + var/ilim_u + var/ilim_d + var/bottom_lim = ((limit_y - 1) * limit_x) -/datum/random_map/automata/get_additional_spawns(var/value, var/turf/T) - return + if (!islist(map)) + set_map_size() -/datum/random_map/automata/proc/iterate(var/iteration) - var/list/next_map[limit_x*limit_y] - var/tmp_cell - var/current_cell - var/count - if (!islist(map)) - set_map_size() - for(var/x = 1, x <= limit_x, x++) - for(var/y = 1, y <= limit_y, y++) - PREPARE_CELL(x,y) - current_cell = tmp_cell - next_map[current_cell] = map[current_cell] + for (var/i in 1 to (limit_x * limit_y)) count = 0 - // Every attempt to place this in a proc or a list has resulted in - // the generator being totally bricked and useless. Fuck it. We're - // hardcoding this shit. Feel free to rewrite and PR a fix. ~ Z - PREPARE_CELL(x,y) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x+1,y+1) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x-1,y-1) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x+1,y-1) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x-1,y+1) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x-1,y) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x,y-1) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x+1,y) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ - PREPARE_CELL(x,y+1) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - count++ + is_not_border_left = i != 1 && ((i - 1) % limit_x) + is_not_border_right = i % limit_x + + if (CELL_ALIVE(map[i])) // Center row. + ++count + if (is_not_border_left && CELL_ALIVE(map[i - 1])) + ++count + if (is_not_border_right && CELL_ALIVE(map[i + 1])) + ++count + + if (i > limit_x) // top row + ilim_u = i - limit_x + if (CELL_ALIVE(map[ilim_u])) + ++count + if (is_not_border_left && CELL_ALIVE(map[ilim_u - 1])) + ++count + if (is_not_border_right && CELL_ALIVE(map[ilim_u + 1])) + ++count + + if (i <= bottom_lim) // bottom row + ilim_d = i + limit_x + if (CELL_ALIVE(map[ilim_d])) + ++count + if (is_not_border_left && CELL_ALIVE(map[ilim_d - 1])) + ++count + if (is_not_border_right && CELL_ALIVE(map[ilim_d + 1])) + ++count if(count >= cell_threshold) - REVIVE_CELL(current_cell, next_map) - else - KILL_CELL(current_cell, next_map) - - CHECK_TICK + REVIVE_CELL(i, next_map) + else // Nope. Can't be alive. Kill it. + KILL_CELL(i, next_map) - map = next_map + CHECK_TICK -/datum/random_map/automata/proc/revive_cell(var/target_cell, var/list/use_next_map, var/final_iter) - if(!use_next_map) - use_next_map = map - use_next_map[target_cell] = cell_live_value + map = next_map -/datum/random_map/automata/proc/kill_cell(var/target_cell, var/list/use_next_map, var/final_iter) - if(!use_next_map) - use_next_map = map - use_next_map[target_cell] = cell_dead_value +/datum/random_map/automata/get_additional_spawns(value, turf/T) + return #undef KILL_CELL #undef REVIVE_CELL diff --git a/code/modules/random_map/automata/caves.dm b/code/modules/random_map/automata/caves.dm index 3f93358f138..574ae85cf96 100644 --- a/code/modules/random_map/automata/caves.dm +++ b/code/modules/random_map/automata/caves.dm @@ -32,12 +32,9 @@ // Create ore turfs. /datum/random_map/automata/cave_system/cleanup() - var/tmp_cell - for (var/x = 1; x < limit_x; x++) - for (var/y = 1; y < limit_y; y++) - PREPARE_CELL(x, y) - if (tmp_cell && CELL_ALIVE(map[tmp_cell])) - ore_turfs += tmp_cell + for (var/i = 1 to (limit_x * limit_y)) + if (CELL_ALIVE(map[i])) + ore_turfs += i game_log("ASGEN", "Found [ore_turfs.len] ore turfs.") var/ore_count = round(map.len/20) @@ -68,8 +65,6 @@ if(!origin_z) origin_z = 1 var/tmp_cell - var/x - var/y var/new_path var/num_applied = 0 for (var/thing in block(locate(origin_x, origin_y, origin_z), locate(limit_x, limit_y, origin_z))) @@ -78,13 +73,7 @@ if (!T || (target_turf_type && !istype(T, target_turf_type))) continue - x = T.x - y = T.y - - PREPARE_CELL(x,y) - - if (!tmp_cell) - continue + tmp_cell = TRANSLATE_COORD(T.x, T.y) switch (map[tmp_cell]) if(DOOR_CHAR) @@ -119,7 +108,6 @@ target_turf_type = /turf/unsimulated/chasm_mask mineral_sparse = /turf/unsimulated/mask mineral_rich = /turf/unsimulated/mask - cell_threshold = 5 /datum/random_map/automata/cave_system/chasms/apply_to_map() if(!origin_x) origin_x = 1 @@ -127,9 +115,6 @@ if(!origin_z) origin_z = 1 var/tmp_cell - var/x - var/y - var/z var/new_path var/num_applied = 0 for (var/thing in block(locate(origin_x, origin_y, origin_z), locate(limit_x, limit_y, origin_z))) @@ -138,14 +123,7 @@ if (!T || (target_turf_type && !istype(T, target_turf_type))) continue - x = T.x - y = T.y - z = T.z - - PREPARE_CELL(x,y) - - if (!tmp_cell) - continue + tmp_cell = TRANSLATE_COORD(T.x, T.y) switch (map[tmp_cell]) if(DOOR_CHAR) @@ -153,7 +131,7 @@ if(EMPTY_CHAR) new_path = mineral_rich if(FLOOR_CHAR) - var/turf/below = GET_BELOW_OR_NULL(T, z) + var/turf/below = GET_BELOW_OR_NULL(T, T.z) if(below) var/area/below_area = below.loc // Let's just assume that the turf is not in nullspace. if(below_area.station_area) diff --git a/code/modules/random_map/noise/noise.dm b/code/modules/random_map/noise/noise.dm index 1ee03fb2526..425952a2af5 100644 --- a/code/modules/random_map/noise/noise.dm +++ b/code/modules/random_map/noise/noise.dm @@ -33,15 +33,14 @@ // Diamond-square algorithm. /datum/random_map/noise/seed_map() // Instantiate the grid. - for(var/x = 1, x <= limit_x, x++) - for(var/y = 1, y <= limit_y, y++) - map[GET_MAP_CELL(x,y)] = 0 + for (var/i = 1 to (limit_x * limit_y)) + map[i] = 0 // Now dump in the actual random data. - map[GET_MAP_CELL(1,1)] = cell_base+rand(initial_cell_range) - map[GET_MAP_CELL(1,limit_y)] = cell_base+rand(initial_cell_range) - map[GET_MAP_CELL(limit_x,limit_y)] = cell_base+rand(initial_cell_range) - map[GET_MAP_CELL(limit_x,1)] = cell_base+rand(initial_cell_range) + map[TRANSLATE_COORD(1,1)] = cell_base+rand(initial_cell_range) + map[TRANSLATE_COORD(1,limit_y)] = cell_base+rand(initial_cell_range) + map[TRANSLATE_COORD(limit_x,limit_y)] = cell_base+rand(initial_cell_range) + map[TRANSLATE_COORD(limit_x,1)] = cell_base+rand(initial_cell_range) /datum/random_map/noise/generate_map() // Begin recursion. @@ -69,33 +68,33 @@ (x,y)----------(x+hsize,y)----------(x+isize,y) */ // Central edge values become average of corners. - map[GET_MAP_CELL(x+hsize,y+isize)] = round((\ - map[GET_MAP_CELL(x,y+isize)] + \ - map[GET_MAP_CELL(x+isize,y+isize)] \ + map[TRANSLATE_COORD(x+hsize,y+isize)] = round((\ + map[TRANSLATE_COORD(x,y+isize)] + \ + map[TRANSLATE_COORD(x+isize,y+isize)] \ )/2) - map[GET_MAP_CELL(x+hsize,y)] = round(( \ - map[GET_MAP_CELL(x,y)] + \ - map[GET_MAP_CELL(x+isize,y)] \ + map[TRANSLATE_COORD(x+hsize,y)] = round(( \ + map[TRANSLATE_COORD(x,y)] + \ + map[TRANSLATE_COORD(x+isize,y)] \ )/2) map[get_map_cell(x,y+hsize)] = round(( \ - map[GET_MAP_CELL(x,y+isize)] + \ - map[GET_MAP_CELL(x,y)] \ + map[TRANSLATE_COORD(x,y+isize)] + \ + map[TRANSLATE_COORD(x,y)] \ )/2) - map[GET_MAP_CELL(x+isize,y+hsize)] = round(( \ - map[GET_MAP_CELL(x+isize,y+isize)] + \ - map[GET_MAP_CELL(x+isize,y)] \ + map[TRANSLATE_COORD(x+isize,y+hsize)] = round(( \ + map[TRANSLATE_COORD(x+isize,y+isize)] + \ + map[TRANSLATE_COORD(x+isize,y)] \ )/2) // Centre value becomes the average of all other values + possible random variance. - var/current_cell = GET_MAP_CELL(x+hsize,y+hsize) + var/current_cell = TRANSLATE_COORD(x+hsize,y+hsize) map[current_cell] = round(( \ - map[GET_MAP_CELL(x+hsize,y+isize)] + \ - map[GET_MAP_CELL(x+hsize,y)] + \ - map[GET_MAP_CELL(x,y+hsize)] + \ - map[GET_MAP_CELL(x+isize,y)] \ + map[TRANSLATE_COORD(x+hsize,y+isize)] + \ + map[TRANSLATE_COORD(x+hsize,y)] + \ + map[TRANSLATE_COORD(x,y+hsize)] + \ + map[TRANSLATE_COORD(x+isize,y)] \ )/4) if(prob(random_variance_chance)) @@ -113,51 +112,48 @@ subdivide(iteration, x+hsize, y+hsize, hsize) /datum/random_map/noise/cleanup() - - for(var/i = 1;i<=smoothing_iterations;i++) + var/is_not_border_left + var/is_not_border_right + for(var/i = 1 to smoothing_iterations) var/list/next_map[limit_x*limit_y] - for(var/x = 1, x <= limit_x, x++) - for(var/y = 1, y <= limit_y, y++) - - var/current_cell = get_map_cell(x,y) + for(var/x = 1 to limit_x) + for(var/y = 1 to limit_y) + var/current_cell = TRANSLATE_COORD(x,y) next_map[current_cell] = map[current_cell] - var/val_count = 0 - var/total = 0 + var/val_count = 1 + var/total = map[current_cell] + + is_not_border_left = (x != 1) + is_not_border_right = (x != limit_x) + + // Center row. Center value's already been done above. + if (is_not_border_left) + total += map[TRANSLATE_COORD(x - 1, y)] + ++val_count + if (is_not_border_right) + total += map[TRANSLATE_COORD(x + 1, y)] + ++val_count + + if (y != 1) // top row + total += map[TRANSLATE_COORD(x, y - 1)] + ++val_count + if (is_not_border_left) + total += map[TRANSLATE_COORD(x - 1, y - 1)] + ++val_count + if (is_not_border_right) + total += map[TRANSLATE_COORD(x + 1, y - 1)] + ++val_count + + if (y != limit_y) // bottom row + total += map[TRANSLATE_COORD(x, y + 1)] + ++val_count + if (is_not_border_left) + total += map[TRANSLATE_COORD(x - 1, y + 1)] + ++val_count + if (is_not_border_right) + total += map[TRANSLATE_COORD(x + 1, y + 1)] + ++val_count - // Get the average neighboring value. - var/tmp_cell - PREPARE_CELL(x+1,y+1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x-1,y-1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x+1,y-1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x-1,y+1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x-1,y) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x,y-1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x+1,y) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - PREPARE_CELL(x,y+1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ total = round(total/val_count) if(abs(map[current_cell]-total) <= cell_smooth_amt) diff --git a/code/modules/random_map/noise/ore.dm b/code/modules/random_map/noise/ore.dm index 889fdf38507..3b1f6dd666f 100644 --- a/code/modules/random_map/noise/ore.dm +++ b/code/modules/random_map/noise/ore.dm @@ -53,7 +53,7 @@ T.resources["carbonaceous rock"] = rand(3,5) var/tmp_cell - PREPARE_CELL(x, y) + TRANSLATE_AND_VERIFY_COORD(x, y) if(tmp_cell < rare_val) // Surface metals. T.resources["iron"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX)