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:
Tigercat2000
2015-05-11 12:26:48 -07:00
parent 9dff485066
commit d98bf2d958
10 changed files with 1083 additions and 767 deletions
+53
View File
@@ -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
+1 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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))))
+2
View File
@@ -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)