diff --git a/code/__DEFINES/dropships.dm b/code/__DEFINES/dropships.dm
index f7df570a2864..d53e7c68d8db 100644
--- a/code/__DEFINES/dropships.dm
+++ b/code/__DEFINES/dropships.dm
@@ -10,3 +10,8 @@
#define DROPSHIP_MIN_AUTO_DELAY 10 SECONDS
#define DROPSHIP_AUTO_RETRY_COOLDOWN 20 SECONDS
#define DROPSHIP_MEDEVAC_COOLDOWN 20 SECONDS
+
+//Hatches states
+#define SHUTTLE_DOOR_BROKEN -1
+#define SHUTTLE_DOOR_UNLOCKED 0
+#define SHUTTLE_DOOR_LOCKED 1
diff --git a/code/game/machinery/doors/multi_tile.dm b/code/game/machinery/doors/multi_tile.dm
index f943cd696897..4214a7234085 100644
--- a/code/game/machinery/doors/multi_tile.dm
+++ b/code/game/machinery/doors/multi_tile.dm
@@ -241,10 +241,43 @@
no_panel = 1
not_weldable = 1
var/queen_pryable = TRUE
+ var/obj/docking_port/mobile/marine_dropship/linked_dropship
+
/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/ex_act(severity)
return
+/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/attackby(obj/item/item, mob/user)
+ if(HAS_TRAIT(item, TRAIT_TOOL_MULTITOOL))
+ var/direction
+ switch(id)
+ if("starboard_door")
+ direction = "starboard"
+ if("port_door")
+ direction = "port"
+ if("aft_door")
+ direction = "aft"
+ if(!linked_dropship || !linked_dropship.door_control.door_controllers[direction])
+ return ..()
+ var/datum/door_controller/single/control = linked_dropship.door_control.door_controllers[direction]
+ if (control.status != SHUTTLE_DOOR_BROKEN)
+ return ..()
+ if(!skillcheck(user, SKILL_ENGINEER, SKILL_ENGINEER_ENGI))
+ to_chat(user, SPAN_WARNING("You don't seem to understand how to restore a remote connection to [src]."))
+ return
+ if(user.action_busy)
+ return
+
+ to_chat(user, SPAN_WARNING("You begin to restore the remote connection to [src]."))
+ if(!do_after(user, 5 SECONDS, INTERRUPT_ALL, BUSY_ICON_BUILD))
+ to_chat(user, SPAN_WARNING("You fail to restore a remote connection to [src]."))
+ return
+ unlock(TRUE)
+ close(FALSE)
+ control.status = SHUTTLE_DOOR_UNLOCKED
+ to_chat(user, SPAN_WARNING("You successfully restored the remote connection to [src]."))
+ return
+ ..()
/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/unlock()
if(is_reserved_level(z))
@@ -261,11 +294,26 @@
if(!locked)
return ..()
+ if(xeno.action_busy)
+ return
+
to_chat(xeno, SPAN_NOTICE("You try and force the doors open"))
if(do_after(xeno, 3 SECONDS, INTERRUPT_ALL, BUSY_ICON_HOSTILE))
unlock(TRUE)
open(1)
lock(TRUE)
+ var/direction
+ switch(id)
+ if("starboard_door")
+ direction = "starboard"
+ if("port_door")
+ direction = "port"
+ if("aft_door")
+ direction = "aft"
+ if(linked_dropship && linked_dropship.door_control.door_controllers[direction])
+ var/datum/door_controller/single/control = linked_dropship.door_control.door_controllers[direction]
+ control.status = SHUTTLE_DOOR_BROKEN
+
/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/ds1
name = "\improper Alamo cargo door"
diff --git a/code/modules/shuttle/computers/escape_pod_computer.dm b/code/modules/shuttle/computers/escape_pod_computer.dm
index c45ac7d56102..dd621c83eaec 100644
--- a/code/modules/shuttle/computers/escape_pod_computer.dm
+++ b/code/modules/shuttle/computers/escape_pod_computer.dm
@@ -55,7 +55,7 @@
.["docking_status"] = STATE_LAUNCHED
var/obj/structure/machinery/door/door = shuttle.door_handler.doors[1]
.["door_state"] = door.density
- .["door_lock"] = shuttle.door_handler.is_locked
+ .["door_lock"] = shuttle.door_handler.status == SHUTTLE_DOOR_LOCKED
.["can_delay"] = TRUE//launch_status[2]
.["launch_without_evac"] = launch_without_evac
diff --git a/code/modules/shuttle/helpers.dm b/code/modules/shuttle/helpers.dm
index 6b29f155582e..9c8d817ec237 100644
--- a/code/modules/shuttle/helpers.dm
+++ b/code/modules/shuttle/helpers.dm
@@ -19,7 +19,7 @@
if(!door_controllers[direction])
var/datum/door_controller/single/new_controller = new()
new_controller.label = label
- new_controller.is_locked = FALSE
+ new_controller.status = SHUTTLE_DOOR_UNLOCKED
door_controllers[direction] = new_controller
var/datum/door_controller/single/controller = door_controllers[direction]
@@ -29,12 +29,12 @@
if(direction == "all")
for(var/i in door_controllers)
var/datum/door_controller/single/control = door_controllers[i]
- if(!control.is_locked)
+ if(control.status != SHUTTLE_DOOR_LOCKED)
return FALSE
return TRUE
if(door_controllers[direction])
var/datum/door_controller/single/single_controller = door_controllers[direction]
- return single_controller.is_locked
+ return single_controller.status == SHUTTLE_DOOR_LOCKED
else
WARNING("Direction [direction] does not exist.")
return FALSE
@@ -60,9 +60,9 @@
for(var/direction in door_controllers)
var/datum/door_controller/single/controller = door_controllers[direction]
- var/list/door_data = list("id" = direction, "value" = controller.is_locked)
+ var/list/door_data = list("id" = direction, "value" = controller.status)
. += list(door_data)
- if(!controller.is_locked)
+ if(controller.status == SHUTTLE_DOOR_UNLOCKED)
all_locked = FALSE
var/list/door_data = list("id" = "all", "value" = all_locked)
@@ -74,7 +74,7 @@
/datum/door_controller/single
var/label = "dropship"
var/list/doors = list()
- var/is_locked = FALSE
+ var/status = SHUTTLE_DOOR_UNLOCKED
/datum/door_controller/single/Destroy(force, ...)
. = ..()
@@ -93,23 +93,29 @@
if("close")
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/structure/machinery/door/airlock, close))
if("force-lock")
+ if (status == SHUTTLE_DOOR_BROKEN)
+ continue
INVOKE_ASYNC(src, PROC_REF(lockdown_door), door)
- is_locked = TRUE
+ status = SHUTTLE_DOOR_LOCKED
if("lock")
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/structure/machinery/door/airlock, lock))
- is_locked = TRUE
+ if (status != SHUTTLE_DOOR_BROKEN)
+ status = SHUTTLE_DOOR_LOCKED
if("unlock")
INVOKE_ASYNC(door, TYPE_PROC_REF(/obj/structure/machinery/door/airlock, unlock))
- is_locked = FALSE
+ if (status != SHUTTLE_DOOR_BROKEN)
+ status = SHUTTLE_DOOR_UNLOCKED
if("force-lock-launch")
if(asynchronous)
INVOKE_ASYNC(src, PROC_REF(lockdown_door_launch), door)
else
lockdown_door_launch(door)
- is_locked = TRUE
+ if (status != SHUTTLE_DOOR_BROKEN)
+ status = SHUTTLE_DOOR_LOCKED
if("force-unlock")
INVOKE_ASYNC(src, PROC_REF(force_lock_open_door), door)
- is_locked = FALSE
+ if (status != SHUTTLE_DOOR_BROKEN)
+ status = SHUTTLE_DOOR_UNLOCKED
else
CRASH("Unknown door command [action]")
diff --git a/code/modules/shuttle/shuttles/dropship.dm b/code/modules/shuttle/shuttles/dropship.dm
index ce9ba7c623bb..e9f9e50e5798 100644
--- a/code/modules/shuttle/shuttles/dropship.dm
+++ b/code/modules/shuttle/shuttles/dropship.dm
@@ -43,6 +43,9 @@
door_control.add_door(air, "port")
if("aft_door")
door_control.add_door(air, "aft")
+ var/obj/structure/machinery/door/airlock/multi_tile/almayer/dropshiprear/hatch = air
+ if(istype(hatch))
+ hatch.linked_dropship = src
RegisterSignal(src, COMSIG_DROPSHIP_ADD_EQUIPMENT, PROC_REF(add_equipment))
RegisterSignal(src, COMSIG_DROPSHIP_REMOVE_EQUIPMENT, PROC_REF(remove_equipment))
diff --git a/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx b/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx
index 2ae9a17fe35f..679b78efe843 100644
--- a/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx
+++ b/tgui/packages/tgui/interfaces/DropshipFlightControl.tsx
@@ -3,9 +3,17 @@ import { Window } from '../layouts';
import { Box, Button, Flex, Icon, ProgressBar, Section, Stack } from '../components';
import { LaunchButton, CancelLaunchButton, DisabledScreen, InFlightCountdown, LaunchCountdown, NavigationProps, ShuttleRecharge, DockingPort } from './NavigationShuttle';
+const DoorStatusEnum = {
+ SHUTTLE_DOOR_BROKEN: -1,
+ SHUTTLE_DOOR_UNLOCKED: 0,
+ SHUTTLE_DOOR_LOCKED: 1,
+} as const;
+
+type DoorStatusEnums = typeof DoorStatusEnum[keyof typeof DoorStatusEnum];
+
interface DoorStatus {
id: string;
- value: 0 | 1;
+ value: DoorStatusEnums;
}
interface AutomatedControl {
@@ -40,7 +48,7 @@ const DropshipDoorControl = () => {
.filter((x) => x.id === 'all')
.map((x) => (
<>
- {x.value === 0 && (
+ {x.value === DoorStatusEnum.SHUTTLE_DOOR_UNLOCKED && (
)}
- {x.value === 1 && (
+ {x.value === DoorStatusEnum.SHUTTLE_DOOR_LOCKED && (