From 5c37b9e58cc294fd2bd83c506dec7e9e5f692b44 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Wed, 14 Jan 2015 14:13:29 +1030 Subject: [PATCH] Committing some maze fixes and trying to reproduce a weird DD bug. --- code/controllers/master_controller.dm | 10 +- code/controllers/verbs.dm | 17 +++ code/modules/admin/admin_verbs.dm | 1 + code/modules/random_map/maze.dm | 91 ++++++++++--- .../modules/random_map/mining_distribution.dm | 10 +- code/modules/random_map/random_map.dm | 7 +- code/modules/random_map/setpiece.dm | 125 ++++++++++++++++++ 7 files changed, 225 insertions(+), 36 deletions(-) create mode 100644 code/modules/random_map/setpiece.dm diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index 73c8c6c3db..cc9be26f84 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -108,15 +108,19 @@ datum/controller/game_controller/proc/setup_objects() var/obj/machinery/atmospherics/unary/vent_scrubber/T = U T.broadcast_status() + // Create hidden rooms after asteroid is generated but before ore. + for(var/i = 0, i < max_secret_rooms, i++) + make_mining_asteroid_secret() + // Create the mining ore distribution map. // These values determine the specific area that the map is applied to. // If you do not use the official Baycode asteroid map, you will need to change them. asteroid_ore_map = new /datum/random_map/ore(null,13,32,5,217,223) //Shitty hack to fix mining turf overlays, for some reason New() is not being called. - for(var/turf/simulated/floor/plating/airless/asteroid/T in world) - T.updateMineralOverlays() - T.name = "asteroid" + //for(var/turf/simulated/floor/plating/airless/asteroid/T in world) + // T.updateMineralOverlays() + // T.name = "asteroid" //Set up spawn points. populate_spawn_points() diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 73c453824c..3dcba37bc0 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -13,6 +13,23 @@ return choice.display_map(usr) + +/client/proc/create_random_map() + set category = "Debug" + set name = "Create Random Map" + set desc = "Create a random map." + + if(!holder) return + + var/map_datum = input("Choose a map to create.") as null|anything in typesof(/datum/random_map)-/datum/random_map + if(!map_datum) + return + var/seed = input("Seed? (default null)") as text|null + var/tx = input("X? (default 1)") as text|null + var/ty = input("Y? (default 1)") as text|null + var/tz = input("Z? (default 1)") as text|null + new map_datum(seed,tx,ty,tz) + /client/proc/restart_controller(controller in list("Master","Failsafe","Lighting","Supply")) set category = "Debug" set name = "Restart Controller" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 4a19264def..4515ab642d 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -149,6 +149,7 @@ var/list/admin_verbs_debug = list( /client/proc/reload_mentors, /client/proc/restart_controller, /client/proc/print_random_map, + /client/proc/create_random_map, /client/proc/show_plant_genes, /client/proc/enable_debug_verbs, /client/proc/callproc, diff --git a/code/modules/random_map/maze.dm b/code/modules/random_map/maze.dm index 83cb03a4b6..4404e013ef 100644 --- a/code/modules/random_map/maze.dm +++ b/code/modules/random_map/maze.dm @@ -1,10 +1,17 @@ +/datum/maze_coor // why is this necessary ugh + var/x + var/y + +/datum/maze_coor/New(var/nx,var/ny) + x = nx + y = ny + /datum/random_map/maze descriptor = "maze" real_size = 128 - iterations = 0 - size = 4 + iterations = 3 - var/list/marked_walls = list() + var/list/marked = list() /datum/random_map/maze/seed_map() for(var/x = 1, x <= real_size, x++) @@ -12,35 +19,75 @@ map[get_map_cell(x,y)] = 2 // Add a random cell to start the loop with. - marked_walls |= list(list(rand(1,round(real_size/2)),rand(1,round(real_size/2)))) - iterate(1) - -/datum/random_map/maze/iterate() + var/datum/maze_coor/tcoor = new(2*rand(1,round(real_size/2)),2*rand(1,round(real_size/2))) + var/last_x = tcoor.x + var/last_y = tcoor.y + marked |= tcoor // If we make this recursive BYOND freaks out, so it'll have to work as a big fat loop. - while(marked_walls.len) + var/iter_sanity = 0 + while(marked.len && iter_sanity < 5000) //Should cap out at 4096 or so, ideally. + iter_sanity++ + sleep(-1) // Grab a wall entry. - var/index = rand(1,marked_walls.len) - var/list/cell_data = marked_walls[index] - marked_walls.Remove(index) - var/x = cell_data[1] - var/y = cell_data[2] + var/datum/maze_coor/coor = pick(marked) + marked -= coor + var/x = coor.x + var/y = coor.y - // Mark as floor. + // Mark target tile and intermediary wall as floor. + if(last_x && last_y) + var/tx = (last_x < x) ? x-1 : x+1 + var/ty = (last_y < y) ? y-1 : y+1 + last_x = x + last_y = y + if(within_bounds(get_map_cell(tx,ty))) + map[get_map_cell(tx,ty)] = 1 if(within_bounds(get_map_cell(x,y))) map[get_map_cell(x,y)] = 1 // Iterate over neighbors. if(within_bounds(get_map_cell(x,y+2)) && map[get_map_cell(x,y+2)] == 2) - marked_walls |= list(list(x,y+2)) - map[get_map_cell(x,y+1)] = 1 + marked |= new /datum/maze_coor(x,y+2) if(within_bounds(get_map_cell(x,y-2)) && map[get_map_cell(x,y-2)] == 2) - marked_walls |= list(list(x,y-2)) - map[get_map_cell(x,y-1)] = 1 + marked |= new /datum/maze_coor(x,y-2) if(within_bounds(get_map_cell(x+2,y)) && map[get_map_cell(x+2,y)] == 2) - marked_walls |= list(list(x+2,y)) - map[get_map_cell(x+1,y)] = 1 + marked |= new /datum/maze_coor(x+2,y) if(within_bounds(get_map_cell(x-2,y)) && map[get_map_cell(x-2,y)] == 2) - marked_walls |= list(list(x-2,y)) - map[get_map_cell(x-1,y)] = 1 \ No newline at end of file + marked |= new /datum/maze_coor(x-2,y) + +/datum/random_map/maze/iterate() + var/list/next_map[raw_map_size] + for(var/x = 1, x <= real_size, x++) + for(var/y = 1, y <= real_size, y++) + var/current_cell = get_map_cell(x,y) + // Sanity check. + if(!within_bounds(current_cell)) + continue + // Copy over original value. + next_map[current_cell] = map[current_cell] + // Check all neighbors. + var/count = 0 + if(next_map[current_cell] == 2) + for(var/cell in list(get_map_cell(x+1,y+1),get_map_cell(x-1,y-1),get_map_cell(x+1,y-1),get_map_cell(x-1,y+1),get_map_cell(x-1,y),get_map_cell(x,y-1),get_map_cell(x+1,y),get_map_cell(x,y+1))) + if(within_bounds(cell) && map[cell] == 1) + count++ + if(count>= 7) + next_map[current_cell] = 1 // becomes a floor + break + map = next_map + + +/datum/random_map/maze/apply_to_turf(var/x,var/y) + var/current_cell = get_map_cell(x,y) + if(!within_bounds(current_cell)) + return + var/turf/T = locate(x,y,origin_z) + if(map[current_cell] == 2) + T.ChangeTurf(/turf/simulated/wall) + else + T.ChangeTurf(/turf/simulated/floor) + +/datum/random_map/maze/cleanup() + return 1 \ No newline at end of file diff --git a/code/modules/random_map/mining_distribution.dm b/code/modules/random_map/mining_distribution.dm index 9b6faf9c02..76c3b5bcc0 100644 --- a/code/modules/random_map/mining_distribution.dm +++ b/code/modules/random_map/mining_distribution.dm @@ -28,9 +28,6 @@ Deep minerals: descriptor = "resource distribution map" real_size = 65 // Must be (power of 2)+1 for diamond-square. cell_range = 255 // These values are used to seed ore values rather than to determine a turf type. - var/cell_base // Set in New() - var/initial_cell_range // Set in New() - iterations = 0 // We'll handle iterating on our end (recursive, with args). var/chunk_size = 4 // Size each cell represents on map @@ -38,6 +35,8 @@ Deep minerals: var/random_element = 0.5 // Determines the variance when smoothing out cell values. var/deep_val = 0.8 // Threshold for deep metals, set in new as percentage of cell_range. var/rare_val = 0.7 // Threshold for rare metal, set in new as percentage of cell_range. + var/cell_base // Set in New() + var/initial_cell_range // Set in New() /datum/random_map/ore/New() rare_val = cell_range * rare_val @@ -77,9 +76,6 @@ Deep minerals: //Halfassed diamond-square algorithm with some fuckery since it's a single dimension array. /datum/random_map/ore/seed_map() - // Reset size. - size = real_size-1 - // Instantiate the grid. for(var/x = 1, x <= real_size, x++) for(var/y = 1, y <= real_size, y++) @@ -90,7 +86,7 @@ Deep minerals: map[get_map_cell(1,real_size)] = cell_base+rand(initial_cell_range) map[get_map_cell(real_size,real_size)] = cell_base+rand(initial_cell_range) map[get_map_cell(real_size,1)] = cell_base+rand(initial_cell_range) - iterate(1,1,1,size) // Start the recursion here. + iterate(1,1,1,(real_size-1)) // Start the recursion here. /datum/random_map/ore/display_map(atom/user) diff --git a/code/modules/random_map/random_map.dm b/code/modules/random_map/random_map.dm index 338caafb2d..278f51876d 100644 --- a/code/modules/random_map/random_map.dm +++ b/code/modules/random_map/random_map.dm @@ -6,16 +6,15 @@ var/global/list/random_maps = list() /datum/random_map - var/descriptor = "asteroid" // Display name. + var/descriptor = "asteroid" // Display name. var/real_size = 246 // Size of each edge (must be square :(). - var/size = 2 // In basic implementation this will only be used for 3x3 blocks. var/cell_range = 2 // Random range for initial cells. var/iterations = 5 // Number of times to apply the automata rule. var/max_attempts = 5 // Fail if a sane map isn't generated by this point. var/raw_map_size // Used for creating new maps each iteration. Value must be real_size^2 var/list/map = list() // Actual map. - var/origin_x = 0 // Origin point, left. - var/origin_y = 0 // Origin point, bottom. + var/origin_x = 1 // Origin point, left. + var/origin_y = 1 // Origin point, bottom. var/origin_z = 1 // Target Z-level. var/limit_x = 256 // Maximum x bound. var/limit_y = 256 // Maximum y bound. diff --git a/code/modules/random_map/setpiece.dm b/code/modules/random_map/setpiece.dm new file mode 100644 index 0000000000..f4d728bcf5 --- /dev/null +++ b/code/modules/random_map/setpiece.dm @@ -0,0 +1,125 @@ +/datum/setpiece + var/descriptor + var/base_x + var/base_y + var/origin_x + var/origin_y + var/origin_z + var/x_bound + var/y_bound + var/list/map + var/min_x = 32 + var/min_y = 32 + +/datum/setpiece/New(var/x, var/y, var/x_size, var/y_size) + + // Get operating paramaters. + if(x_size) + x_bound = x_size + else + x_bound = base_x + if(y_size) + y_bound = y_size + else + y_bound = base_y + + origin_x = x + origin_y = y + + // Initialize map. + map = list() + map.len = x_bound * y_bound + + // Build. + if(is_buildable()) + generate() + apply_to_map() + return 1 + return 0 + +/datum/setpiece/proc/is_buildable() + return 1 + +/datum/setpiece/proc/apply_to_map() + return 1 + +/datum/setpiece/proc/generate() + return 1 + +/datum/setpiece/asteroid_secret + descriptor = "secret room" + base_x = 5 + base_y = 5 + min_x = 5 + min_y = 5 + +/datum/setpiece/asteroid_secret/is_buildable() + + var/valid = 0 + var/turf/T = null + var/sanity = 0 + var/list/room = null + var/list/turfs = null + + turfs = get_area_turfs(/area/mine/unexplored) + + if(!turfs.len) + return 0 + + while(!valid) + valid = 1 + sanity++ + if(sanity > 100) + return 0 + + T=pick(turfs) + if(!T) + return 0 + + var/list/surroundings = list() + + surroundings += range(7, locate(T.x,T.y,T.z)) + surroundings += range(7, locate(T.x+size,T.y,T.z)) + surroundings += range(7, locate(T.x,T.y+size,T.z)) + surroundings += range(7, locate(T.x+size,T.y+size,T.z)) + + if(locate(/area/mine/explored) in surroundings) // +5s are for view range + valid = 0 + continue + + if(locate(/turf/space) in surroundings) + valid = 0 + continue + + if(locate(/area/asteroid/artifactroom) in surroundings) + valid = 0 + continue + + if(locate(/turf/simulated/floor/plating/airless/asteroid) in surroundings) + valid = 0 + continue + + if(!T) + return 0 + + room = spawn_room(T,size,size,,,1) + + if(room) + T = pick(room["floors"]) + if(T) + var/surprise = null + valid = 0 + while(!valid) + surprise = pickweight(space_surprises) + if(surprise in spawned_surprises) + if(prob(20)) + valid++ + else + continue + else + valid++ + + spawned_surprises.Add(surprise) + new surprise(T) + + return 1 \ No newline at end of file