From 5f5f15f0c239a9bbde5cba33cca3838d3730f481 Mon Sep 17 00:00:00 2001
From: ihatethisengine <115417687+ihatethisengine@users.noreply.github.com>
Date: Tue, 27 Feb 2024 04:30:48 +0300
Subject: [PATCH] Pried dropship's hatches cannot be locked again (#5808)
# About the pull request
https://github.com/cmss13-devs/cmss13/pull/5015 this PR allowed a lot
better control of the doors for POs, but as it turned out Queen cannot
disable door control from the outside anymore. So it led to dropships to
be basically unenterable if PO controls the cockpit. Now pried open
hatch cannot be remotely locked anymore. Engineer can fix the door by
multitooling.
# Explain why it's good for the game
Xenos can assault dropships again.
# Testing Photographs and Procedure
Screenshots & Videos
![2024-02-25_21-02-58](https://github.com/cmss13-devs/cmss13/assets/115417687/5f38c206-e26c-43fe-b247-cb2dd407797a)
# Changelog
:cl: ihatethisengine
balance: Pried open dropship hatches cannot be remotely locked anymore
/:cl:
---------
Co-authored-by: Drathek <76988376+Drulikar@users.noreply.github.com>
---
code/__DEFINES/dropships.dm | 5 ++
code/game/machinery/doors/multi_tile.dm | 48 +++++++++++++++++++
.../shuttle/computers/escape_pod_computer.dm | 2 +-
code/modules/shuttle/helpers.dm | 28 ++++++-----
code/modules/shuttle/shuttles/dropship.dm | 3 ++
.../tgui/interfaces/DropshipFlightControl.tsx | 21 ++++++--
6 files changed, 90 insertions(+), 17 deletions(-)
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 ed2874fc3505..9e734a0152e7 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 557e443f08a2..d0f27d869741 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 && (