diff --git a/code/modules/shuttle/custom_shuttle.dm b/code/modules/shuttle/custom_shuttle.dm
index 8047e972db..e9a5ca4688 100644
--- a/code/modules/shuttle/custom_shuttle.dm
+++ b/code/modules/shuttle/custom_shuttle.dm
@@ -35,67 +35,63 @@
. = ..()
. += distance_multiplier < 1 ? "Bluespace shortcut module installed. Route is [distance_multiplier]x the original length." : ""
-/obj/machinery/computer/custom_shuttle/ui_interact(mob/user)
+/obj/machinery/computer/custom_shuttle/ui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "CustomShuttleConsole", name)
+ ui.open()
+
+/obj/machinery/computer/custom_shuttle/ui_data(mob/user)
+ var/list/data = list()
var/list/options = params2list(possible_destinations)
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
- var/dat = "[M ? "Current Location : [M.getStatusText()]" : "Shuttle link required."]
"
+ data["docked_location"] = M ? M.get_status_text_tgui() : null
if(M)
- dat += "Run Flight Calculations
"
- dat += "Shuttle Data
"
- dat += "Shuttle Mass: [calculated_mass/10]tons
"
- dat += "Engine Force: [calculated_dforce]kN ([calculated_engine_count] engines)
"
- dat += "Sublight Speed: [calculated_speed]ms-1
"
- dat += calculated_speed < 1 ? "INSUFFICIENT ENGINE POWER
" : ""
- dat += calculated_non_operational_thrusters > 0 ? "Warning: [calculated_non_operational_thrusters] thrusters offline.
" : ""
- dat += "Fuel Consumption: [calculated_consumption]units per distance
"
- dat += "Engine Cooldown: [calculated_cooldown]s
"
- var/destination_found
+ calculateStats(FALSE, 0, TRUE)
+ data["ship_name"] = M.area_type ? M.area_type:name : "ERROR"
+ data["shuttle_mass"] = calculated_mass/10
+ data["engine_force"] = calculated_dforce
+ data["engines"] = calculated_engine_count
+ data["calculated_speed"] = calculated_speed
+ data["damaged_engines"] = calculated_non_operational_thrusters
+ data["calculated_consumption"] = calculated_consumption
+ data["calculated_cooldown"] = calculated_cooldown
+ data["locations"] = list()
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
if(!options.Find(S.id))
continue
- if(!M.check_dock(S, silent=TRUE))
+ if(!M.check_dock(S, silent = TRUE))
continue
- if(calculated_speed == 0)
- break
- destination_found = TRUE
- var/dist = round(calculateDistance(S))
- dat += "Target [S.name] (Dist: [dist] | Fuel Cost: [round(dist * calculated_consumption)] | Time: [round(dist / calculated_speed)])
"
- if(!destination_found)
- dat += "No valid destinations
"
- dat += "
[targetLocation ? "Target Location : [targetLocation]" : "No Target Location"]"
- dat += "
Initate Flight
"
- dat += "Close"
+ var/list/location_data = list(
+ id = S.id,
+ name = S.name,
+ dist = round(calculateDistance(S))
+ )
+ data["locations"] += list(location_data)
+ data["destination"] = targetLocation
+ return data
- popup = new(user, "computer", M ? M.name : "shuttle", 350, 450)
- popup.set_content("[dat]")
- popup.open()
-
-/obj/machinery/computer/custom_shuttle/Topic(href, href_list)
- if(..())
+/obj/machinery/computer/custom_shuttle/ui_act(action, params)
+ . = ..()
+ if(.)
return
- usr.set_machine(src)
- src.add_fingerprint(usr)
if(!allowed(usr))
to_chat(usr, "Access denied.")
return
- if(href_list["calculate"])
- calculateStats()
- ui_interact(usr)
- return
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
if(!M)
+ to_chat(usr, "Shuttle Link Required.")
return
if(M.launch_status == ENDGAME_LAUNCHED)
return
- if(href_list["setloc"])
- SetTargetLocation(href_list["setloc"])
- ui_interact(usr)
- return
- else if(href_list["fly"])
- Fly()
- ui_interact(usr)
- return
+
+ switch(action)
+ if("setloc")
+ SetTargetLocation(params["setloc"])
+ if("fly")
+ Fly()
+ return
/obj/machinery/computer/custom_shuttle/proc/calculateDistance(var/obj/docking_port/stationary/port)
var/deltaX = port.x - x
diff --git a/tgui/packages/tgui/interfaces/CustomShuttleConsole.js b/tgui/packages/tgui/interfaces/CustomShuttleConsole.js
new file mode 100644
index 0000000000..f6d76754a7
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/CustomShuttleConsole.js
@@ -0,0 +1,136 @@
+/* eslint-disable react/jsx-closing-tag-location */
+import { useBackend } from '../backend';
+import { Box, Button, Flex, Icon, LabeledList, Modal, Section, Table, Tooltip } from '../components';
+import { Window } from '../layouts';
+
+export const CustomShuttleConsole = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ docked_location,
+ ship_name = "ERROR",
+ shuttle_mass = 0,
+ engine_force = 0,
+ engines = 0,
+ calculated_speed = 0,
+ calculated_non_operational_thrusters = 0,
+ calculated_consumption = 0,
+ calculated_cooldown = 0,
+ locations = [],
+ destination = null,
+ } = data;
+ return (
+
+
+
+ {!docked_location ? (
+
+
+
+
+
+
+ {"Shuttle Link Required."}
+
+
+
+ ) : (
+ <>
+ {ship_name}
+
+
+
+ {docked_location}
+
+
+ {shuttle_mass / 10}ton{shuttle_mass !== 1 ? "s" : null}
+
+
+ {engine_force}Kn ({engines} engine{engines !== 1 ? "s" : null})
+
+
+ {calculated_speed}ms{-1} {calculated_speed < 1 ? : null}
+
+ {calculated_non_operational_thrusters.len
+ ?
+ {calculated_non_operational_thrusters} thruster{calculated_non_operational_thrusters !== 1 ? "s are" : " is"} not operational.
+
+ : null}
+
+ {calculated_consumption} unit{calculated_consumption !== 1 ? "s" : null} per travel
+
+
+ {calculated_cooldown}s
+
+
+
+
+ {locations.length===0 && (
+
+ No valid destinations
+
+ ) || (
+
+ {locations.map(location => (
+
+ {location.name} | ({location.dist}m) |
+
+ |
+
+ ))}
+
+ )}
+
+
+
+ >
+ )}
+
+
+
+ );
+};
+
+const getLocationNameById = (locations, id) => {
+ return locations?.find(location => location.id === id)?.name;
+};
+
+const getLocationIdByName = (locations, name) => {
+ return locations?.find(location => location.name === name)?.id;
+};
+
+const STATUS_COLOR_KEYS = {
+ "In Transit": "good",
+ "Idle": "average",
+ "Igniting": "average",
+ "Recharging": "average",
+ "Missing": "bad",
+ "Unauthorized Access": "bad",
+ "Locked": "bad",
+};