[MIRROR] Backports Bay/Neb random map optimizations.

This commit is contained in:
Chompstation Bot
2021-09-27 18:23:26 +00:00
parent cfad19ad15
commit 1b244b5de5
4 changed files with 207 additions and 130 deletions

View File

@@ -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 -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_SURFACE_COUNT 75
#define MIN_RARE_COUNT 50 #define MIN_RARE_COUNT 50
#define MIN_DEEP_COUNT 25 #define MIN_DEEP_COUNT 25
@@ -12,12 +13,42 @@
#define RESOURCE_MID_MIN 0.5 #define RESOURCE_MID_MIN 0.5
#define RESOURCE_LOW_MAX 0.5 #define RESOURCE_LOW_MAX 0.5
#define RESOURCE_LOW_MIN 0 #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 FLOOR_CHAR 0
#define WALL_CHAR 1 #define WALL_CHAR 1
#define DOOR_CHAR 2 #define DOOR_CHAR 2
#define EMPTY_CHAR 3 #define EMPTY_CHAR 3
#define ROOM_TEMP_CHAR 4 #define ROOM_TEMP_CHAR 4
#define MONSTER_CHAR 5 #define MONSTER_CHAR 5
#define ARTIFACT_TURF_CHAR 6 #define ARTIFACT_TURF_CHAR 6
#define ARTIFACT_CHAR 7 #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;\
}

View File

@@ -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 /datum/random_map/automata
descriptor = "generic caves" descriptor = "generic caves"
initial_wall_cell = 55 initial_wall_cell = 55
@@ -8,58 +12,60 @@
// Automata-specific procs and processing. // Automata-specific procs and processing.
/datum/random_map/automata/generate_map() /datum/random_map/automata/generate_map()
for(var/i=1;i<=iterations;i++) for(var/iter = 1 to iterations)
iterate(i) 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) if (!islist(map))
return set_map_size()
/datum/random_map/automata/proc/iterate(var/iteration) for (var/i in 1 to (limit_x * limit_y))
var/list/next_map[limit_x*limit_y] count = 0
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
// Every attempt to place this in a proc or a list has resulted in is_not_border_left = i != 1 && ((i - 1) % limit_x)
// the generator being totally bricked and useless. Fuck it. We're is_not_border_right = i % limit_x
// hardcoding this shit. Feel free to rewrite and PR a fix. ~ Z
var/tmp_cell = get_map_cell(x,y) if (CELL_ALIVE(map[i])) // Center row.
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ ++count
tmp_cell = get_map_cell(x+1,y+1) if (is_not_border_left && CELL_ALIVE(map[i - 1]))
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ ++count
tmp_cell = get_map_cell(x-1,y-1) if (is_not_border_right && CELL_ALIVE(map[i + 1]))
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ ++count
tmp_cell = get_map_cell(x+1,y-1)
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ if (i > limit_x) // top row
tmp_cell = get_map_cell(x-1,y+1) ilim_u = i - limit_x
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ if (CELL_ALIVE(map[ilim_u]))
tmp_cell = get_map_cell(x-1,y) ++count
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ if (is_not_border_left && CELL_ALIVE(map[ilim_u - 1]))
tmp_cell = get_map_cell(x,y-1) ++count
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ if (is_not_border_right && CELL_ALIVE(map[ilim_u + 1]))
tmp_cell = get_map_cell(x+1,y) ++count
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++
tmp_cell = get_map_cell(x,y+1) if (i <= bottom_lim) // bottom row
if(tmp_cell && cell_is_alive(map[tmp_cell])) count++ 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) if(count >= cell_threshold)
revive_cell(current_cell, next_map, (iteration == iterations)) REVIVE_CELL(i, next_map)
else else // Nope. Can't be alive. Kill it.
kill_cell(current_cell, next_map, (iteration == iterations)) KILL_CELL(i, next_map)
map = next_map
// Check if a given tile counts as alive for the automata generations. CHECK_TICK
/datum/random_map/automata/proc/cell_is_alive(var/value)
return (value == cell_live_value) && (value != cell_dead_value)
/datum/random_map/automata/proc/revive_cell(var/target_cell, var/list/use_next_map, var/final_iter) map = next_map
if(!use_next_map)
use_next_map = map
use_next_map[target_cell] = cell_live_value
/datum/random_map/automata/proc/kill_cell(var/target_cell, var/list/use_next_map, var/final_iter) /datum/random_map/automata/get_additional_spawns(value, turf/T)
if(!use_next_map) return
use_next_map = map
use_next_map[target_cell] = cell_dead_value #undef KILL_CELL
#undef REVIVE_CELL

View File

