// Controls the emergency shuttle #define SHUTTLE_TRANSIT 1 // these define the time taken for the shuttle to get to SS13 // and the time before it leaves again #define SHUTTLEARRIVETIME 360 // 6 minutes = 360 seconds #define SHUTTLELEAVETIME 120 // 2 minutes = 120 seconds #define SHUTTLETRANSITTIME 120 // 2 minutes = 120 seconds var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle datum/shuttle_controller var/location = 0 //0 = somewhere far away, 1 = at SS13, 2 = returned from SS13 var/online = 0 var/direction = 1 //-1 = going back to central command, 1 = going back to SS13 var/disabled = 0 //Block shuttle calling if it's disabled. var/callcount = 0 //Number of shuttle calls required to break through interference (wizard mode) var/endtime // round_elapsed_ticks that shuttle arrives var/announcement_done = 0 var/can_recall = 1 // set to 0 in the admin call thing to make it not recallable var/list/airbridges = list() var/map_turf = /turf/space //Set in New() by map settings var/transit_turf = /turf/space/no_replace //Not currently modified var/centcom_turf = /turf/unsimulated/outdoors/grass //Not currently modified // call the shuttle // if not called before, set the endtime to T+600 seconds // otherwise if outgoing, switch to incoming proc/incall() if (online) if(direction == -1) setdirection(1) else settimeleft(SHUTTLEARRIVETIME) online = 1 ircbot.event("shuttlecall", src.timeleft()) proc/recall() if (online && direction == 1) setdirection(-1) ircbot.event("shuttlerecall", src.timeleft()) // returns the time (in seconds) before shuttle arrival // note if direction = -1, gives a count-up to SHUTTLEARRIVETIME proc/timeleft() if(online) var/timeleft = round((endtime - ticker.round_elapsed_ticks)/10 ,1) if(direction == 1) return timeleft else return SHUTTLEARRIVETIME-timeleft else return SHUTTLEARRIVETIME // sets the time left to a given delay (in seconds) proc/settimeleft(var/delay) endtime = ticker.round_elapsed_ticks + delay * 10 // sets the shuttle direction // 1 = towards SS13, -1 = back to centcom proc/setdirection(var/dirn) if(direction == dirn) return direction = dirn // if changing direction, flip the timeleft by SHUTTLEARRIVETIME var/ticksleft = endtime - ticker.round_elapsed_ticks endtime = ticker.round_elapsed_ticks + (SHUTTLEARRIVETIME*10 - ticksleft) return proc/process() emergency_shuttle New() ..() for (var/obj/machinery/computer/airbr/S in machines) if (S.emergency && !(S in src.airbridges)) src.airbridges += S map_turf = map_settings.shuttle_map_turf process() if (!online) return var/timeleft = timeleft() if (timeleft > 1e5 || timeleft <= 0) // midnight rollover protection timeleft = 0 switch (location) if (SHUTTLE_LOC_CENTCOM) if (timeleft>SHUTTLEARRIVETIME) online = 0 direction = 1 endtime = null return 0 else if (timeleft <= 0) location = SHUTTLE_LOC_STATION if (ticker && ticker.mode) if (ticker.mode.shuttle_available == 0) command_alert("CentCom has received reports of unusual activity on the station. The shuttle has been returned to base as a precaution, and will not be usable."); online = 0 direction = 1 endtime = null return 0 if (ticker.mode.shuttle_available == 2 && (ticker.round_elapsed_ticks < max(0, ticker.mode.shuttle_available_threshold)) && callcount < 1) callcount++ command_alert("CentCom reports that the emergency shuttle has veered off course due to unknown interference. The next shuttle will be equipped with electronic countermeasures to break through."); online = 0 direction = 1 location = SHUTTLE_LOC_CENTCOM endtime = null return 0 processScheduler.disableProcess("Fluid_Turfs") var/area/start_location = locate(map_settings ? map_settings.escape_centcom : /area/shuttle/escape/centcom) var/area/end_location = locate(map_settings ? map_settings.escape_station : /area/shuttle/escape/station) var/list/dstturfs = list() var/northBound = 1 var/southBound = world.maxy var/westBound = world.maxx var/eastBound = 1 for (var/atom/A as obj|mob in end_location) SPAWN_DBG(0) A.ex_act(1) for (var/turf/P in start_location) if (istype(P, centcom_turf)) new map_turf(P) end_location.color = null //Remove the colored shuttle! for (var/turf/T in end_location) dstturfs += T if (T.y > northBound) northBound = T.y if (T.y < southBound) southBound = T.y if (T.x < westBound) westBound = T.x if (T.x > eastBound) eastBound = T.x // hey you, get out of the way! var/shuttle_dir = map_settings ? map_settings.escape_dir : EAST // default to cog2 direction because EH for (var/turf/T in dstturfs) // find the turf to move things to var/turf/D = locate(shuttle_dir == EAST ? eastBound + 1 : T.x, // X shuttle_dir == NORTH ? northBound + 1 : shuttle_dir == EAST ? T.y : southBound - 1, // Y 1) // Z for (var/atom/movable/AM as mob|obj in T) if (isobserver(AM)) continue // skip ghosties AM.set_loc(D) // NOTE: Commenting this out to avoid recreating mass driver glitch /* SPAWN_DBG(0) AM.throw_at(E, 1, 1) return */ if (istype(T, /turf/simulated)) T.ReplaceWithSpace() start_location.move_contents_to(end_location, centcom_turf) settimeleft(SHUTTLELEAVETIME) #ifdef UNDERWATER_MAP end_location.force_fullbright = 1 end_location.update_fullbright() #endif if (src.airbridges.len) for (var/obj/machinery/computer/airbr/S in src.airbridges) S.establish_bridge() boutput(world, "The Emergency Shuttle has docked with the station! You have [timeleft()/60] minutes to board the Emergency Shuttle.") ircbot.event("shuttledock") world << csound("sound/misc/shuttle_arrive1.ogg") processScheduler.enableProcess("Fluid_Turfs") return 1 #ifdef SHUTTLE_TRANSIT // shuttle spends some time in transit to centcom before arriving if (SHUTTLE_LOC_STATION) if (!announcement_done && timeleft <= 60) var/display_time = round(timeleft()/60) //if (display_time <= 0) // The Emergency Shuttle will be entering the wormhole to CentCom in 0 minutes! //display_time = 1 // fuckofffffffffff boutput(world, "The Emergency Shuttle will be entering the wormhole to CentCom in [display_time] minute[s_es(display_time)]! Please prepare for wormhole traversal.") announcement_done = 1 else if (announcement_done < 2 && timeleft < 30) var/area/sound_location = locate(/area/shuttle_sound_spawn) playsound(sound_location, 'sound/effects/ship_charge.ogg', 100) announcement_done = 2 else if (announcement_done < 3 && timeleft < 4) var/area/sound_location = locate(/area/shuttle_sound_spawn) playsound(sound_location, 'sound/effects/ship_engage.ogg', 100) announcement_done = 3 else if (announcement_done < 4 && timeleft < 1) var/area/sound_location = locate(/area/shuttle_sound_spawn) playsound(sound_location, 'sound/effects/explosion_new4.ogg', 75) playsound(sound_location, 'sound/effects/flameswoosh.ogg', 75) announcement_done = 4 if (src.airbridges.len) for (var/obj/machinery/computer/airbr/S in src.airbridges) S.remove_bridge() else if (timeleft > 0) return 0 else location = SHUTTLE_LOC_TRANSIT var/area/start_location = locate(map_settings ? map_settings.escape_station : /area/shuttle/escape/station) var/area/end_location = locate(map_settings ? map_settings.escape_transit : /area/shuttle/escape/transit) var/door_type = map_settings ? map_settings.ext_airlocks : /obj/machinery/door/airlock/external for (var/obj/machinery/door/D in start_location) if (istype(D, door_type)) D.set_density(1) D.locked = 1 D.update_icon() for (var/atom/A in start_location) if(istype( A, /obj/stool )) var/obj/stool/O = A if( !O.anchored ) var/atom/target = get_edge_target_turf(O, pick(alldirs)) if( O.buckled_guy ) boutput( O.buckled_guy, "The [O] shoots off due to being unsecured!" ) O.unbuckle() if( target ) SPAWN_DBG(0) O.throw_at( target, 25, 1 )//dear god I am sorry in advance for doing this else if(istype( A, /mob )) var/mob/M = A shake_camera(M, 32, 4) M.addOverlayComposition(/datum/overlayComposition/shuttle_warp) if (!isturf(M.loc) || !isliving(M) || isintangible(M)) continue SPAWN_DBG(1 DECI SECOND) var/bonus_stun = 0 if (ishuman(M)) var/mob/living/carbon/human/H = M bonus_stun = (H && H.buckled && H.on_chair) //DEBUG_MESSAGE("[M] is human and bonus_stun is [bonus_stun]") if (!M.buckled || bonus_stun) M.changeStatus("stunned", 2 SECONDS) M.changeStatus("weakened", 2 SECONDS) if (prob(50) || bonus_stun) var/atom/target = get_edge_target_turf(M, pick(alldirs)) SPAWN_DBG(0) if (target) if (M.buckled) M.buckled.unbuckle() M.throw_at(target, 25, 1) if (bonus_stun) M.changeStatus("paralysis", 60) M.playsound_local(target, 'sound/impact_sounds/Flesh_Break_1.ogg', 50, 1) M.show_text("You are thrown off the chair! [prob(50) ? "Standing on that during takeoff was a terrible idea!" : null]", "red") if (!bonus_stun) M.show_text("You are thrown about as the shuttle launches due to not being securely buckled in!", "red") for (var/turf/O in start_location) if (istype(O, map_turf)) new transit_turf(O) var/area/shuttle_particle_spawn/particle_spawn = locate(/area/shuttle_particle_spawn) in world if (particle_spawn) particle_spawn.start_particles() #ifdef UNDERWATER_MAP end_location.force_fullbright = 1 end_location.update_fullbright() #endif SPAWN_DBG(0) var/shuttle_dir = map_settings ? map_settings.escape_dir : EAST // default to cog2 direction because EH for (var/obj/landmark/L in escape_pod_success) if (L.dir != shuttle_dir) escape_pod_success -= L //leave behind only landmarks that match our dir DEBUG_MESSAGE("Now moving shuttle!") start_location.move_contents_to(end_location, map_turf) DEBUG_MESSAGE("Done moving shuttle!") settimeleft(SHUTTLETRANSITTIME) boutput(world, "The Emergency Shuttle has left for CentCom! It will arrive in [timeleft()/60] minute[s_es(timeleft()/60)]!") world << csound("sound/misc/shuttle_enroute.ogg") //online = 0 return 1 if (SHUTTLE_LOC_TRANSIT) if (timeleft>0) return 0 else var/area/start_location = locate(map_settings ? map_settings.escape_transit : /area/shuttle/escape/transit) var/area/end_location = locate(map_settings ? map_settings.escape_centcom : /area/shuttle/escape/centcom) for (var/mob/M in start_location) M.removeOverlayComposition(/datum/overlayComposition/shuttle_warp) M.removeOverlayComposition(/datum/overlayComposition/shuttle_warp/ew) var/door_type = map_settings ? map_settings.ext_airlocks : /obj/machinery/door/airlock/external for (var/obj/machinery/door/D in start_location) if (istype(D, door_type)) D.set_density(0) D.locked = 0 D.update_icon() for (var/turf/G in start_location) if (istype(G, transit_turf)) new centcom_turf(G) start_location.move_contents_to(end_location, transit_turf) boutput(world, "The Emergency Shuttle has arrived at CentCom!") world << csound("sound/misc/shuttle_centcom.ogg") logTheThing("station", null, null, "The emergency shuttle has arrived at Centcom.") online = 0 #ifdef UNDERWATER_MAP end_location.force_fullbright = 1 end_location.update_fullbright() #endif location = SHUTTLE_LOC_RETURNED return 1 else return 1 #else // standard shuttle departure - immediately arrives at centcom if (SHUTTLE_LOC_STATION) if (timeleft>0) return 0 else location = SHUTTLE_LOC_RETURNED var/area/start_location = locate(map_settings ? map_settings.escape_station : /area/shuttle/escape/station) var/area/end_location = locate(map_settings ? map_settings.escape_centcom : /area/shuttle/escape/centcom) for (var/turf/O in start_location) if (istype(O, transit_turf)) new centcom_turf(O) start_location.move_contents_to(end_location, map_turf) boutput(world, "The Emergency Shuttle has arrived at CentCom!") logTheThing("station", null, null, "The emergency shuttle has arrived at Centcom.") online = 0 #ifdef UNDERWATER_MAP end_location.force_fullbright = 1 end_location.update_fullbright() #endif return 1 else return 1 #endif