diff --git a/code/controllers/subsystems/records.dm b/code/controllers/subsystems/records.dm index 14b6db03a9d..093df3e192a 100644 --- a/code/controllers/subsystems/records.dm +++ b/code/controllers/subsystems/records.dm @@ -7,6 +7,7 @@ SUBSYSTEM_DEF(records) var/list/warrants var/list/viruses + var/list/shuttle_assignments var/list/shuttle_manifests var/list/excluded_fields @@ -23,6 +24,10 @@ SUBSYSTEM_DEF(records) for(var/type in localized_fields) localized_fields[type] = compute_localized_field(type) + for(var/shuttle in SSatlas.current_map.shuttle_manifests) + var/datum/record/shuttle_assignment/A = new /datum/record/shuttle_assignment(shuttle) + shuttle_assignments += A + InitializeCitizenships() InitializeReligions() InitializeAccents() @@ -34,6 +39,7 @@ SUBSYSTEM_DEF(records) records_locked = list() warrants = list() viruses = list() + shuttle_assignments = list() shuttle_manifests = list() excluded_fields = list() localized_fields = list() @@ -108,6 +114,8 @@ SUBSYSTEM_DEF(records) viruses += record if(/datum/record/shuttle_manifest) shuttle_manifests += record + if(/datum/record/shuttle_assignment) + shuttle_assignments += record onCreate(record) /datum/controller/subsystem/records/proc/update_record(var/datum/record/record) @@ -123,6 +131,8 @@ SUBSYSTEM_DEF(records) viruses |= record if(/datum/record/shuttle_manifest) shuttle_manifests |= record + if(/datum/record/shuttle_assignment) + shuttle_assignments |= record onModify(record) /datum/controller/subsystem/records/proc/remove_record(var/datum/record/record) @@ -138,6 +148,8 @@ SUBSYSTEM_DEF(records) viruses *= record if(/datum/record/shuttle_manifest) shuttle_manifests -= record + if(/datum/record/shuttle_assignment) + shuttle_assignments -= record onDelete(record) qdel(record) diff --git a/code/datums/records.dm b/code/datums/records.dm index c508c9cddde..c2ee8b572bf 100644 --- a/code/datums/records.dm +++ b/code/datums/records.dm @@ -254,10 +254,25 @@ var/warrant_uid = 0 //Manifest record /datum/record/shuttle_manifest name = "Unknown" - var/shuttle = "Unknown" cmp_field = "name" + var/shuttle = "Unknown" + var/pilot = FALSE + var/lead = FALSE var/shuttle_uid = 0 /datum/record/shuttle_manifest/New() ..() id = shuttle_uid++ + +/datum/record/shuttle_assignment + var/shuttle + var/destination = "Unknown" + var/heading = 0 + var/mission = "Exploration" + var/departure_time + var/return_time + cmp_field = "destination" + +/datum/record/shuttle_assignment/New(var/for_shuttle) + . = ..() + shuttle = for_shuttle diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index 0dec9b7bd4b..b74aa2786af 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -177,3 +177,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) wrist_radio = /obj/item/device/radio/headset/wrist/command clipon_radio = /obj/item/device/radio/headset/wrist/clip/command messengerbag = /obj/item/storage/backpack/messenger/com + + tab_pda = /obj/item/modular_computer/handheld/pda/bridge + wristbound = /obj/item/modular_computer/handheld/wristbound/preset/pda/bridge + tablet = /obj/item/modular_computer/handheld/preset/bridge diff --git a/code/modules/modular_computers/computers/subtypes/preset_handheld.dm b/code/modules/modular_computers/computers/subtypes/preset_handheld.dm index a71d19c53f8..6087059b8f9 100644 --- a/code/modules/modular_computers/computers/subtypes/preset_handheld.dm +++ b/code/modules/modular_computers/computers/subtypes/preset_handheld.dm @@ -135,6 +135,9 @@ // Command / Misc +/obj/item/modular_computer/handheld/preset/bridge + _app_preset_type = /datum/modular_computer_app_presets/bridge + /obj/item/modular_computer/handheld/preset/command _app_preset_type = /datum/modular_computer_app_presets/command diff --git a/code/modules/modular_computers/computers/subtypes/preset_pda.dm b/code/modules/modular_computers/computers/subtypes/preset_pda.dm index 5037dfa31f5..2a02523446e 100644 --- a/code/modules/modular_computers/computers/subtypes/preset_pda.dm +++ b/code/modules/modular_computers/computers/subtypes/preset_pda.dm @@ -130,6 +130,9 @@ // Command / Misc +/obj/item/modular_computer/handheld/pda/bridge + _app_preset_type = /datum/modular_computer_app_presets/bridge + /obj/item/modular_computer/handheld/pda/command _app_preset_type = /datum/modular_computer_app_presets/command icon_add = "h" diff --git a/code/modules/modular_computers/computers/subtypes/preset_wristbound.dm b/code/modules/modular_computers/computers/subtypes/preset_wristbound.dm index 01232388d07..acf51a1a073 100644 --- a/code/modules/modular_computers/computers/subtypes/preset_wristbound.dm +++ b/code/modules/modular_computers/computers/subtypes/preset_wristbound.dm @@ -55,6 +55,9 @@ _app_preset_type = /datum/modular_computer_app_presets/research icon_state = "wristbound-tox" +/obj/item/modular_computer/handheld/wristbound/preset/advanced/bridge + _app_preset_type = /datum/modular_computer_app_presets/bridge + /obj/item/modular_computer/handheld/wristbound/preset/advanced/command _app_preset_type = /datum/modular_computer_app_presets/command icon_state = "wristbound-h" @@ -220,6 +223,9 @@ // Command / Misc +/obj/item/modular_computer/handheld/wristbound/preset/pda/bridge + _app_preset_type = /datum/modular_computer_app_presets/bridge + /obj/item/modular_computer/handheld/wristbound/preset/pda/command _app_preset_type = /datum/modular_computer_app_presets/command icon_add = "h" diff --git a/code/modules/modular_computers/file_system/programs/app_presets_crew.dm b/code/modules/modular_computers/file_system/programs/app_presets_crew.dm index a18f92e9a2a..bd5074872a0 100644 --- a/code/modules/modular_computers/file_system/programs/app_presets_crew.dm +++ b/code/modules/modular_computers/file_system/programs/app_presets_crew.dm @@ -106,6 +106,20 @@ ) return flatten_list(_prg_list) +/datum/modular_computer_app_presets/bridge + name = "bridge" + display_name = "Bridge" + description = "Contains the most common bridge programs" + available = TRUE + +/datum/modular_computer_app_presets/bridge/return_install_programs(obj/item/modular_computer/comp) + var/list/_prg_list = list( + COMPUTER_APP_PRESET_SYSTEM, + COMPUTER_APP_PRESET_HORIZON_CIVILIAN, + new /datum/computer_file/program/away_manifest(comp), + ) + return flatten_list(_prg_list) + /datum/modular_computer_app_presets/command name = "command" display_name = "Command" diff --git a/code/modules/modular_computers/file_system/programs/command/away_manifest.dm b/code/modules/modular_computers/file_system/programs/command/away_manifest.dm index e0b7a18bac6..c282d4cbde5 100644 --- a/code/modules/modular_computers/file_system/programs/command/away_manifest.dm +++ b/code/modules/modular_computers/file_system/programs/command/away_manifest.dm @@ -18,18 +18,38 @@ if(active_record) data["active_record"] = list( "name" = active_record.name, + "id" = active_record.id, "shuttle" = active_record.shuttle, - "id" = active_record.id + "pilot" = active_record.pilot, + "lead" = active_record.lead ) else var/list/allshuttles = list() + var/list/allassignments = list() for (var/datum/record/shuttle_manifest/m in SSrecords.shuttle_manifests) allshuttles += list(list( "name" = m.name, + "id" = m.id, "shuttle" = m.shuttle, - "id" = m.id + "pilot" = m.pilot, + "lead" = m.lead )) + for(var/datum/record/shuttle_assignment/a in SSrecords.shuttle_assignments) + if(!a.departure_time) + a.departure_time = worldtime2text() + if(!a.return_time) + a.return_time = worldtime2text(world.time + 1 HOUR) + allassignments += list(list( + "shuttle" = a.shuttle, + "destination" = a.destination, + "heading" = a.heading, + "mission" = a.mission, + "departure_time" = a.departure_time, + "return_time" = a.return_time + )) + data["shuttles"] = SSatlas.current_map.shuttle_manifests data["shuttle_manifest"] = allshuttles + data["shuttle_assignments"] = allassignments data["active_record"] = null return data @@ -89,7 +109,7 @@ var/names = list() for(var/datum/record/general/r in SSrecords.records) names += r.name - var/newname = sanitize(input(usr, "Please enter name.") as null|anything in names) + var/newname = sanitize(tgui_input_list(usr, "Please select name.", "Name select", names, active_record.name)) if(!computer.use_check_and_message(usr)) if(!newname) return @@ -97,15 +117,79 @@ if("editentrynamecustom") . = TRUE - var/newname = sanitize(input("Please enter name.") as null|text) + var/newname = sanitize(tgui_input_text(usr, "Please enter name.", "Name entry", active_record.name)) if(!computer.use_check_and_message(usr)) if(!newname) return active_record.name = newname + if("editentryshuttle") . = TRUE - var/newshuttle = sanitize(input("Please enter shuttle.") as null|anything in list("SCCV Canary", "SCCV Intrepid", "SCCV Spark")) + var/newshuttle = tgui_input_list(usr, "Please select shuttle.", "Shuttle select", SSatlas.current_map.shuttle_manifests, active_record.shuttle) if(!computer.use_check_and_message(usr)) if(!newshuttle) return active_record.shuttle = newshuttle + + if("editdestination") + for(var/datum/record/shuttle_assignment/a in SSrecords.shuttle_assignments) + if(a.shuttle == params["editdestination"]) + var/new_dest = sanitize(tgui_input_text(usr, "Please enter destination.", "Destination entry", a.destination)) + if(!computer.use_check_and_message(usr)) + if(!new_dest) + return + a.destination = new_dest + + if("editheading") + for(var/datum/record/shuttle_assignment/a in SSrecords.shuttle_assignments) + if(a.shuttle == params["editheading"]) + var/new_head = floor(tgui_input_number(usr, "Please enter heading.", "Heading entry", a.heading, 359, 0)) + if(new_head < 0 || new_head > 359 || !new_head) + new_head = 0 + if(!computer.use_check_and_message(usr)) + a.heading = new_head + + if("editmission") + for(var/datum/record/shuttle_assignment/a in SSrecords.shuttle_assignments) + if(a.shuttle == params["editmission"]) + var/new_mis = tgui_input_list(usr, "Please select mission.", "Mission select", SSatlas.current_map.shuttle_missions, a.mission) + if(!computer.use_check_and_message(usr)) + if(!new_mis) + return + a.mission = new_mis + + if("editdeparturetime") + for(var/datum/record/shuttle_assignment/a in SSrecords.shuttle_assignments) + if(a.shuttle == params["editdeparturetime"]) + var/new_depart = sanitize(tgui_input_text(usr, "Please enter new departure time.", "Departure time entry", a.departure_time)) + if(!computer.use_check_and_message(usr)) + if(!new_depart) + return + a.departure_time = new_depart + + if("editreturntime") + for(var/datum/record/shuttle_assignment/a in SSrecords.shuttle_assignments) + if(a.shuttle == params["editreturntime"]) + var/new_return = sanitize(tgui_input_text(usr, "Please enter new return time.", "Return time entry", a.departure_time)) + if(!computer.use_check_and_message(usr)) + if(!new_return) + return + a.return_time = new_return + + if("editlead") + for(var/datum/record/shuttle_manifest/m in SSrecords.shuttle_manifests) + if(m.id == text2num(params["editlead"])) + m.lead = !m.lead + if(m.lead) + for(var/datum/record/shuttle_manifest/other in SSrecords.shuttle_manifests) // There can be only one + if(other.shuttle == m.shuttle && other.lead && other != m) + other.lead = FALSE + + if("editpilot") + for(var/datum/record/shuttle_manifest/m in SSrecords.shuttle_manifests) + if(m.id == text2num(params["editpilot"])) + m.pilot = !m.pilot + if(m.pilot) + for(var/datum/record/shuttle_manifest/other in SSrecords.shuttle_manifests) + if(other.shuttle == m.shuttle && other.pilot && other != m) + other.pilot = FALSE diff --git a/html/changelogs/shuttlemanifestexpansion.yml b/html/changelogs/shuttlemanifestexpansion.yml new file mode 100644 index 00000000000..bd9923c28ee --- /dev/null +++ b/html/changelogs/shuttlemanifestexpansion.yml @@ -0,0 +1,7 @@ +author: Sparky_hotdog + +delete-after: True + +changes: + - rscadd: "Updated the shuttle manifest program to include extra details such as shuttle destination, heading, mission and departure & return times, as well as the assignment of a mission leader and shuttle pilot." + - rscadd: "Added the shuttle manifest program to Bridge Crew PDAs at round start." diff --git a/maps/_common/mapsystem/map.dm b/maps/_common/mapsystem/map.dm index fe9d9495297..2d1f1d0b69b 100644 --- a/maps/_common/mapsystem/map.dm +++ b/maps/_common/mapsystem/map.dm @@ -123,6 +123,17 @@ var/allow_borgs_to_leave = FALSE //this controls if borgs can leave the station or ship without exploding var/area/warehouse_basearea //this controls where the cargospawner tries to populate warehouse items + /** + * A list of the shuttles on this map, used by the Shuttle Manifest program to populate itself. + * Formatted with the shuttle name as an index, followed by a list containing the color and icon to be used for the shuttle's drop down + * On the manifest. i.e. "SCCV Intrepid" = list("color" = "purple", "icon" = "compass") + */ + var/list/shuttle_manifests = list() + /** + * A list of the missions shuttles can select for their assignment in the Shuttle Manifest program. + */ + var/list/shuttle_missions = list() + /datum/map/New() if(!map_levels) map_levels = station_levels.Copy() diff --git a/maps/sccv_horizon/code/sccv_horizon.dm b/maps/sccv_horizon/code/sccv_horizon.dm index 345cca8f02b..f18d3f0636b 100644 --- a/maps/sccv_horizon/code/sccv_horizon.dm +++ b/maps/sccv_horizon/code/sccv_horizon.dm @@ -141,6 +141,12 @@ warehouse_basearea = /area/operations/storage + shuttle_manifests = list( + "SCCV Canary" = list("color" = "blue", "icon" = "binoculars"), + "SCCV Intrepid" = list("color" = "purple", "icon" = "compass"), + "SCCV Spark" = list("color" = "brown", "icon" = "gem")) + shuttle_missions = list("Exploration", "Research", "Prospecting", "Transport", "Combat", "Rescue", "Training") + /datum/map/sccv_horizon/send_welcome() var/obj/effect/overmap/visitable/ship/horizon = SSshuttle.ship_by_type(/obj/effect/overmap/visitable/ship/sccv_horizon) diff --git a/tgui/packages/tgui/interfaces/AwayShuttleManifest.tsx b/tgui/packages/tgui/interfaces/AwayShuttleManifest.tsx index ac053295ff3..770112e25b4 100644 --- a/tgui/packages/tgui/interfaces/AwayShuttleManifest.tsx +++ b/tgui/packages/tgui/interfaces/AwayShuttleManifest.tsx @@ -3,16 +3,42 @@ import { Button, LabeledList, NoticeBox, Section, Flex, Table, Collapsible } fro import { NtosWindow } from '../layouts'; export type AwayShuttleData = { + shuttles: { name: Shuttle[] }; shuttle_manifest: ShuttleCrew[]; active_record: ShuttleCrew; + shuttle_assignments: ShuttleAssignment[]; +}; + +type Shuttle = { + color: string; + icon: string; }; type ShuttleCrew = { name: string; shuttle: string; + pilot: Boolean; + lead: Boolean; id: number; }; +type ShuttleAssignment = { + shuttle: string; + destination: string; + heading: number; + mission: string; + departure_time: string; + return_time: string; +}; + +const num2bearing = function (num) { + let bearing = '000'; + if (num < 10) bearing = '00' + num; + else if (num < 100) bearing = '0' + num; + else bearing = num; + return bearing; +}; + export const AwayShuttleManifest = (props, context) => { const { act, data } = useBackend(context); @@ -79,111 +105,166 @@ export const AllShuttles = (props, context) => { return ( <> - -
act('addentry')} /> - }> - {data.shuttle_manifest && data.shuttle_manifest.length ? ( - - - - Name - - {data.shuttle_manifest - .filter((m) => m.shuttle === 'SCCV Canary') - .map((ShuttleCrew) => ( - - - -
+ + Shuttle Assignment: + + {data.shuttle_assignments + .filter((m) => m.shuttle === name) + .map((ShuttleAssignment) => ( + + + + Destination: +
+
+
+
act('addentry')} + /> + }> + {data.shuttle_manifest && data.shuttle_manifest.length ? ( + + + + Crew Onboard: - ))} -
-
- ) : ( - No crew detected. - )} -
-
- -
act('addentry')} /> - }> - {data.shuttle_manifest && data.shuttle_manifest.length ? ( - - - - Name - - {data.shuttle_manifest - .filter((m) => m.shuttle === 'SCCV Intrepid') - .map((ShuttleCrew) => ( - - - -
-
- ) : ( - No crew detected. - )} -
-
- -
act('addentry')} /> - }> - {data.shuttle_manifest && data.shuttle_manifest.length ? ( - - - - Name - - {data.shuttle_manifest - .filter((m) => m.shuttle === 'SCCV Spark') - .map((ShuttleCrew) => ( - - - -
-
- ) : ( - No crew detected. - )} -
-
+ {data.shuttle_manifest + .filter((m) => m.shuttle === name) + .map((ShuttleCrew) => ( + + + +