diff --git a/code/controllers/Processes/shuttles/emergency.dm b/code/controllers/Processes/shuttles/emergency.dm
index ee5cd947df5..46ad051f3bd 100644
--- a/code/controllers/Processes/shuttles/emergency.dm
+++ b/code/controllers/Processes/shuttles/emergency.dm
@@ -19,7 +19,6 @@
return 0 //shuttle master not initialized
shuttle_master.emergency = src
- log_to_dd("EMERGENCY FUCKING DOCKING PORT CREATED GOD FUCKING DAMNIT")
return 1
/obj/docking_port/mobile/emergency/timeLeft(divisor)
diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm
index c2dcd3270a0..bad613cdae9 100644
--- a/code/game/machinery/computer/shuttle.dm
+++ b/code/game/machinery/computer/shuttle.dm
@@ -1,75 +1,97 @@
-/obj/machinery/computer/shuttle
- name = "shuttle control conse"
+/obj/machinery/computer/emergency_shuttle
+ name = "emergency shuttle console"
desc = "For shuttle control."
- icon_keyboard = "tech_key"
icon_screen = "shuttle"
- var/auth_need = 3.0
- var/list/authorized = list( )
-
- light_color = LIGHT_COLOR_CYAN
+ icon_keyboard = "tech_key"
+ var/auth_need = 3
+ var/list/authorized = list()
- attackby(var/obj/item/weapon/card/W as obj, var/mob/user as mob, params)
- if(stat & (BROKEN|NOPOWER)) return
- if ((!( istype(W, /obj/item/weapon/card) ) || !( ticker ) || emergency_shuttle.location() || !( user ))) return
- if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
- if (istype(W, /obj/item/device/pda))
- var/obj/item/device/pda/pda = W
- W = pda.id
- if (!W:access) //no access
- user << "The access level of [W:registered_name]\'s card is not high enough. "
- return
-
- var/list/cardaccess = W:access
- if(!istype(cardaccess, /list) || !cardaccess.len) //no access
- user << "The access level of [W:registered_name]\'s card is not high enough. "
- return
-
- if(!(access_heads in W:access)) //doesn't have this access
- user << "The access level of [W:registered_name]\'s card is not high enough. "
- return 0
-
- var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort")
- if(emergency_shuttle.location() && user.get_active_hand() != W)
- return 0
- switch(choice)
- if("Authorize")
- src.authorized -= W:registered_name
- src.authorized += W:registered_name
- if (src.auth_need - src.authorized.len > 0)
- message_admins("[key_name_admin(user.client)] has authorized early shuttle launch ",0,1)
- log_game("[key_name(user)] has authorized early shuttle launch in ([x],[y],[z])")
- world << text("\blue Alert: [] authorizations needed until shuttle is launched early", src.auth_need - src.authorized.len)
- else
- message_admins("[key_name_admin(user.client)] has launched the emergency shuttle before launch.",0,1)
- log_game("[key_name(user)] has launched the emergency shuttle before launch in ([x],[y],[z]).")
- world << "\blue Alert: Shuttle launch time shortened to 10 seconds!"
- emergency_shuttle.set_launch_countdown(10)
- //src.authorized = null
- qdel(src.authorized)
- src.authorized = list( )
-
- if("Repeal")
- src.authorized -= W:registered_name
- world << text("\blue Alert: [] authorizations needed until shuttle is launched early", src.auth_need - src.authorized.len)
-
- if("Abort")
- world << "\blue All authorizations to shortening time for shuttle launch have been revoked!"
- src.authorized.len = 0
- src.authorized = list( )
+/obj/machinery/computer/emergency_shuttle/attackby(obj/item/weapon/card/W, mob/user, params)
+ if(stat & (BROKEN|NOPOWER)) return
+ if(!istype(W, /obj/item/weapon/card))
return
+ if(shuttle_master.emergency.mode != SHUTTLE_DOCKED)
+ return
+ if(!user)
+ return
+ if(shuttle_master.emergency.timeLeft() < 11)
+ return
+ if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
+ if (istype(W, /obj/item/device/pda))
+ var/obj/item/device/pda/pda = W
+ W = pda.id
+ if (!W:access) //no access
+ user << "The access level of [W:registered_name]\'s card is not high enough. "
+ return
- emag_act(mob/user as mob)
- if (!emagged)
- var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel")
+ var/list/cardaccess = W:access
+ if(!istype(cardaccess, /list) || !cardaccess.len) //no access
+ user << "The access level of [W:registered_name]\'s card is not high enough. "
+ return
- if(!emagged && !emergency_shuttle.location())
- switch(choice)
- if("Launch")
- message_admins("[key_name_admin(user.client)] has emagged the emergency shuttle before launch.",0,1)
- log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) before launch.")
- world << "\blue Alert: Shuttle launch time shortened to 10 seconds!"
- emergency_shuttle.set_launch_countdown(10)
- emagged = 1
- if("Cancel")
- return
+ if(!(access_heads in W:access)) //doesn't have this access
+ user << "The access level of [W:registered_name]\'s card is not high enough. "
+ return 0
+
+ var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort")
+ if(shuttle_master.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != W)
+ return 0
+
+ var/seconds = shuttle_master.emergency.timeLeft()
+ if(seconds <= 10)
+ return 0
+
+ switch(choice)
+ if("Authorize")
+ if(!authorized.Find(W:registered_name))
+ authorized += W:registered_name
+ if(auth_need - authorized.len > 0)
+ message_admins("[key_name_admin(user.client)](?) (FLW) has authorized early shuttle launch ",0,1)
+ log_game("[key_name(user)] has authorized early shuttle launch in ([x],[y],[z])")
+ minor_announcement.Announce("[auth_need - authorized.len] more authorization(s) needed until shuttle is launched early")
+ else
+ message_admins("[key_name_admin(user.client)](?) (FLW) has launched the emergency shuttle [seconds] seconds before launch.",0,1)
+ log_game("[key_name(user)] has launched the emergency shuttle in ([x],[y],[z]) [seconds] seconds before launch.")
+ minor_announcement.Announce("The emergency shuttle will launch in 10 seconds")
+ shuttle_master.emergency.setTimer(100)
+
+ if("Repeal")
+ if(authorized.Remove(W:registered_name))
+ minor_announcement.Announce("[auth_need - authorized.len] authorizations needed until shuttle is launched early")
+
+ if("Abort")
+ if(authorized.len)
+ minor_announcement.Announce("All authorizations to launch the shuttle early have been revoked.")
+ authorized.Cut()
+
+/obj/machinery/computer/emergency_shuttle/emag_act(mob/user)
+ if(!emagged && shuttle_master.emergency.mode == SHUTTLE_DOCKED)
+ var/time = shuttle_master.emergency.timeLeft()
+ message_admins("[key_name_admin(user.client)](?) (FLW) has emagged the emergency shuttle [time] seconds before launch.",0,1)
+ log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.")
+ minor_announcement.Announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:")
+ shuttle_master.emergency.setTimer(100)
+ emagged = 1
+
+/obj/machinery/computer/supplycomp
+ name = "supply shuttle console"
+ desc = "Used to order supplies."
+ icon_screen = "supply"
+ req_access = list(access_cargo)
+ circuit = /obj/item/weapon/circuitboard/supplycomp
+ var/temp = null
+ var/reqtime = 0 //Cooldown for requisitions - Quarxink
+ var/hacked = 0
+ var/can_order_contraband = 0
+ var/last_viewed_group = "categories"
+
+
+/obj/machinery/computer/ordercomp
+ name = "supply ordering console"
+ desc = "Used to order supplies from cargo staff."
+ icon_screen = "request"
+ circuit = /obj/item/weapon/circuitboard/ordercomp
+ var/temp = null
+ var/reqtime = 0 //Cooldown for requisitions - Quarxink
+ var/last_viewed_group = "categories"
\ No newline at end of file
diff --git a/code/game/machinery/computer/shuttle_tg.dm b/code/game/machinery/computer/shuttle_tg.dm
deleted file mode 100644
index ddc35c6f5af..00000000000
--- a/code/game/machinery/computer/shuttle_tg.dm
+++ /dev/null
@@ -1,97 +0,0 @@
-/obj/machinery/computer/emergency_shuttle
- name = "emergency shuttle console"
- desc = "For shuttle control."
- icon_screen = "shuttle"
- icon_keyboard = "tech_key"
- var/auth_need = 3
- var/list/authorized = list()
-
-
-/obj/machinery/computer/emergency_shuttle/attackby(obj/item/weapon/card/W, mob/user, params)
- if(stat & (BROKEN|NOPOWER)) return
- if(!istype(W, /obj/item/weapon/card))
- return
- if(shuttle_master.emergency.mode != SHUTTLE_DOCKED)
- return
- if(!user)
- return
- if(shuttle_master.emergency.timeLeft() < 11)
- return
- if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
- if (istype(W, /obj/item/device/pda))
- var/obj/item/device/pda/pda = W
- W = pda.id
- if (!W:access) //no access
- user << "The access level of [W:registered_name]\'s card is not high enough. "
- return
-
- var/list/cardaccess = W:access
- if(!istype(cardaccess, /list) || !cardaccess.len) //no access
- user << "The access level of [W:registered_name]\'s card is not high enough. "
- return
-
- if(!(access_heads in W:access)) //doesn't have this access
- user << "The access level of [W:registered_name]\'s card is not high enough. "
- return 0
-
- var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort")
- if(shuttle_master.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != W)
- return 0
-
- var/seconds = shuttle_master.emergency.timeLeft()
- if(seconds <= 10)
- return 0
-
- switch(choice)
- if("Authorize")
- if(!authorized.Find(W:registered_name))
- authorized += W:registered_name
- if(auth_need - authorized.len > 0)
- message_admins("[key_name_admin(user.client)](?) (FLW) has authorized early shuttle launch ",0,1)
- log_game("[key_name(user)] has authorized early shuttle launch in ([x],[y],[z])")
- minor_announcement.Announce("[auth_need - authorized.len] more authorization(s) needed until shuttle is launched early")
- else
- message_admins("[key_name_admin(user.client)](?) (FLW) has launched the emergency shuttle [seconds] seconds before launch.",0,1)
- log_game("[key_name(user)] has launched the emergency shuttle in ([x],[y],[z]) [seconds] seconds before launch.")
- minor_announcement.Announce("The emergency shuttle will launch in 10 seconds")
- shuttle_master.emergency.setTimer(100)
-
- if("Repeal")
- if(authorized.Remove(W:registered_name))
- minor_announcement.Announce("[auth_need - authorized.len] authorizations needed until shuttle is launched early")
-
- if("Abort")
- if(authorized.len)
- minor_announcement.Announce("All authorizations to launch the shuttle early have been revoked.")
- authorized.Cut()
-
-/obj/machinery/computer/emergency_shuttle/emag_act(mob/user)
- if(!emagged && shuttle_master.emergency.mode == SHUTTLE_DOCKED)
- var/time = shuttle_master.emergency.timeLeft()
- message_admins("[key_name_admin(user.client)](?) (FLW) has emagged the emergency shuttle [time] seconds before launch.",0,1)
- log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.")
- minor_announcement.Announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:")
- shuttle_master.emergency.setTimer(100)
- emagged = 1
-
-/obj/machinery/computer/supplycomp
- name = "supply shuttle console"
- desc = "Used to order supplies."
- icon_screen = "supply"
- req_access = list(access_cargo)
- circuit = /obj/item/weapon/circuitboard/supplycomp
- var/temp = null
- var/reqtime = 0 //Cooldown for requisitions - Quarxink
- var/hacked = 0
- var/can_order_contraband = 0
- var/last_viewed_group = "categories"
-
-
-/obj/machinery/computer/ordercomp
- name = "supply ordering console"
- desc = "Used to order supplies from cargo staff."
- icon_screen = "request"
- circuit = /obj/item/weapon/circuitboard/ordercomp
- var/temp = null
- var/reqtime = 0 //Cooldown for requisitions - Quarxink
- var/last_viewed_group = "categories"
\ No newline at end of file
diff --git a/code/modules/shuttle/README.md b/code/modules/shuttle/README.md
new file mode 100644
index 00000000000..0d090e8e5d7
--- /dev/null
+++ b/code/modules/shuttle/README.md
@@ -0,0 +1,148 @@
+
+
+- [Shuttle system](#shuttle-system)
+ - [Introduction](#introduction)
+ - [Docking ports](#docking-ports)
+ - [/obj/docking_port](#objdockingport)
+ - [Variables](#variables)
+ - [/obj/docking_port/mobile](#objdockingportmobile)
+ - [/obj/docking_port/mobile](#objdockingportmobile)
+ - [Modifications](#modifications)
+ - [Shuttle Controller](#shuttle-controller)
+ - [Airlocks](#airlocks)
+ - [Initialization](#initialization)
+
+
+# Shuttle system
+## Introduction
+This folder belongs to the "shuttle" system. The shuttle system is used to control the
+"Shuttles" on the map, which are, at their core, a rectangular area of turfs that "move".
+
+The shuttle system is comprised of two primary files.
+[`shuttle.dm`](http://github.com/ParadiseSS13/Paradise/blob/master/code/modules/shuttle/shuttle.dm),
+which contains the primary code, and
+[`shuttles.dm`](http://github.com/ParadiseSS13/Paradise/blob/master/code/controllers/Process/shuttles.dm)
+which contains the back-end controller system.
+There are a few other files, but it isn't worth noting on.
+
+Shuttles are used for many purposes, including the end of rounds, so it's important to
+understand them.
+
+## Docking ports
+### /obj/docking_port
+The `/obj/docking_port` type is the primary component of the shuttle system. Almost all of
+the shuttle system is controlled by the docking ports, the only thing that isn't, really,
+is the shuttle manager, which manages, you guessed it, the docking ports.
+
+Docking ports are split into two main types: `/obj/docking_port/stationary`, and
+`/obj/docking_port/mobile`, but they share a few variables and procs defined at the
+`/obj/docking_port` level.
+
+#### Variables
+`id`: This variable is used for any plain-text references to the docking port. It should
+always be lowercase.
+
+`width`, `height`: The width and height variables are **absolute** value variables which
+define the bounding box of the docking port. It is very important to note that these are
+different from the `dwidth` and `dheight` in terms of how they are counted. As they are
+absolute representations of the size of the bounding box, they need to be equal to the
+amount of turfs on the side of the bounding box. An easy way to think of it is, if you
+start at the very corner piece, you would start the count at `1` from that corner piece,
+IE, you move 1 turf in any direction, it would be `2`.
+
+A crude ASCII example:
+```
+||D|||
+```
+Would be classed by the values `width` = 6, `height` = 1.
+
+It is important to note that bounding boxes are *always* rectangular. However, shuttles
+are allowed to be any shape they so wish, as anything that matches the `turf_type` of
+stationary docking ports will not be moved with the shuttle- by default, this is equal to
+`/turf/space`.
+Another quick example of this:
+```
+ |||
+ |||
+ |||
+ |||||
+||||||D
+|||||||
+||| |||
+```
+This, even though it is not exactly a rectangle, would be classified by the values
+`width` = `7`, `height` = `7`.
+
+
+`dwidth`, `dheight`: The relative offset of the docking port to the bounding box. These
+values are calculated **relative** to the bounding box. The values are counted from the
+bottom left corner of the bounding box, **relative** to the direction of the docking port.
+The "bottom left corner" changes depending on the direction of the docking port object.
+so a docking port **facing north** that looks something like this:
+
+```
+|||
+|||
+|||D|
+|||||
+```
+
+Would have a `dwidth` value of `3`, and a `dheight` value of `1`.
+A docking port **facing south** that looks like this:
+
+```
+||||||
+|||D||
+ ||||
+```
+
+Would have a `dwidth` value of `2`, and a `dheight` value of `1`
+
+
+### /obj/docking_port/mobile
+`/obj/docking_port/mobile`, or, "Mobile" docking ports are used to define and control the
+movement of the shuttle chunks. The "Mobile" docking port moves with the shuttle, and is
+essentially attached to it. A "Mobile" docking port only moves to predefined positions
+on the map, referred to as "Stationary" docking ports.
+
+### /obj/docking_port/mobile
+`/obj/docking_port/stationary`, or "Stationary" docking ports are used as predefined
+references for where "Mobile" docking ports may move. "Stationary" docking ports do not
+move unless something has gone horribly wrong. They are essentially static points in
+space. Going into details, whenever a "Mobile" docking port "moves", it registers with the
+stationary docking port that it was requested to move to, and moves itself to it. It is
+important to note that docking ports will switch direction on the fly, and a "Stationary"
+docking port not matching the initial direction of the "Mobile" docking port will cause
+the entire shuttle to be rotated in order for the "Mobile" docking port to face the same
+direction as the "Stationary" docking port.
+
+
+## Modifications
+There are three main differences between -tg-station13's shuttle system and the one in
+use on Paradise, and none are very complex.
+
+### Shuttle Controller
+This is a very simple change. On -tg-station13, the shuttle controller is referenced by a
+variable named `SSShuttle`. On Paradise, due to controller naming conventions, it is
+instead named `shuttle_master`.
+
+### Airlocks
+The biggest modification comes in the form of how docking ports interact with airlocks.
+With -tg-station13's base code, any door on the shuttle will be closed, and any door
+directly next to the mobile docking port will be closed off of the shuttle.
+
+In Paradise, however, when a mobile docking port undocks from the stationary docking port,
+it will look for any door in the machine list who's `id_tag` variable matches the
+stationary docking port's `id` variable. When it finds these doors, it will close *and*
+bolt the doors shut. Any airlocks on the shuttle will be closed as per usual, but any
+airlocks within the shuttle with the `id_tag` of `s_docking_airlock` will also be bolted,
+and will stay bolted until the shuttle has exited transit space.
+
+### Initialization
+In -tg-station13's shuttle system, all docking ports register with the shuttle controller
+on `New()`. However, as Paradise uses a different system for the shuttle controller, it is
+not yet created when `New()` is called.
+
+To fix this issue, all docking ports will not initialize automatically on `New()`.
+Instead, they are manually initialized by the shuttle controller when it is created, via
+a proc called `initialize()`.
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index e49fd1b2d8d..b657eb91c9c 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -1,5 +1,5 @@
//use this define to highlight docking port bounding boxes (ONLY FOR DEBUG USE)
-#define DOCKING_PORT_HIGHLIGHT
+//#define DOCKING_PORT_HIGHLIGHT
//NORTH default dir
/obj/docking_port
@@ -142,7 +142,6 @@
return 0
shuttle_master.stationary += src
- log_to_dd("stationary dock initialized [src], [id]") //SHUTTLE-WIP DEBUG
if(!id)
id = "[shuttle_master.stationary.len]"
if(name == "dock")
diff --git a/paradise.dme b/paradise.dme
index 32b6a1c5c96..9d877166a09 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -10,7 +10,7 @@
#define DEBUG
// END_PREFERENCES
// BEGIN_INCLUDE
-#include "_maps\metastation.dm"
+#include "_maps\cyberiad.dm"
#include "code\_compile_options.dm"
#include "code\hub.dm"
#include "code\stylesheet.dm"
@@ -500,7 +500,7 @@
#include "code\game\machinery\computer\robot.dm"
#include "code\game\machinery\computer\salvage_ship.dm"
#include "code\game\machinery\computer\security.dm"
-#include "code\game\machinery\computer\shuttle_tg.dm"
+#include "code\game\machinery\computer\shuttle.dm"
#include "code\game\machinery\computer\skills.dm"
#include "code\game\machinery\computer\specops_shuttle.dm"
#include "code\game\machinery\computer\station_alert.dm"