From 1b244b5de57c37259752240ec0502dd99d0910ff Mon Sep 17 00:00:00 2001 From: Chompstation Bot Date: Mon, 27 Sep 2021 18:23:26 +0000 Subject: [PATCH] [MIRROR] Backports Bay/Neb random map optimizations. --- code/modules/random_map/_random_map_setup.dm | 47 +++++- code/modules/random_map/automata/automata.dm | 100 ++++++------ code/modules/random_map/automata/caves.dm | 30 ++-- code/modules/random_map/noise/noise.dm | 160 +++++++++++-------- 4 files changed, 207 insertions(+), 130 deletions(-) diff --git a/code/modules/random_map/_random_map_setup.dm b/code/modules/random_map/_random_map_setup.dm index 9c8213b904..7ee7373e34 100644 --- a/code/modules/random_map/_random_map_setup.dm +++ b/code/modules/random_map/_random_map_setup.dm @@ -3,6 +3,7 @@ -This controls the amount of sand turf it will create in the caves, I assume it controls the amount of minerals and undeground minerals aswell */ +<<<<<<< HEAD #define MIN_SURFACE_COUNT 75 #define MIN_RARE_COUNT 50 #define MIN_DEEP_COUNT 25 @@ -12,12 +13,42 @@ #define RESOURCE_MID_MIN 0.5 #define RESOURCE_LOW_MAX 0.5 #define RESOURCE_LOW_MIN 0 +||||||| parent of 569e369789... Merge pull request #11614 from VOREStation/upstream-merge-8299 +#define MIN_SURFACE_COUNT 500 +#define MIN_RARE_COUNT 200 +#define MIN_DEEP_COUNT 100 +#define RESOURCE_HIGH_MAX 4 +#define RESOURCE_HIGH_MIN 2 +#define RESOURCE_MID_MAX 3 +#define RESOURCE_MID_MIN 1 +#define RESOURCE_LOW_MAX 1 +#define RESOURCE_LOW_MIN 0 +======= +#define MIN_SURFACE_COUNT 500 +#define MIN_RARE_COUNT 200 +#define MIN_DEEP_COUNT 100 +#define RESOURCE_HIGH_MAX 4 +#define RESOURCE_HIGH_MIN 2 +#define RESOURCE_MID_MAX 3 +#define RESOURCE_MID_MIN 1 +#define RESOURCE_LOW_MAX 1 +#define RESOURCE_LOW_MIN 0 +>>>>>>> 569e369789... Merge pull request #11614 from VOREStation/upstream-merge-8299 -#define FLOOR_CHAR 0 -#define WALL_CHAR 1 -#define DOOR_CHAR 2 -#define EMPTY_CHAR 3 -#define ROOM_TEMP_CHAR 4 -#define MONSTER_CHAR 5 -#define ARTIFACT_TURF_CHAR 6 -#define ARTIFACT_CHAR 7 \ No newline at end of file +#define FLOOR_CHAR 0 +#define WALL_CHAR 1 +#define DOOR_CHAR 2 +#define EMPTY_CHAR 3 +#define ROOM_TEMP_CHAR 4 +#define MONSTER_CHAR 5 +#define ARTIFACT_TURF_CHAR 6 +#define ARTIFACT_CHAR 7 + +#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 f3867d78bd..544b625a33 100644 --- a/code/modules/random_map/automata/automata.dm +++ b/code/modules/random_map/automata/automata.dm @@ -1,3 +1,7 @@ +#define CELL_ALIVE(VAL) (VAL == cell_live_value) +#define KILL_CELL(CELL, NEXT_MAP) NEXT_MAP[CELL] = cell_dead_value; +#define REVIVE_CELL(CELL, NEXT_MAP) NEXT_MAP[CELL] = cell_live_value; + /datum/random_map/automata descriptor = "generic caves" initial_wall_cell = 55 @@ -8,58 +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] - for(var/x = 1, x <= limit_x, x++) - for(var/y = 1, y <= limit_y, y++) - var/current_cell = get_map_cell(x,y) - next_map[current_cell] = map[current_cell] - var/count = 0 + 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 - var/tmp_cell = get_map_cell(x,y) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x+1,y+1) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x-1,y-1) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x+1,y-1) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x-1,y+1) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x-1,y) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x,y-1) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x+1,y) - if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ - tmp_cell = get_map_cell(x,y+1) - if(tmp_cell && cell_is_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, (iteration == iterations)) - else - kill_cell(current_cell, next_map, (iteration == iterations)) - map = next_map + REVIVE_CELL(i, next_map) + else // Nope. Can't be alive. Kill it. + KILL_CELL(i, next_map) -// Check if a given tile counts as alive for the automata generations. -/datum/random_map/automata/proc/cell_is_alive(var/value) - return (value == cell_live_value) && (value != cell_dead_value) + 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 \ No newline at end of file +/datum/random_map/automata/get_additional_spawns(value, turf/T) + return + +#undef KILL_CELL +#undef REVIVE_CELL \ No newline at end of file diff --git a/code/modules/random_map/automata/caves.dm b/code/modules/random_map/automata/caves.dm index 0d3b49eb67..f2609b1d8f 100644 --- a/code/modules/random_map/automata/caves.dm +++ b/code/modules/random_map/automata/caves.dm @@ -18,28 +18,36 @@ return "X" return ..(value) -/datum/random_map/automata/cave_system/revive_cell(var/target_cell, var/list/use_next_map, var/final_iter) - ..() - if(final_iter) - ore_turfs |= target_cell - -/datum/random_map/automata/cave_system/kill_cell(var/target_cell, var/list/use_next_map, var/final_iter) - ..() - if(final_iter) - ore_turfs -= target_cell - // Create ore turfs. /datum/random_map/automata/cave_system/cleanup() + var/tmp_cell + for (var/x = 1 to limit_x) + for (var/y = 1 to limit_y) + tmp_cell = TRANSLATE_COORD(x, y) + if (CELL_ALIVE(map[tmp_cell])) + ore_turfs += tmp_cell + + testing("ASGEN: Found [ore_turfs.len] ore turfs.") var/ore_count = round(map.len/20) + var/door_count = 0 + var/empty_count = 0 while((ore_count>0) && (ore_turfs.len>0)) - if(!priority_process) sleep(-1) + + if(!priority_process) + CHECK_TICK + var/check_cell = pick(ore_turfs) ore_turfs -= check_cell if(prob(75)) map[check_cell] = DOOR_CHAR // Mineral block + door_count += 1 else map[check_cell] = EMPTY_CHAR // Rare mineral block. + empty_count += 1 ore_count-- + + testing("ASGEN: Set [door_count] turfs to random minerals.") + testing("ASGEN: Set [empty_count] turfs to high-chance random minerals.") return 1 /datum/random_map/automata/cave_system/apply_to_turf(var/x,var/y) diff --git a/code/modules/random_map/noise/noise.dm b/code/modules/random_map/noise/noise.dm index 8e45a21c3f..d8702a59a6 100644 --- a/code/modules/random_map/noise/noise.dm +++ b/code/modules/random_map/noise/noise.dm @@ -10,6 +10,7 @@ var/cell_base // Set in New() var/initial_cell_range // Set in New() var/smoothing_iterations = 0 + var/smooth_single_tiles // Single turfs of different value are not allowed /datum/random_map/noise/New() initial_cell_range = cell_range/5 @@ -35,13 +36,13 @@ // 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 + map[TRANSLATE_COORD(x,y)] = 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 +70,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)) @@ -104,58 +105,58 @@ // Recurse until size is too small to subdivide. if(isize>3) - if(!priority_process) sleep(-1) + if(!priority_process) + CHECK_TICK iteration++ subdivide(iteration, x, y, hsize) subdivide(iteration, x+hsize, y, hsize) subdivide(iteration, x, y+hsize, hsize) subdivide(iteration, x+hsize, y+hsize, hsize) +#define NOISE2VALUE(X) CLAMP(round(((X)/cell_range)*10), 0, 9) /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 = get_map_cell(x+1,y+1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_cell(x-1,y-1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_cell(x+1,y-1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_cell(x-1,y+1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_cell(x-1,y) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_cell(x,y-1) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_cell(x+1,y) - if(tmp_cell) - total += map[tmp_cell] - val_count++ - tmp_cell = get_map_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) @@ -165,4 +166,35 @@ else if(map[current_cell] < total) map[current_cell]-=cell_smooth_amt map[current_cell] = max(0,min(cell_range,map[current_cell])) - map = next_map \ No newline at end of file + map = next_map + + if(smooth_single_tiles) + var/list/buddies = list() + for(var/x in 1 to limit_x - 1) + for(var/y in 1 to limit_y - 1) + var/mapcell = get_map_cell(x,y) + var/list/neighbors = get_neighbors(x, y) + buddies.Cut() + var/mapcellval = NOISE2VALUE(map[mapcell]) + for(var/cell in neighbors) + if(NOISE2VALUE(map[cell]) == mapcellval) + buddies |= cell + if(!length(buddies)) + map[mapcell] = map[pick(neighbors)] +#undef NOISE2VALUE + +/datum/random_map/noise/proc/get_neighbors(x, y, include_diagonals) + . = list() + if(!include_diagonals) + var/static/list/ortho_offsets = list(list(-1, 0), list(1, 0), list(0, 1), list(0,-1)) + for(var/list/offset in ortho_offsets) + var/tmp_cell = get_map_cell(x+offset[1],y+offset[2]) + if(tmp_cell) + . += tmp_cell + else + for(var/dx in -1 to 1) + for(var/dy in -1 to 1) + var/tmp_cell = get_map_cell(x+dx,y+dy) + if(tmp_cell) + . += tmp_cell + . -= get_map_cell(x,y)