mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 08:06:33 +01:00
21b4095dfd
Upstream 04/17/2026 fixes https://github.com/Bubberstation/Bubberstation/issues/5549 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com> Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com> Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com> Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com> Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com> Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com> Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com> Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com> Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com> Co-authored-by: loganuk <fakeemail123@aol.com> Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com> Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com> Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com> Co-authored-by: Lucy <lucy@absolucy.moe> Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com> Co-authored-by: Isratosh <Isratosh@hotmail.com> Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com> Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com> Co-authored-by: Alexander V. <volas@ya.ru> Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com> Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com> Co-authored-by: Tim <timothymtorres@gmail.com> Co-authored-by: Iamgoofball <iamgoofball@gmail.com> Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com> Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com> Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com> Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com> Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com> Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com> Co-authored-by: Josh <josh.adam.powell@gmail.com> Co-authored-by: Josh Powell <josh.powell@softwire.com> Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com> Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com> Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com> Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
207 lines
8.0 KiB
Plaintext
207 lines
8.0 KiB
Plaintext
/datum/space_level/proc/set_linkage(new_linkage)
|
|
linkage = new_linkage
|
|
if(linkage == SELFLOOPING)
|
|
neigbours = list(TEXT_NORTH,TEXT_SOUTH,TEXT_EAST,TEXT_WEST)
|
|
for(var/A in neigbours)
|
|
neigbours[A] = src
|
|
|
|
/datum/space_level/proc/set_neigbours(list/L)
|
|
for(var/datum/space_transition_point/P in L)
|
|
if(P.x == xi)
|
|
if(P.y == yi+1)
|
|
neigbours[TEXT_NORTH] = P.spl
|
|
P.spl.neigbours[TEXT_SOUTH] = src
|
|
else if(P.y == yi-1)
|
|
neigbours[TEXT_SOUTH] = P.spl
|
|
P.spl.neigbours[TEXT_NORTH] = src
|
|
else if(P.y == yi)
|
|
if(P.x == xi+1)
|
|
neigbours[TEXT_EAST] = P.spl
|
|
P.spl.neigbours[TEXT_WEST] = src
|
|
else if(P.x == xi-1)
|
|
neigbours[TEXT_WEST] = P.spl
|
|
P.spl.neigbours[TEXT_EAST] = src
|
|
|
|
#define CHORDS_TO_1D(x, y, grid_diameter) ((x) + ((y) - 1) * (grid_diameter))
|
|
/datum/space_transition_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/space_transition_point/New(nx, ny, list/grid)
|
|
if(!grid)
|
|
qdel(src)
|
|
return
|
|
var/grid_diameter = sqrt(length(grid))
|
|
if(nx > grid_diameter || ny > grid_diameter)
|
|
stack_trace("Attempted to set a position outside the size of [grid_diameter]")
|
|
qdel(src)
|
|
return
|
|
x = nx
|
|
y = ny
|
|
var/position = CHORDS_TO_1D(x, y, grid_diameter)
|
|
if(grid[position])
|
|
return
|
|
grid[position] = src
|
|
|
|
/datum/space_transition_point/proc/set_neigbours(list/grid, size)
|
|
neigbours.Cut()
|
|
|
|
if(x+1 <= size)
|
|
neigbours |= grid[CHORDS_TO_1D(x+1, y, size)]
|
|
if(x-1 >= 1)
|
|
neigbours |= grid[CHORDS_TO_1D(x-1, y, size)]
|
|
if(y+1 <= size)
|
|
neigbours |= grid[CHORDS_TO_1D(x, y + 1, size)]
|
|
if(y-1 >= 1)
|
|
neigbours |= grid[CHORDS_TO_1D(x, y - 1, size)]
|
|
|
|
/datum/controller/subsystem/mapping/proc/setup_map_transitions() //listamania
|
|
var/list/transition_levels = list()
|
|
var/list/cached_z_list = z_list
|
|
var/linkage
|
|
for(var/datum/space_level/level as anything in cached_z_list)
|
|
if(level.linkage != CROSSLINKED && level.linkage != GRIDLINKED)
|
|
continue
|
|
|
|
transition_levels.Add(level)
|
|
|
|
if(!isnull(linkage) && level.linkage != linkage)
|
|
// Either you be gridlinked or crosslinked, both is uhhh... a headache
|
|
stack_trace("Mixed linkages detected in z-level neighbour transitions!")
|
|
continue
|
|
linkage = level.linkage
|
|
|
|
if(linkage == CROSSLINKED)
|
|
set_cross_linkages(transition_levels)
|
|
else if(linkage == GRIDLINKED)
|
|
set_grid_linkages(transition_levels)
|
|
|
|
// Now that we've handed out neighbors, we're gonna handle an edge case
|
|
// Need to check if all our levels have neighbors in all directions
|
|
// If they don't, we'll make them wrap all the way around to the other side of the grid
|
|
for(var/direction in GLOB.cardinals)
|
|
var/dir = "[direction]"
|
|
var/inverse = "[REVERSE_DIR(direction)]"
|
|
for(var/datum/space_level/level as anything in transition_levels)
|
|
// If we have something in this dir that isn't just us, continue on
|
|
if(level.neigbours[dir] && level.neigbours[dir] != level)
|
|
continue
|
|
var/datum/space_level/head = level
|
|
while(head.neigbours[inverse] && head.neigbours[inverse] != head)
|
|
head = head.neigbours[inverse]
|
|
|
|
// Alllright we've landed on someone who we can wrap around onto safely, let's make that connection yeah?
|
|
head.neigbours[inverse] = level
|
|
level.neigbours[dir] = head
|
|
|
|
//Lists below are pre-calculated values arranged in the list in such a way to be easily accessable in the loop by the counter
|
|
//Its either this or madness with lotsa math
|
|
var/inner_max_x = world.maxx - TRANSITIONEDGE
|
|
var/inner_max_y = world.maxy - TRANSITIONEDGE
|
|
var/list/x_pos_beginning = list(1, 1, inner_max_x, 1) //x values of the lowest-leftest turfs of the respective 4 blocks on each side of zlevel
|
|
var/list/y_pos_beginning = list(inner_max_y, 1, 1 + TRANSITIONEDGE, 1 + TRANSITIONEDGE) //y values respectively
|
|
var/list/x_pos_ending = list(world.maxx, world.maxx, world.maxx, 1 + TRANSITIONEDGE) //x values of the highest-rightest turfs of the respective 4 blocks on each side of zlevel
|
|
var/list/y_pos_ending = list(world.maxy, 1 + TRANSITIONEDGE, inner_max_y, inner_max_y) //y values respectively
|
|
var/list/x_pos_transition = list(1, 1, TRANSITIONEDGE + 2, inner_max_x - 1) //values of x for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective x value later in the code
|
|
var/list/y_pos_transition = list(TRANSITIONEDGE + 2, inner_max_y - 1, 1, 1) //values of y for the transition from respective blocks on the side of zlevel, 1 is being translated into turfs respective y value later in the code
|
|
|
|
// Cache the range passed to the mirage border element, to reduce world var access in the thousands
|
|
var/range_cached = (maxviewdist() - 1) / 2
|
|
|
|
for(var/datum/space_level/level as anything in cached_z_list)
|
|
if(!level.neigbours.len)
|
|
continue
|
|
var/zlevelnumber = level.z_value
|
|
for(var/side in 1 to 4)
|
|
var/list/turfblock = block(
|
|
x_pos_beginning[side], y_pos_beginning[side], zlevelnumber,
|
|
x_pos_ending[side], y_pos_ending[side], zlevelnumber
|
|
)
|
|
var/dirside = 2**(side-1)
|
|
var/x_target = x_pos_transition[side] == 1 ? 0 : x_pos_transition[side]
|
|
var/y_target = y_pos_transition[side] == 1 ? 0 : y_pos_transition[side]
|
|
var/datum/space_level/neighbor = level.neigbours["[dirside]"]
|
|
var/zdestination = neighbor.z_value
|
|
|
|
for(var/turf/open/S in turfblock)
|
|
S.destination_x = x_target || S.x
|
|
S.destination_y = y_target || S.y
|
|
S.destination_z = zdestination
|
|
|
|
// Mirage border code
|
|
var/mirage_dir
|
|
if(S.x == 1 + TRANSITIONEDGE)
|
|
mirage_dir |= WEST
|
|
else if(S.x == inner_max_x)
|
|
mirage_dir |= EAST
|
|
if(S.y == 1 + TRANSITIONEDGE)
|
|
mirage_dir |= SOUTH
|
|
else if(S.y == inner_max_y)
|
|
mirage_dir |= NORTH
|
|
if(!mirage_dir)
|
|
continue
|
|
|
|
var/turf/place = locate(S.destination_x, S.destination_y, zdestination)
|
|
S.AddElement(/datum/element/mirage_border, place, mirage_dir, range_cached)
|
|
|
|
/// Construct linkages randomly to get maze-like space transitions
|
|
/// We do this by constructing a very large grid, and placing the levels randomly inside, and then filling out the empty spaces
|
|
/datum/controller/subsystem/mapping/proc/set_cross_linkages(list/transition_levels)
|
|
var/grid_diameter = (length(transition_levels) * 2) + 1
|
|
var/list/grid = new /list(grid_diameter ** 2)
|
|
|
|
var/datum/space_transition_point/point
|
|
for(var/x in 1 to grid_diameter)
|
|
for(var/y in 1 to grid_diameter)
|
|
point = new /datum/space_transition_point(x, y, grid)
|
|
grid[CHORDS_TO_1D(x, y, grid_diameter)] = point
|
|
for(point as anything in grid)
|
|
point.set_neigbours(grid, grid_diameter)
|
|
|
|
var/center = round(grid_diameter / 2)
|
|
if(transition_levels.len)
|
|
point = grid[CHORDS_TO_1D(center, center, grid_diameter)]
|
|
grid.Cut()
|
|
|
|
var/list/transition_pick = transition_levels.Copy()
|
|
var/list/possible_points = list()
|
|
var/list/used_points = list()
|
|
|
|
while(transition_pick.len)
|
|
var/datum/space_level/level = pick_n_take(transition_pick)
|
|
level.xi = point.x
|
|
level.yi = point.y
|
|
point.spl = level
|
|
possible_points |= point.neigbours
|
|
used_points |= point
|
|
possible_points.Remove(used_points)
|
|
level.set_neigbours(used_points)
|
|
point = pick(possible_points)
|
|
CHECK_TICK
|
|
|
|
/// Connect the z-levels in a non-randomized grid
|
|
/datum/controller/subsystem/mapping/proc/set_grid_linkages(list/transition_levels)
|
|
var/grid_diameter = ceil(sqrt(length(transition_levels)))
|
|
var/list/grid = new /list(grid_diameter ** 2)
|
|
|
|
// Construct an imaginary grid with the right neighbours etc for our grid
|
|
var/datum/space_transition_point/point
|
|
for(var/x in 1 to grid_diameter)
|
|
for(var/y in 1 to grid_diameter)
|
|
point = new /datum/space_transition_point(x, y, grid)
|
|
grid[CHORDS_TO_1D(x, y, grid_diameter)] = point
|
|
|
|
// Translate the grid we made to the z-levels
|
|
var/list/used_points = list()
|
|
for(var/i in 1 to transition_levels.len)
|
|
var/datum/space_level/level = transition_levels[i]
|
|
point = grid[i]
|
|
level.xi = point.x
|
|
level.yi = point.y
|
|
point.spl = level
|
|
used_points += point //this used_points list is kinda lame, you can remove it if you can find out what the slice function in byond is
|
|
level.set_neigbours(used_points)
|
|
#undef CHORDS_TO_1D
|