mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 11:05:03 +01:00
Spacecube transitioning
This commit adds the spacecube system from -tg-. The spacecube system allows for predicatably random space layouts- it is randomized every round, but the transitions stay consistant for that round, therefore making it possible to 'map' space, or explore in teams.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
#define Z_NORTH 1
|
||||
#define Z_EAST 2
|
||||
#define Z_SOUTH 3
|
||||
#define Z_WEST 4
|
||||
|
||||
var/list/cardinal = list( NORTH, SOUTH, EAST, WEST )
|
||||
var/list/alldirs = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
|
||||
|
||||
//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there.
|
||||
//(Exceptions: extended, sandbox and nuke) -Errorage
|
||||
//Was list("3" = 30, "4" = 70).
|
||||
//Spacing should be a reliable method of getting rid of a body -- Urist.
|
||||
//Go away Urist, I'm restoring this to the longer list. ~Errorage
|
||||
var/list/accessable_z_levels = list(1,3,4,5,6,7) //Keep this to six maps, repeating z-levels is okay if needed
|
||||
|
||||
var/global/list/global_map = null
|
||||
//list/global_map = list(list(1,5),list(4,3))//an array of map Z levels.
|
||||
//Resulting sector map looks like
|
||||
//|_1_|_4_|
|
||||
//|_5_|_3_|
|
||||
//
|
||||
//1 - SS13
|
||||
//4 - Derelict
|
||||
//3 - AI satellite
|
||||
//5 - empty space
|
||||
|
||||
var/shuttle_z = 2 //default
|
||||
|
||||
var/list/monkeystart = list()
|
||||
var/list/wizardstart = list()
|
||||
var/list/newplayer_start = list()
|
||||
var/list/latejoin = list()
|
||||
var/list/latejoin_gateway = list()
|
||||
var/list/latejoin_cryo = list()
|
||||
var/list/latejoin_cyborg = list()
|
||||
var/list/prisonwarp = list() //prisoners go to these
|
||||
var/list/holdingfacility = list() //captured people go here
|
||||
var/list/xeno_spawn = list()//Aliens spawn at these.
|
||||
// list/mazewarp = list()
|
||||
var/list/tdome1 = list()
|
||||
var/list/tdome2 = list()
|
||||
var/list/team_alpha = list()
|
||||
var/list/team_bravo = list()
|
||||
var/list/tdomeobserve = list()
|
||||
var/list/tdomeadmin = list()
|
||||
var/list/aroomwarp = list()
|
||||
var/list/prisonsecuritywarp = list() //prison security goes to these
|
||||
var/list/prisonwarped = list() //list of players already warped
|
||||
var/list/blobstart = list()
|
||||
var/list/ninjastart = list()
|
||||
|
||||
//away missions
|
||||
var/list/awaydestinations = list() //a list of landmarks that the warpgate can take you to
|
||||
@@ -356,5 +356,4 @@ datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
|
||||
msg += "\t [varname] = [D.type]\n"
|
||||
else
|
||||
msg += "\t [varname] = [varval]\n"
|
||||
world.log << msg
|
||||
|
||||
world.log << msg
|
||||
+138
-95
@@ -7,6 +7,10 @@
|
||||
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_x
|
||||
var/destination_y
|
||||
|
||||
/turf/space/New()
|
||||
if(!istype(src, /turf/space/transit))
|
||||
icon_state = "[((x + y) ^ ~(x * y) + z) % 25]"
|
||||
@@ -77,109 +81,53 @@
|
||||
|
||||
inertial_drift(A)
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
if(transition)
|
||||
|
||||
// Okay, so let's make it so that people can travel z levels but not nuke disks!
|
||||
// if(ticker.mode.name == "nuclear emergency") return
|
||||
if(A.z > MAX_Z) return // For "Unenterable" z levels, they have their own entrance/exit code, eg: Away missions
|
||||
if (A.x <= TRANSITIONEDGE || A.x >= (world.maxx - TRANSITIONEDGE - 1) || A.y <= TRANSITIONEDGE || A.y >= (world.maxy - TRANSITIONEDGE - 1))
|
||||
if(istype(A, /obj/effect/meteor)||istype(A, /obj/effect/space_dust))
|
||||
del(A)
|
||||
return
|
||||
if(A.z > MAX_Z) return //for away missions
|
||||
|
||||
if(istype(A, /obj/item/weapon/disk/nuclear)) // Don't let nuke disks travel Z levels ... And moving this shit down here so it only fires when they're actually trying to change z-level.
|
||||
del(A) //The disk's Destroy() proc ensures a new one is created
|
||||
return
|
||||
if(istype(A, /obj/item/flag/nation)) // Don't letflags travel Z levels ... And moving this shit down here so it only fires when they're actually trying to change z-level.
|
||||
var/obj/item/flag/nation/N = A
|
||||
N.loc = N.startloc //The flag returns to base.
|
||||
return
|
||||
var/mob/living/MM = null
|
||||
var/fukkendisk = A.GetTypeInAllContents(/obj/item/weapon/disk/nuclear)
|
||||
var/obj/item/flag/nation/fukkenflag = A.GetTypeInAllContents(/obj/item/flag/nation)
|
||||
if(fukkenflag)
|
||||
fukkenflag.loc = fukkenflag.startloc
|
||||
if(isliving(A))
|
||||
A << "<span class='warning'>The flag you were carrying was just returned to it's base. Nice try.</span>"
|
||||
if(fukkendisk)
|
||||
if(isliving(A))
|
||||
MM = A
|
||||
if(MM.client && !MM.stat)
|
||||
MM << "<span class='warning'>Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is.</span>"
|
||||
if(MM.x <= TRANSITIONEDGE)
|
||||
MM.inertia_dir = 4
|
||||
else if(MM.x >= world.maxx -TRANSITIONEDGE)
|
||||
MM.inertia_dir = 8
|
||||
else if(MM.y <= TRANSITIONEDGE)
|
||||
MM.inertia_dir = 1
|
||||
else if(MM.y >= world.maxy -TRANSITIONEDGE)
|
||||
MM.inertia_dir = 2
|
||||
else
|
||||
qdel(fukkendisk)//Make the disk respawn if it is on a clientless mob or corpse
|
||||
else
|
||||
qdel(fukkendisk)//Make the disk respawn if it is floating on its own
|
||||
return
|
||||
if(destination_x)
|
||||
A.x = destination_x
|
||||
|
||||
if(destination_y)
|
||||
A.y = destination_y
|
||||
|
||||
//Check if it's a mob pulling an object. Have the object transition with the mob if it's not the nuke disk
|
||||
var/obj/was_pulling = null
|
||||
var/mob/living/MM = null
|
||||
var/fukkendisk = A.GetTypeInAllContents(/obj/item/weapon/disk/nuclear)
|
||||
var/obj/item/flag/nation/fukkenflag = A.GetTypeInAllContents(/obj/item/flag/nation)
|
||||
if(fukkenflag)
|
||||
fukkenflag.loc = fukkenflag.startloc
|
||||
if(isliving(A))
|
||||
A << "<span class='warning'>The flag you were carrying was just returned to it's base. Nice try.</span>"
|
||||
if(fukkendisk)
|
||||
if(isliving(A))
|
||||
MM = A
|
||||
if(MM.pulling)
|
||||
//Check for that fucking disk
|
||||
if(istype(MM.pulling, /obj/item/weapon/disk/nuclear))
|
||||
qdel(MM.pulling)
|
||||
else
|
||||
was_pulling = MM.pulling
|
||||
fukkenflag = null
|
||||
fukkendisk = was_pulling.GetTypeInAllContents(/obj/item/weapon/disk/nuclear)
|
||||
fukkenflag = was_pulling.GetTypeInAllContents(/obj/item/flag/nation)
|
||||
if(fukkenflag)
|
||||
fukkenflag.loc = fukkenflag.startloc
|
||||
if(isliving(A))
|
||||
A << "<span class='warning'>The flag you were carrying was just returned to it's base. Nice try.</span>"
|
||||
if(fukkendisk)
|
||||
MM << "<span class='warning'>You think you saw something slip out of [was_pulling], but you couldn't tell where it went...</span>"
|
||||
qdel(fukkendisk)
|
||||
if(MM.client && !MM.stat)
|
||||
MM << "<span class='warning'>Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is.</span>"
|
||||
if(MM.x <= TRANSITIONEDGE)
|
||||
MM.inertia_dir = 4
|
||||
else if(MM.x >= world.maxx -TRANSITIONEDGE)
|
||||
MM.inertia_dir = 8
|
||||
else if(MM.y <= TRANSITIONEDGE)
|
||||
MM.inertia_dir = 1
|
||||
else if(MM.y >= world.maxy -TRANSITIONEDGE)
|
||||
MM.inertia_dir = 2
|
||||
else
|
||||
qdel(fukkendisk)//Make the disk respawn if it is on a clientless mob or corpse
|
||||
else
|
||||
qdel(fukkendisk)//Make the disk respawn if it is floating on its own
|
||||
return
|
||||
|
||||
var/move_to_z = src.z
|
||||
var/safety = 1
|
||||
A.z = text2num(transition)
|
||||
|
||||
while(move_to_z == src.z)
|
||||
var/move_to_z_str = pickweight(accessable_z_levels)
|
||||
move_to_z = text2num(move_to_z_str)
|
||||
safety++
|
||||
if(safety > 10)
|
||||
break
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.pulling)
|
||||
var/turf/T = get_step(L.loc,turn(A.dir, 180))
|
||||
L.pulling.loc = T
|
||||
|
||||
if(!move_to_z)
|
||||
return
|
||||
|
||||
A.z = move_to_z
|
||||
|
||||
if(src.x <= TRANSITIONEDGE)
|
||||
A.x = world.maxx - TRANSITIONEDGE - 2
|
||||
A.y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
|
||||
|
||||
else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
|
||||
A.x = TRANSITIONEDGE + 1
|
||||
A.y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
|
||||
|
||||
else if (src.y <= TRANSITIONEDGE)
|
||||
A.y = world.maxy - TRANSITIONEDGE -2
|
||||
A.x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
|
||||
|
||||
else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
|
||||
A.y = TRANSITIONEDGE + 1
|
||||
A.x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
|
||||
|
||||
spawn (0)
|
||||
if(was_pulling && MM)
|
||||
was_pulling.loc = MM.loc
|
||||
MM.pulling = was_pulling
|
||||
was_pulling.pulledby = MM
|
||||
if ((A && A.loc))
|
||||
A.loc.Entered(A)
|
||||
//now we're on the new z_level, proceed the space drifting
|
||||
if ((A && A.loc))
|
||||
A.loc.Entered(A)
|
||||
|
||||
/turf/space/proc/Sandbox_Spacemove(atom/movable/A as mob|obj)
|
||||
var/cur_x
|
||||
@@ -288,4 +236,99 @@
|
||||
spawn (0)
|
||||
if ((A && A.loc))
|
||||
A.loc.Entered(A)
|
||||
return
|
||||
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()
|
||||
+3
-41
@@ -17,18 +17,6 @@ var/global/list/sec_hud_users = list()
|
||||
|
||||
var/global/defer_powernet_rebuild = 0 // true if net rebuild will be called manually after an event
|
||||
|
||||
var/global/list/global_map = null
|
||||
//list/global_map = list(list(1,5),list(4,3))//an array of map Z levels.
|
||||
//Resulting sector map looks like
|
||||
//|_1_|_4_|
|
||||
//|_5_|_3_|
|
||||
//
|
||||
//1 - SS13
|
||||
//4 - Derelict
|
||||
//3 - AI satellite
|
||||
//5 - empty space
|
||||
|
||||
|
||||
//////////////
|
||||
var/list/paper_tag_whitelist = list("center","p","div","span","h1","h2","h3","h4","h5","h6","hr","pre", \
|
||||
"big","small","font","i","u","b","s","sub","sup","tt","br","hr","ol","ul","li","caption","col", \
|
||||
@@ -131,6 +119,8 @@ var/master_mode = "extended"//"extended"
|
||||
var/secret_force_mode = "secret" // if this is anything but "secret", the secret rotation will forceably choose this mode
|
||||
|
||||
var/datum/engine_eject/engine_eject_control = null
|
||||
var/list/carplist = list()
|
||||
// list/traitors = list() //traitor list
|
||||
var/host = null
|
||||
var/aliens_allowed = 1
|
||||
var/ooc_allowed = 1
|
||||
@@ -159,36 +149,9 @@ var/mouse_respawn_time = 5 //Amount of time that must pass between a player dyin
|
||||
var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
|
||||
var/CHARGELEVEL = 0.0005 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
|
||||
|
||||
var/shuttle_z = 2 //default
|
||||
var/airtunnel_start = 68 // default
|
||||
var/airtunnel_stop = 68 // default
|
||||
var/airtunnel_bottom = 72 // default
|
||||
var/list/monkeystart = list()
|
||||
var/list/wizardstart = list()
|
||||
var/list/newplayer_start = list()
|
||||
var/list/latejoin = list()
|
||||
var/list/latejoin_gateway = list()
|
||||
var/list/latejoin_cryo = list()
|
||||
var/list/latejoin_cyborg = list()
|
||||
var/list/prisonwarp = list() //prisoners go to these
|
||||
var/list/holdingfacility = list() //captured people go here
|
||||
var/list/xeno_spawn = list()//Aliens spawn at these.
|
||||
// list/mazewarp = list()
|
||||
var/list/tdome1 = list()
|
||||
var/list/tdome2 = list()
|
||||
var/list/team_alpha = list()
|
||||
var/list/team_bravo = list()
|
||||
var/list/tdomeobserve = list()
|
||||
var/list/tdomeadmin = list()
|
||||
var/list/aroomwarp = list()
|
||||
var/list/prisonsecuritywarp = list() //prison security goes to these
|
||||
var/list/prisonwarped = list() //list of players already warped
|
||||
var/list/blobstart = list()
|
||||
var/list/ninjastart = list()
|
||||
var/list/carplist = list()
|
||||
// list/traitors = list() //traitor list
|
||||
var/list/cardinal = list( NORTH, SOUTH, EAST, WEST )
|
||||
var/list/alldirs = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
|
||||
// reverse_dir[dir] = reverse of dir
|
||||
var/list/reverse_dir = list(2, 1, 3, 8, 10, 9, 11, 4, 6, 5, 7, 12, 14, 13, 15, 32, 34, 33, 35, 40, 42, 41, 43, 36, 38, 37, 39, 44, 46, 45, 47, 16, 18, 17, 19, 24, 26, 25, 27, 20, 22, 21, 23, 28, 30, 29, 31, 48, 50, 49, 51, 56, 58, 57, 59, 52, 54, 53, 55, 60, 62, 61, 63)
|
||||
|
||||
@@ -243,8 +206,7 @@ var/datum/event_manager/event_manager = new()
|
||||
#define EVENT_LEVEL_MODERATE 2
|
||||
#define EVENT_LEVEL_MAJOR 3
|
||||
|
||||
//away missions
|
||||
var/list/awaydestinations = list() //a list of landmarks that the warpgate can take you to
|
||||
|
||||
|
||||
// MySQL configuration
|
||||
|
||||
|
||||
+1
-7
@@ -453,13 +453,7 @@ var/MAX_EX_FLASH_RANGE = 14
|
||||
#define GAS_CO2 (1 << 3)
|
||||
#define GAS_N2O (1 << 4)
|
||||
|
||||
#define MAX_Z 7 // Used in space.dm to defince which Z-levels cannot be exited via space.
|
||||
var/list/accessable_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = 60)
|
||||
//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there.
|
||||
//(Exceptions: extended, sandbox and nuke) -Errorage
|
||||
//Was list("3" = 30, "4" = 70).
|
||||
//Spacing should be a reliable method of getting rid of a body -- Urist.
|
||||
//Go away Urist, I'm restoring this to the longer list. ~Errorage
|
||||
#define MAX_Z 8 // Used in space.dm to defince which Z-levels cannot be exited via space.
|
||||
|
||||
#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE))))
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
// Create robolimbs for chargen.
|
||||
populate_robolimb_list()
|
||||
|
||||
setup_map_transitions() //Before the MC starts up
|
||||
|
||||
processScheduler = new
|
||||
master_controller = new /datum/controller/game_controller()
|
||||
spawn(1)
|
||||
|
||||
Reference in New Issue
Block a user