diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index ec573e348a2..dbd78b50188 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -9,7 +9,7 @@ thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT heat_capacity = 700000 - var/transition //These is used in transistions as a way to tell where on the "cube" of space you're transitioning from/to + var/destination_z var/destination_x var/destination_y @@ -85,30 +85,18 @@ user << "\red The plating is going to need some support." return - -// Ported from unstable r355 - /turf/space/Entered(atom/movable/A as mob|obj) ..() - if ((!(A) || src != A.loc)) return + if ((!(A) || src != A.loc)) + return - if(transition) - - if(A.z > MAX_Z) return //for away missions - - if(destination_x) - A.x = destination_x - - if(destination_y) - A.y = destination_y - - var/obj/item/flag/nation/fukkenflag = A.GetTypeInAllContents(/obj/item/flag/nation) - if(fukkenflag) - fukkenflag.loc = fukkenflag.startloc - if(isliving(A)) - A << "The flag you were carrying was just returned to it's base. Nice try." - - A.z = text2num(transition) + if(destination_z) + if(A.z > MAX_Z) + return + + A.x = destination_x + A.y = destination_y + A.z = destination_z if(isliving(A)) var/mob/living/L = A @@ -229,100 +217,5 @@ A.loc.Entered(A) return - -/turf/space/proc/Assign_Destination() - - if(transition) - if(x <= TRANSITIONEDGE) //west - destination_x = world.maxx - TRANSITIONEDGE - 2 - else if (x >= (world.maxx - TRANSITIONEDGE - 1)) //east - destination_x = TRANSITIONEDGE + 1 - else if (y <= TRANSITIONEDGE) //south - destination_y = world.maxy - TRANSITIONEDGE - 2 - else if (y >= (world.maxy - TRANSITIONEDGE - 1)) //north - destination_y = TRANSITIONEDGE + 1 - -/* - Set the space turf transitions for the "space cube" - Connections: - ___ ___ - /_A_/| /_F_/| - | |C| | |E| - |_B_|/ |_D_|/ - Note that all maps except F are oriented with north towards A. A and F are oriented with north towards D. - The characters on the second cube should be upside down in this illustration, but aren't because of a lack of unicode support. -*/ -proc/setup_map_transitions() //listamania - - var/list/unplaced_z_levels = accessable_z_levels - var/list/free_zones = list("A", "B", "C", "D", "E", "F") - var/list/zone_connections = list("D ","C ","B ","E ","A ","C ","F ","E ","A ","D ","F ","B ","A ","E ","F ","C ","A ","B ","F ","D ","D ","C ","B ","E") //This describes the borders of a cube based on free zones, really! - var/text_zone_connections = list2text(zone_connections) - var/list/final_zone_connections = list() - var/list/turfs_needing_transition = list() - var/list/turfs_needing_destinations = list() - var/list/z_level_order = list() - var/z_level - var/placement - var/total_processed = 0 - - for(var/turf/space/S in world) //Define the transistions of the z levels - total_processed++ - if (S.x == TRANSITIONEDGE || S.x == (world.maxx - TRANSITIONEDGE - 1) || S.y == TRANSITIONEDGE || S.y == (world.maxy - TRANSITIONEDGE - 1)) - turfs_needing_transition += S - - //if we've processed lots of turfs, switch to background processing to prevent being mistaken for an infinite loop - if(total_processed > 450000) - set background = 1 - - while(free_zones.len != 0) //Assign the sides of the cube - if(!unplaced_z_levels || !unplaced_z_levels.len) //if we're somehow unable to fill the cube, pad with deep space - z_level = 6 - else - z_level = pick(unplaced_z_levels) - if(z_level > world.maxz) //A safety if one of the unplaced_z_levels doesn't actually exist - z_level = 6 - placement = pick(free_zones) - text_zone_connections = replacetext(text_zone_connections, placement, "[z_level]") - - for(var/turf/space/S in turfs_needing_transition) //pass the identity zone to the relevent turfs - if(S.transition && prob(50)) //In z = 6 (deep space) it's a bit of a crapshoot in terms of navigation - continue - if(S.z == z_level) - S.transition = num2text(z_level) - if(!(S in turfs_needing_destinations)) - turfs_needing_destinations += S - if(S.z != 6) //deep space turfs need to hang around in case they get reassigned a zone - turfs_needing_transition -= S - - z_level_order += num2text(z_level) - unplaced_z_levels -= z_level - free_zones -= placement - - zone_connections = text2list(replacetext(text_zone_connections, " ", "\n")) //Convert the string back into a list - - final_zone_connections.len = z_level_order.len - - var/list/temp = list() - - for(var/j=1, j<= 24, j++) - temp += zone_connections[j] - if(temp.len == 4) //Chunks of cardinal directions - final_zone_connections[z_level_order[j/4]] += temp - temp = list() - - for(var/turf/space/S in turfs_needing_destinations) //replace the identity zone with the destination z-level - var/list/directions = final_zone_connections[S.transition] - if(S.x <= TRANSITIONEDGE) - S.transition = directions[Z_WEST] - else if(S.x >= (world.maxx - TRANSITIONEDGE - 1)) - S.transition = directions[Z_EAST] - else if(S.y <= TRANSITIONEDGE) - S.transition = directions[Z_SOUTH] - else - S.transition = directions[Z_NORTH] - - S.Assign_Destination() - /turf/space/singularity_act() - return \ No newline at end of file + return diff --git a/code/modules/space transition/space_transition.dm b/code/modules/space transition/space_transition.dm new file mode 100644 index 00000000000..81be4604193 --- /dev/null +++ b/code/modules/space transition/space_transition.dm @@ -0,0 +1,187 @@ +//This is realisation of the working torus-looping randomized-per-round space map, this kills the cube + +#define Z_LEVEL_NORTH "1" +#define Z_LEVEL_SOUTH "2" +#define Z_LEVEL_EAST "4" +#define Z_LEVEL_WEST "8" + + +var/list/z_levels_list = list() + +/datum/space_level + var/name = "Your config settings failed, you need to fix this for the datum space levels to work" + var/list/neigbours + var/z_value = 1 //actual z placement + var/linked = 1 + var/xi + var/yi //imaginary placements on the grid + +/datum/space_level/New() + neigbours = list() + var/list/L = list(Z_LEVEL_NORTH,Z_LEVEL_SOUTH,Z_LEVEL_EAST,Z_LEVEL_WEST) + for(var/A in L) + neigbours[A] = src + +/datum/space_level/proc/set_neigbours(list/L) + for(var/datum/point/P in L) + if(P.x == xi) + if(P.y == yi+1) + neigbours[Z_LEVEL_NORTH] = P.spl + P.spl.neigbours[Z_LEVEL_SOUTH] = src + else if(P.y == yi-1) + neigbours[Z_LEVEL_SOUTH] = P.spl + P.spl.neigbours[Z_LEVEL_NORTH] = src + else if(P.y == yi) + if(P.x == xi+1) + neigbours[Z_LEVEL_EAST] = P.spl + P.spl.neigbours[Z_LEVEL_WEST] = src + else if(P.x == xi-1) + neigbours[Z_LEVEL_WEST] = P.spl + P.spl.neigbours[Z_LEVEL_EAST] = src + +/datum/point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else + var/list/neigbours = list() + var/x + var/y + var/datum/space_level/spl + +/datum/point/New(nx, ny, list/point_grid) + if(!point_grid) + qdel(src) + return + var/list/L = point_grid[1] + if(nx > point_grid.len || ny > L.len) + qdel(src) + return + x = nx + y = ny + if(point_grid[x][y]) + return + point_grid[x][y] = src + +/datum/point/proc/set_neigbours(list/grid) + var/max_X = grid.len + var/list/max_Y = grid[1] + max_Y = max_Y.len + neigbours.Cut() + if(x+1 <= max_X) + neigbours |= grid[x+1][y] + if(x-1 >= 1) + neigbours |= grid[x-1][y] + if(y+1 <= max_Y) + neigbours |= grid[x][y+1] + if(y-1 >= 1) + neigbours |= grid[x][y-1] + + +//config/space_levels.txt is where you define your zlevel datum names, their connection to actual z levels and if you want them connected to one another or not +//Grammar: Name;z value;linked/unlinked +//Name is the name of the datum, just for the sake of it +//z value is to what actual map z level this datum is pointing +//linked/unlinked decide if you want the z level in the general map or not, for example centcomm is not reachable +//Each entry must be separated with a single empty line, no spaces outside the name +//No comments in the file allowed + +/proc/setup_map_transitions() //listamania + var/list/SLS = file2list("config/space_levels.txt", "\n\n") + var/datum/space_level/D + var/list/config_settings[SLS.len][] + for(var/A in SLS) + config_settings[SLS.Find(A)] = text2list(A, ";") + var/conf_set_len = SLS.len + SLS.Cut() + for(var/A in config_settings) + D = new() + D.name = A[1] + D.z_value = text2num(A[2]) + if(A[3] != "linked") + D.linked = 0 + z_levels_list["[D.z_value]"] = D + else + SLS.Add(D) + var/list/point_grid[conf_set_len*2+1][conf_set_len*2+1] + var/list/grid = list() + var/datum/point/P + for(var/i = 1, i<=conf_set_len*2+1, i++) + for(var/j = 1, j<=conf_set_len*2+1, j++) + P = new/datum/point(i,j, point_grid) + point_grid[i][j] = P + grid.Add(P) + for(var/datum/point/pnt in grid) + pnt.set_neigbours(point_grid) + P = point_grid[conf_set_len][conf_set_len] + var/list/possible_points = list() + var/list/used_points = list() + grid.Cut() + while(SLS.len) + D = pick(SLS) + SLS.Remove(D) + D.xi = P.x + D.yi = P.y + P.spl = D + possible_points |= P.neigbours + used_points |= P + possible_points.Remove(used_points) + D.set_neigbours(used_points) + P = pick(possible_points) + grid["[D.z_value]"] = D + + for(var/A in z_levels_list) + grid[A] = z_levels_list[A] + + for(var/turf/space/S in world) //Define the transistions of the z levels + if(S.x <= TRANSITIONEDGE) + D = grid["[S.z]"] + if(D.neigbours[Z_LEVEL_WEST] != D) + D = D.neigbours[Z_LEVEL_WEST] + S.destination_z = D.z_value + else + while(D.neigbours[Z_LEVEL_EAST] != D) + D = D.neigbours[Z_LEVEL_EAST] + S.destination_z = D.z_value + S.destination_x = world.maxx - TRANSITIONEDGE - 2 + S.destination_y = S.y + + if(S.x >= (world.maxx - TRANSITIONEDGE - 1)) + D = grid["[S.z]"] + if(D.neigbours[Z_LEVEL_EAST] != D) + D = D.neigbours[Z_LEVEL_EAST] + S.destination_z = D.z_value + else + while(D.neigbours[Z_LEVEL_WEST] != D) + D = D.neigbours[Z_LEVEL_WEST] + S.destination_z = D.z_value + S.destination_x = TRANSITIONEDGE + 2 + S.destination_y = S.y + + if(S.y <= TRANSITIONEDGE) + D = grid["[S.z]"] + if(D.neigbours[Z_LEVEL_SOUTH] != D) + D = D.neigbours[Z_LEVEL_SOUTH] + S.destination_z = D.z_value + else + while(D.neigbours[Z_LEVEL_NORTH] != D) + D = D.neigbours[Z_LEVEL_NORTH] + S.destination_z = D.z_value + S.destination_x = S.x + S.destination_y = world.maxy - TRANSITIONEDGE - 2 + + if(S.y >= (world.maxy - TRANSITIONEDGE - 1)) + D = grid["[S.z]"] + if(D.neigbours[Z_LEVEL_NORTH] != D) + D = D.neigbours[Z_LEVEL_NORTH] + S.destination_z = D.z_value + else + while(D.neigbours[Z_LEVEL_SOUTH] != D) + D = D.neigbours[Z_LEVEL_SOUTH] + S.destination_z = D.z_value + S.destination_x = S.x + S.destination_y = TRANSITIONEDGE + 2 + + for(var/A in grid) + z_levels_list[A] = grid[A] + +#undef Z_LEVEL_NORTH +#undef Z_LEVEL_SOUTH +#undef Z_LEVEL_EAST +#undef Z_LEVEL_WEST diff --git a/paradise.dme b/paradise.dme index 76969b151fa..99373700176 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1822,6 +1822,7 @@ #include "code\modules\shuttles\shuttle_supply.dm" #include "code\modules\shuttles\shuttles_multi.dm" #include "code\modules\shuttles\whiteship.dm" +#include "code\modules\space transition\space_transition.dm" #include "code\modules\store\items.dm" #include "code\modules\store\store.dm" #include "code\modules\surgery\bones.dm"