@@ -18,28 +18,36 @@
return "X" return "X"
return ..(value) 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. // Create ore turfs.
/datum/random_map/automata/cave_system/cleanup() /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/ore_count = round(map.len/20)
var/door_count = 0
var/empty_count = 0
while((ore_count>0) && (ore_turfs.len>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) var/check_cell = pick(ore_turfs)
ore_turfs -= check_cell ore_turfs -= check_cell
if(prob(75)) if(prob(75))
map[check_cell] = DOOR_CHAR // Mineral block map[check_cell] = DOOR_CHAR // Mineral block
door_count += 1
else else
map[check_cell] = EMPTY_CHAR // Rare mineral block. map[check_cell] = EMPTY_CHAR // Rare mineral block.
empty_count += 1
ore_count-- ore_count--
testing("ASGEN: Set [door_count] turfs to random minerals.")
testing("ASGEN: Set [empty_count] turfs to high-chance random minerals.")
return 1 return 1
/datum/random_map/automata/cave_system/apply_to_turf(var/x,var/y) /datum/random_map/automata/cave_system/apply_to_turf(var/x,var/y)

View File

@@ -10,6 +10,7 @@
var/cell_base // Set in New() var/cell_base // Set in New()
var/initial_cell_range // Set in New() var/initial_cell_range // Set in New()
var/smoothing_iterations = 0 var/smoothing_iterations = 0
var/smooth_single_tiles // Single turfs of different value are not allowed
/datum/random_map/noise/New() /datum/random_map/noise/New()
initial_cell_range = cell_range/5 initial_cell_range = cell_range/5
@@ -35,13 +36,13 @@
// Instantiate the grid. // Instantiate the grid.
for(var/x = 1, x <= limit_x, x++) for(var/x = 1, x <= limit_x, x++)
for(var/y = 1, y <= limit_y, y++) 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. // Now dump in the actual random data.
map[get_map_cell(1,1)] = cell_base+rand(initial_cell_range) map[TRANSLATE_COORD(1,1)] = cell_base+rand(initial_cell_range)
map[get_map_cell(1,limit_y)] = cell_base+rand(initial_cell_range) map[TRANSLATE_COORD(1,limit_y)] = cell_base+rand(initial_cell_range)
map[get_map_cell(limit_x,limit_y)] = cell_base+rand(initial_cell_range) map[TRANSLATE_COORD(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(limit_x,1)] = cell_base+rand(initial_cell_range)
/datum/random_map/noise/generate_map() /datum/random_map/noise/generate_map()
// Begin recursion. // Begin recursion.
@@ -69,33 +70,33 @@
(x,y)----------(x+hsize,y)----------(x+isize,y) (x,y)----------(x+hsize,y)----------(x+isize,y)
*/ */
// Central edge values become average of corners. // Central edge values become average of corners.
map[get_map_cell(x+hsize,y+isize)] = round((\ map[TRANSLATE_COORD(x+hsize,y+isize)] = round((\
map[get_map_cell(x,y+isize)] + \ map[TRANSLATE_COORD(x,y+isize)] + \
map[get_map_cell(x+isize,y+isize)] \ map[TRANSLATE_COORD(x+isize,y+isize)] \
)/2) )/2)
map[get_map_cell(x+hsize,y)] = round(( \ map[TRANSLATE_COORD(x+hsize,y)] = round(( \
map[get_map_cell(x,y)] + \ map[TRANSLATE_COORD(x,y)] + \
map[get_map_cell(x+isize,y)] \ map[TRANSLATE_COORD(x+isize,y)] \
)/2) )/2)
map[get_map_cell(x,y+hsize)] = round(( \ map[get_map_cell(x,y+hsize)] = round(( \
map[get_map_cell(x,y+isize)] + \ map[TRANSLATE_COORD(x,y+isize)] + \
map[get_map_cell(x,y)] \ map[TRANSLATE_COORD(x,y)] \
)/2) )/2)
map[get_map_cell(x+isize,y+hsize)] = round(( \ map[TRANSLATE_COORD(x+isize,y+hsize)] = round(( \
map[get_map_cell(x+isize,y+isize)] + \ map[TRANSLATE_COORD(x+isize,y+isize)] + \
map[get_map_cell(x+isize,y)] \ map[TRANSLATE_COORD(x+isize,y)] \
)/2) )/2)
// Centre value becomes the average of all other values + possible random variance. // 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[current_cell] = round(( \
map[get_map_cell(x+hsize,y+isize)] + \ map[TRANSLATE_COORD(x+hsize,y+isize)] + \
map[get_map_cell(x+hsize,y)] + \ map[TRANSLATE_COORD(x+hsize,y)] + \
map[get_map_cell(x,y+hsize)] + \ map[TRANSLATE_COORD(x,y+hsize)] + \
map[get_map_cell(x+isize,y)] \ map[TRANSLATE_COORD(x+isize,y)] \
)/4) )/4)
if(prob(random_variance_chance)) if(prob(random_variance_chance))
@@ -104,58 +105,58 @@
// Recurse until size is too small to subdivide. // Recurse until size is too small to subdivide.
if(isize>3) if(isize>3)
if(!priority_process) sleep(-1) if(!priority_process)
CHECK_TICK
iteration++ iteration++
subdivide(iteration, x, y, hsize) subdivide(iteration, x, y, hsize)
subdivide(iteration, x+hsize, y, hsize) subdivide(iteration, x+hsize, y, hsize)
subdivide(iteration, x, y+hsize, hsize) subdivide(iteration, x, y+hsize, hsize)
subdivide(iteration, x+hsize, 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() /datum/random_map/noise/cleanup()
var/is_not_border_left
for(var/i = 1;i<=smoothing_iterations;i++) var/is_not_border_right
for(var/i = 1 to smoothing_iterations)
var/list/next_map[limit_x*limit_y] var/list/next_map[limit_x*limit_y]
for(var/x = 1, x <= limit_x, x++) for(var/x = 1 to limit_x)
for(var/y = 1, y <= limit_y, y++) for(var/y = 1 to limit_y)
var/current_cell = TRANSLATE_COORD(x,y)
var/current_cell = get_map_cell(x,y)
next_map[current_cell] = map[current_cell] next_map[current_cell] = map[current_cell]
var/val_count = 0 var/val_count = 1
var/total = 0 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) total = round(total/val_count)
if(abs(map[current_cell]-total) <= cell_smooth_amt) if(abs(map[current_cell]-total) <= cell_smooth_amt)
@@ -166,3 +167,34 @@
map[current_cell]-=cell_smooth_amt map[current_cell]-=cell_smooth_amt
map[current_cell] = max(0,min(cell_range,map[current_cell])) map[current_cell] = max(0,min(cell_range,map[current_cell]))
map = next_map 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)