diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index adaab0540a..64b75c3fce 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -172,6 +172,7 @@ var/list/gamemode_cache = list() var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect var/list/player_levels = list(1, 3, 4, 5, 6) // Defines all Z-levels a character can typically reach + var/list/sealed_levels = list() // Defines levels that do not allow random transit at the edges. // Event settings var/expected_round_length = 3 * 60 * 60 * 10 // 3 hours diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f86c135da4..84baf5d18e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -210,4 +210,52 @@ /atom/movable/overlay/attack_hand(a, b, c) if (src.master) return src.master.attack_hand(a, b, c) - return + return + +/atom/movable/proc/touch_map_edge() + if(z in config.sealed_levels) + return + + if(config.use_overmap) + overmap_spacetravel(get_turf(src), src) + return + + var/move_to_z = src.get_transit_zlevel() + if(move_to_z) + z = move_to_z + + if(x <= TRANSITIONEDGE) + x = world.maxx - TRANSITIONEDGE - 2 + y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2) + + else if (x >= (world.maxx - TRANSITIONEDGE - 1)) + x = TRANSITIONEDGE + 1 + y = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2) + + else if (y <= TRANSITIONEDGE) + y = world.maxy - TRANSITIONEDGE -2 + x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) + + else if (y >= (world.maxy - TRANSITIONEDGE - 1)) + y = TRANSITIONEDGE + 1 + x = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2) + + if(ticker && istype(ticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear + var/datum/game_mode/nuclear/G = ticker.mode + G.check_nuke_disks() + + spawn(0) + if(loc) loc.Entered(src) + +//This list contains the z-level numbers which can be accessed via space travel and the percentile chances to get there. +var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = 60) + +//by default, transition randomly to another zlevel +/atom/movable/proc/get_transit_zlevel() + var/list/candidates = accessible_z_levels.Copy() + candidates.Remove("[src.z]") + + if(!candidates.len) + return null + return text2num(pickweight(candidates)) + diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm index 4e064d8be6..13cdb511e8 100644 --- a/code/game/gamemodes/events/dust.dm +++ b/code/game/gamemodes/events/dust.dm @@ -89,6 +89,8 @@ The "dust" will damage the hull of the station causin minor hull breaches. walk_towards(src, goal, 1) return + touch_map_edge() + qdel(src) Bump(atom/A) spawn(0) diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 9d18216aa5..06d9b291a2 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -161,4 +161,7 @@ if(istype(W, /obj/item/weapon/pickaxe)) qdel(src) return - ..() + ..() + +/obj/effect/meteor/touch_map_edge() + qdel(src) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index b556ba2070..5d8ac9d071 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -2,6 +2,8 @@ MERCENARY ROUNDTYPE */ +var/list/nuke_disks = list() + /datum/game_mode/nuclear name = "Mercenary" round_description = "A mercenary strike force is approaching the station!" @@ -17,6 +19,18 @@ var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level +//delete all nuke disks not on a station zlevel +/datum/game_mode/nuclear/proc/check_nuke_disks() + for(var/obj/item/weapon/disk/nuclear/N in nuke_disks) + if(isNotStationLevel(N.z)) qdel(N) + +//checks if L has a nuke disk on their person +/datum/game_mode/nuclear/proc/check_mob(mob/living/L) + for(var/obj/item/weapon/disk/nuclear/N in nuke_disks) + if(N.storage_depth(L) >= 0) + return 1 + return 0 + /datum/game_mode/nuclear/declare_completion() if(config.objectives_disabled) return diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm index 2fb1c721d3..dfada178c6 100644 --- a/code/game/machinery/nuclear_bomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -423,9 +423,16 @@ obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob) return return -/obj/item/weapon/disk/nuclear/Destroy() - if(blobstart.len > 0) - var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) - message_admins("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") - log_game("[src] has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") +/obj/item/weapon/disk/nuclear/New() ..() + nuke_disks |= src + +/obj/item/weapon/disk/nuclear/Destroy() + if(!nuke_disks.len && blobstart.len > 0) + var/obj/D = new /obj/item/weapon/disk/nuclear(pick(blobstart)) + message_admins("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + log_game("[src], the last authentication disk, has been destroyed. Spawning [D] at ([D.x], [D.y], [D.z]).") + ..() + +/obj/item/weapon/disk/nuclear/touch_map_edge() + qdel(src) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index d8db07de58..641c3e3086 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -1,6 +1,4 @@ -//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 -var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = 60) + /turf/space icon = 'icons/turf/space.dmi' @@ -67,77 +65,10 @@ var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" = if(ticker && ticker.mode) - if(A.z > 6 && !config.use_overmap) return + // Okay, so let's make it so that people can travel z levels but not nuke disks! + // if(ticker.mode.name == "mercenary") return 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)) - qdel(A) - return - - 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. - qdel(A) //The disk's Destroy() proc ensures a new one is created - return - if(config.use_overmap) - overmap_spacetravel(src,A) - return - var/list/disk_search = A.search_contents_for(/obj/item/weapon/disk/nuclear) - if(!isemptylist(disk_search)) - if(istype(A, /mob/living)) - var/mob/living/MM = A - if(MM.client && !MM.stat) - MM << "\red Something you are carrying is preventing you from leaving. Don't play stupid; you know exactly what it is." - 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 - for(var/obj/item/weapon/disk/nuclear/N in disk_search) - qdel(N)//Make the disk respawn it is on a clientless mob or corpse - else - for(var/obj/item/weapon/disk/nuclear/N in disk_search) - qdel(N)//Make the disk respawn if it is floating on its own - return - - var/move_to_z = src.z - var/safety = 1 - - while(move_to_z == src.z) - var/move_to_z_str = pickweight(accessible_z_levels) - move_to_z = text2num(move_to_z_str) - safety++ - if(safety > 10) - break - - 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 ((A && A.loc)) - A.loc.Entered(A) + A.touch_map_edge() /turf/space/proc/Sandbox_Spacemove(atom/movable/A as mob|obj) var/cur_x diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 80902ddaa9..3097d90659 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -777,3 +777,22 @@ default behaviour is: return ..() +/mob/living/touch_map_edge() + + //check for nuke disks + if(client && stat != DEAD) //if they are clientless and dead don't bother, the parent will treat them as any other container + if(ticker && istype(ticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear + var/datum/game_mode/nuclear/G = ticker.mode + if(G.check_mob(src)) + if(x <= TRANSITIONEDGE) + inertia_dir = 4 + else if(x >= world.maxx -TRANSITIONEDGE) + inertia_dir = 8 + else if(y <= TRANSITIONEDGE) + inertia_dir = 1 + else if(y >= world.maxy -TRANSITIONEDGE) + inertia_dir = 2 + src << "