From fa56a1014984844c71253b788f64f61cd6c1566b Mon Sep 17 00:00:00 2001 From: Iajret <8430839+Iajret@users.noreply.github.com> Date: Sat, 20 Jun 2026 00:52:44 +0300 Subject: [PATCH] FaxBond app for bonding with your fax (fax message subscription app) (#96467) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## About The Pull Request Adds an up that allows you to subscribe to any fax. Heads start with one by default and they are subscribed to their office fax upon joining. Later part involved creation of fax subtype specific to a head. So i decided to also make those as a required map item for the purposes of CI.
UI изображение
its pretty simplistic, but i am not a UI designer, sorry ## Why It's Good For The Game It really sucks when you wait for someones message but they never respond to it because apparently they never visit their office and never saw a paper over their fax if even if they responded, by the time you get an answer you already forgot about it anyway. In general, it makes paperwork experience relating to faxes more enjoyable (probably) ## Changelog :cl: add: added a FaxBond app. Everyone can download it and use it on a fax of their choice to be notified when it receives a message. Heads of staff come with it preinstalled and automatically subscribed to a fax inside their office. /:cl: --- .../CatwalkStation/CatwalkStation_2023.dmm | 35 ++---- .../map_files/Deltastation/DeltaStation2.dmm | 35 ++---- .../map_files/IceBoxStation/IceBoxStation.dmm | 35 ++---- _maps/map_files/MetaStation/MetaStation.dmm | 35 ++---- .../map_files/NebulaStation/NebulaStation.dmm | 35 ++---- _maps/map_files/tramstation/tramstation.dmm | 35 ++---- _maps/map_files/wawastation/wawastation.dmm | 35 ++---- code/__DEFINES/dcs/signals/signals_fax.dm | 1 + .../computers/item/role_tablet_presets.dm | 17 +++ .../file_system/programs/faxnotif.dm | 119 ++++++++++++++++++ code/modules/paperwork/fax.dm | 36 ++++++ code/modules/unit_tests/required_map_items.dm | 1 + tgstation.dme | 2 + tgui/packages/tgui/interfaces/NtosFaxBond.tsx | 85 +++++++++++++ 14 files changed, 310 insertions(+), 196 deletions(-) create mode 100644 code/__DEFINES/dcs/signals/signals_fax.dm create mode 100644 code/modules/modular_computers/file_system/programs/faxnotif.dm create mode 100644 tgui/packages/tgui/interfaces/NtosFaxBond.tsx diff --git a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm index 2b43ae43fb3..168d97dfb35 100644 --- a/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm +++ b/_maps/map_files/CatwalkStation/CatwalkStation_2023.dmm @@ -6147,10 +6147,7 @@ "bCC" = ( /obj/machinery/status_display/evac/directional/north, /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Captain's Office"; - name = "Captain's Fax Machine" - }, +/obj/machinery/fax/heads/captain, /turf/open/floor/wood/large, /area/station/command/heads_quarters/captain/private) "bCH" = ( @@ -18908,11 +18905,8 @@ dir = 8 }, /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Quartermaster's Office"; - name = "Quartermaster's Fax Machine" - }, /obj/machinery/firealarm/directional/west, +/obj/machinery/fax/heads/qm, /turf/open/floor/wood/parquet, /area/station/command/heads_quarters/qm) "eYe" = ( @@ -24244,13 +24238,10 @@ /area/station/service/janitor) "gqc" = ( /obj/structure/table/reinforced/rglass, -/obj/machinery/fax{ - fax_name = "Chief Engineer's Office"; - name = "Chief Engineer's Fax Machine" - }, /obj/effect/turf_decal/siding/yellow/end{ dir = 8 }, +/obj/machinery/fax/heads/ce, /turf/open/floor/engine, /area/station/command/heads_quarters/ce) "gqj" = ( @@ -29012,12 +29003,9 @@ /turf/open/floor/wood, /area/station/command/corporate_showroom) "hIg" = ( -/obj/machinery/fax{ - fax_name = "Head of Personnel's Office"; - name = "Head of Personnel's Fax Machine" - }, /obj/structure/table/wood, /obj/machinery/newscaster/directional/east, +/obj/machinery/fax/heads/hop, /turf/open/floor/wood/tile, /area/station/command/heads_quarters/hop) "hIj" = ( @@ -63250,10 +63238,7 @@ /area/station/commons/fitness/recreation) "qPq" = ( /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Head of Security's Office"; - name = "Head of Security's Fax Machine" - }, +/obj/machinery/fax/heads/hos, /turf/open/floor/wood, /area/station/command/heads_quarters/hos) "qPs" = ( @@ -69362,10 +69347,7 @@ /obj/effect/turf_decal/trimline/dark_blue/filled/line{ dir = 1 }, -/obj/machinery/fax{ - fax_name = "Chief Medical Officer's Office"; - name = "Chief Medical Officer's Fax Machine" - }, +/obj/machinery/fax/heads/cmo, /turf/open/floor/holofloor/dark, /area/station/command/heads_quarters/cmo) "syb" = ( @@ -83445,11 +83427,8 @@ /area/station/engineering/atmos/office) "wha" = ( /obj/structure/cable, -/obj/machinery/fax{ - fax_name = "Research Director's Office"; - name = "Research Director's Fax Machine" - }, /obj/structure/table, +/obj/machinery/fax/heads/rd, /turf/open/floor/wood, /area/station/command/heads_quarters/rd) "whi" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 6b9115f4b99..6031abb9832 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -12832,12 +12832,9 @@ "deW" = ( /obj/machinery/computer/security/telescreen/entertainment/directional/north, /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Chief Medical Officer's Office"; - name = "Chief Medical Officer's Fax Machine" - }, /obj/effect/turf_decal/tile/blue/opposingcorners, /obj/machinery/light/cold/directional/north, +/obj/machinery/fax/heads/cmo, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) "deX" = ( @@ -14882,13 +14879,10 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/table/reinforced, -/obj/machinery/fax{ - fax_name = "Research Director's Office"; - name = "Research Director's Fax Machine" - }, /obj/effect/turf_decal/tile/purple{ dir = 8 }, +/obj/machinery/fax/heads/rd, /turf/open/floor/iron/white, /area/station/command/heads_quarters/rd) "dGs" = ( @@ -16747,11 +16741,8 @@ "edS" = ( /obj/machinery/firealarm/directional/south, /obj/structure/table/reinforced, -/obj/machinery/fax{ - fax_name = "Chief Engineer's Office"; - name = "Chief Engineer's Fax Machine" - }, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/fax/heads/ce, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) "edW" = ( @@ -28965,13 +28956,10 @@ /area/space/nearstation) "haq" = ( /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Quartermaster's Office"; - name = "Quartermaster's Fax Machine" - }, /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 1 }, +/obj/machinery/fax/heads/qm, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) "haw" = ( @@ -38301,12 +38289,9 @@ /area/station/service/library/lounge) "jst" = ( /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Head of Security's Office"; - name = "Head of Security's Fax Machine" - }, /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/nanotrasen/directional/north, +/obj/machinery/fax/heads/hos, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) "jsL" = ( @@ -44901,10 +44886,7 @@ "lbt" = ( /obj/structure/table/wood, /obj/machinery/newscaster/directional/east, -/obj/machinery/fax{ - fax_name = "Head of Personnel's Office"; - name = "Head of Personnel's Fax Machine" - }, +/obj/machinery/fax/heads/hop, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) "lbu" = ( @@ -74913,11 +74895,8 @@ /area/station/security/checkpoint/medical/medsci) "swj" = ( /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Captain's Office"; - name = "Captain's Fax Machine" - }, /obj/structure/sign/nanotrasen/directional/west, +/obj/machinery/fax/heads/captain, /turf/open/floor/wood, /area/station/command/heads_quarters/captain) "swn" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index a31a47131c1..93372524aa3 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -865,10 +865,7 @@ "anP" = ( /obj/structure/table, /obj/machinery/light_switch/directional/north, -/obj/machinery/fax{ - fax_name = "Research Director's Office"; - name = "Research Director's Fax Machine" - }, +/obj/machinery/fax/heads/rd, /turf/open/floor/iron/white/side{ dir = 1 }, @@ -1958,12 +1955,9 @@ "aBi" = ( /obj/effect/turf_decal/trimline/blue/filled/line, /obj/structure/table/glass, -/obj/machinery/fax{ - fax_name = "Chief Medical Officer's Office"; - name = "Chief Medical Officer's Fax Machine" - }, /obj/machinery/light/cold/directional/south, /obj/machinery/firealarm/directional/south, +/obj/machinery/fax/heads/cmo, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) "aBE" = ( @@ -5590,10 +5584,7 @@ /area/station/service/chapel) "bAT" = ( /obj/structure/table/reinforced, -/obj/machinery/fax{ - fax_name = "Chief Engineer's Office"; - name = "Chief Engineer's Fax Machine" - }, +/obj/machinery/fax/heads/ce, /turf/open/floor/iron, /area/station/command/heads_quarters/ce) "bAX" = ( @@ -17424,10 +17415,7 @@ /area/station/service/hydroponics) "eUn" = ( /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Head of Security's Office"; - name = "Head of Security's Fax Machine" - }, +/obj/machinery/fax/heads/hos, /turf/open/floor/wood/large, /area/station/command/heads_quarters/hos) "eUx" = ( @@ -60778,13 +60766,10 @@ /area/icemoon/underground/explored) "rdf" = ( /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Captain's Office"; - name = "Captain's Fax Machine" - }, /obj/effect/turf_decal/siding/wood{ dir = 8 }, +/obj/machinery/fax/heads/captain, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/captain) "rdg" = ( @@ -77884,10 +77869,7 @@ dir = 4 }, /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Head of Personnel's Office"; - name = "Head of Personnel's Fax Machine" - }, +/obj/machinery/fax/heads/hop, /turf/open/floor/iron, /area/station/command/heads_quarters/hop) "vYq" = ( @@ -81692,13 +81674,10 @@ /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Quartermaster's Office"; - name = "Quartermaster's Fax Machine" - }, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 }, +/obj/machinery/fax/heads/qm, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) "xen" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 316f1b0f0f2..611118b44a2 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -8540,13 +8540,10 @@ /area/station/maintenance/port/aft) "cYc" = ( /obj/structure/table/reinforced, -/obj/machinery/fax{ - fax_name = "Chief Engineer's Office"; - name = "Chief Engineer's Fax Machine" - }, /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 }, +/obj/machinery/fax/heads/ce, /turf/open/floor/iron, /area/station/command/heads_quarters/ce) "cYx" = ( @@ -22558,10 +22555,6 @@ dir = 1 }, /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Quartermaster"; - name = "Quartermaster's Fax Machine" - }, /obj/structure/disposalpipe/segment{ dir = 8 }, @@ -22573,6 +22566,7 @@ /obj/effect/mapping_helpers/requests_console/assistance, /obj/effect/mapping_helpers/requests_console/information, /obj/effect/mapping_helpers/requests_console/ore_update, +/obj/machinery/fax/heads/qm, /turf/open/floor/wood/large, /area/station/command/heads_quarters/qm) "hQu" = ( @@ -23730,10 +23724,7 @@ /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Head of Personnel's Office"; - name = "Head of Personnel's Fax Machine" - }, +/obj/machinery/fax/heads/hop, /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) "iiL" = ( @@ -27716,11 +27707,8 @@ /area/station/medical/chemistry) "jxv" = ( /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Captain's Office"; - name = "Captain's Fax Machine" - }, /obj/structure/window/reinforced/spawner/directional/south, +/obj/machinery/fax/heads/captain, /turf/open/floor/wood, /area/station/command/heads_quarters/captain/private) "jxM" = ( @@ -47634,10 +47622,7 @@ /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/table/wood, /obj/structure/cable, -/obj/machinery/fax{ - fax_name = "Head of Security's Office"; - name = "Head of Security's Fax Machine" - }, +/obj/machinery/fax/heads/hos, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) "qmi" = ( @@ -62039,13 +62024,10 @@ "vgZ" = ( /obj/structure/table/glass, /obj/structure/cable, -/obj/machinery/fax{ - fax_name = "Chief Medical Officer's Office"; - name = "Chief Medical Officer's Fax Machine" - }, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 1 }, +/obj/machinery/fax/heads/cmo, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) "vhb" = ( @@ -70099,13 +70081,10 @@ /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Research Director's Office"; - name = "Research Director's Fax Machine" - }, /obj/effect/turf_decal/tile/neutral/opposingcorners{ dir = 1 }, +/obj/machinery/fax/heads/rd, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/rd) "xPx" = ( diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index 4237d32c715..0760f2c0f9a 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -15557,10 +15557,7 @@ /area/station/service/library/printer) "cqG" = ( /obj/structure/table/reinforced/rglass, -/obj/machinery/fax{ - fax_name = "Research Director's Office"; - name = "Research Director's Fax Machine" - }, +/obj/machinery/fax/heads/rd, /turf/open/floor/carpet/purple, /area/station/command/heads_quarters/rd) "cqH" = ( @@ -19865,12 +19862,9 @@ /turf/open/floor/iron/dark, /area/station/engineering/atmos) "cXo" = ( -/obj/machinery/fax{ - fax_name = "Chief Engineer's Office"; - name = "Chief Engineer's Fax Machine" - }, /obj/item/disk/computer/engineering, /obj/structure/table/reinforced/rglass, +/obj/machinery/fax/heads/ce, /turf/open/floor/carpet/orange, /area/station/command/heads_quarters/ce) "cXs" = ( @@ -22743,11 +22737,8 @@ }, /obj/effect/turf_decal/siding/wood, /obj/structure/table/wood, -/obj/machinery/fax{ - fax_name = "Detective's Office"; - name = "Detective's Fax Machine" - }, /obj/structure/detectiveboard/directional/north, +/obj/machinery/fax/heads/hos, /turf/open/floor/wood/large, /area/station/security/detectives_office) "dsq" = ( @@ -67552,10 +67543,7 @@ /obj/item/folder/blue, /obj/item/clothing/neck/stethoscope, /obj/item/clothing/glasses/hud/health, -/obj/machinery/fax{ - fax_name = "Chief Medical Officer's Office"; - name = "Chief Medical Officer's Fax Machine" - }, +/obj/machinery/fax/heads/cmo, /turf/open/floor/carpet/blue, /area/station/command/heads_quarters/cmo) "jWn" = ( @@ -68761,10 +68749,7 @@ /area/station/hallway/secondary/service) "kfr" = ( /obj/structure/table/reinforced/rglass, -/obj/machinery/fax{ - fax_name = "Captain's Office"; - name = "Captain's Fax Machine" - }, +/obj/machinery/fax/heads/captain, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain) "kfu" = ( @@ -74259,10 +74244,7 @@ /area/station/engineering/break_room) "kRR" = ( /obj/structure/table/reinforced/rglass, -/obj/machinery/fax{ - fax_name = "Head of Personnel's Office"; - name = "Head of Personnel's Fax Machine" - }, +/obj/machinery/fax/heads/hop, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/hop) "kSl" = ( @@ -111360,11 +111342,8 @@ /area/station/command/heads_quarters/hop) "quR" = ( /obj/structure/table/reinforced/rglass, -/obj/machinery/fax{ - fax_name = "Quartermaster's Office"; - name = "Quartermaster's Fax Machine" - }, /obj/item/paperwork/cargo, +/obj/machinery/fax/heads/qm, /turf/open/floor/carpet, /area/station/command/heads_quarters/qm) "quT" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 7e9d064585a..acaaaec1f6f 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -5541,11 +5541,8 @@ /area/station/science/xenobiology) "aPm" = ( /obj/structure/table/glass, -/obj/machinery/fax{ - name = "Chief Medical Officer's Fax Machine"; - fax_name = "Chief Medical Officer's Office" - }, /obj/effect/turf_decal/tile/blue/fourcorners, +/obj/machinery/fax/heads/cmo, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) "aPs" = ( @@ -31137,10 +31134,6 @@ /area/station/science/ordnance/storage) "jXF" = ( /obj/structure/table, -/obj/machinery/fax{ - name = "Research Director's Fax Machine"; - fax_name = "Research Director's Office" - }, /obj/machinery/button/door/directional/south{ name = "Science Lockdown Toggle"; pixel_x = -6; @@ -31167,6 +31160,7 @@ id = "misclab"; req_access = list("xenobiology") }, +/obj/machinery/fax/heads/rd, /turf/open/floor/iron/cafeteria, /area/station/command/heads_quarters/rd) "jXG" = ( @@ -55621,10 +55615,7 @@ /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 }, -/obj/machinery/fax{ - name = "Chief Engineer's Fax Machine"; - fax_name = "Chief Engineer's Office" - }, +/obj/machinery/fax/heads/ce, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) "suR" = ( @@ -58017,10 +58008,7 @@ "toY" = ( /obj/structure/table/wood, /obj/structure/reagent_dispensers/wall/peppertank/directional/east, -/obj/machinery/fax{ - name = "Head of Security's Fax Machine"; - fax_name = "Head of Security's Office" - }, +/obj/machinery/fax/heads/hos, /turf/open/floor/carpet, /area/station/command/heads_quarters/hos) "tpm" = ( @@ -67340,10 +67328,7 @@ dir = 8 }, /obj/structure/sign/calendar/directional/west, -/obj/machinery/fax{ - name = "Quartermaster's Fax Machine"; - fax_name = "Quartermaster's Office" - }, +/obj/machinery/fax/heads/qm, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) "wuE" = ( @@ -68259,10 +68244,7 @@ /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/table/wood, /obj/item/radio/intercom/directional/east, -/obj/machinery/fax{ - name = "Captain's Fax Machine"; - fax_name = "Captain's Office" - }, +/obj/machinery/fax/heads/captain, /turf/open/floor/wood, /area/station/command/heads_quarters/captain) "wKm" = ( @@ -70871,11 +70853,8 @@ "xNl" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/table/wood, -/obj/machinery/fax{ - name = "Head of Personnel's Fax Machine"; - fax_name = "Head of Personnel's Office" - }, /obj/machinery/light/warm/directional/north, +/obj/machinery/fax/heads/hop, /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) "xNm" = ( diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index a723bb3f2a8..bcc10a68c16 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -29571,14 +29571,11 @@ /turf/open/floor/plating, /area/station/maintenance/department/cargo) "kki" = ( -/obj/machinery/fax{ - fax_name = "Quartermaster's Office"; - name = "Quartermaster's Fax Machine" - }, /obj/effect/turf_decal/siding/wood{ dir = 6 }, /obj/structure/table/wood/fancy/orange, +/obj/machinery/fax/heads/qm, /turf/open/floor/wood, /area/station/command/heads_quarters/qm) "kkA" = ( @@ -30294,11 +30291,8 @@ /area/station/science/genetics) "kvk" = ( /obj/structure/table, -/obj/machinery/fax{ - fax_name = "Chief Medical Officer's Office"; - name = "Chief Medical Officer's Fax Machine" - }, /obj/machinery/light_switch/directional/north, +/obj/machinery/fax/heads/cmo, /turf/open/floor/iron/dark/textured, /area/station/command/heads_quarters/cmo) "kvo" = ( @@ -44652,16 +44646,13 @@ name = "shutter control"; pixel_x = -8 }, -/obj/machinery/fax{ - fax_name = "Captain's Office"; - name = "Captain's Fax Machine" - }, /obj/structure/table/reinforced, /obj/machinery/keycard_auth/wall_mounted/directional/south{ pixel_x = 8; pixel_y = -24 }, /obj/machinery/status_display/ai/directional/east, +/obj/machinery/fax/heads/captain, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain/private) "pvy" = ( @@ -54205,10 +54196,6 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners{ dir = 1 }, -/obj/machinery/fax{ - fax_name = "Research Director's Office"; - name = "Research Director's Fax Machine" - }, /obj/structure/table, /obj/machinery/camera/autoname/directional/south{ network = list("ss13","rd") @@ -54217,6 +54204,7 @@ /obj/machinery/light_switch/directional/south{ pixel_x = 8 }, +/obj/machinery/fax/heads/rd, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/rd) "sAO" = ( @@ -62013,10 +62001,7 @@ "vlD" = ( /obj/structure/table/wood, /obj/machinery/light_switch/directional/north, -/obj/machinery/fax{ - fax_name = "Head of Personnel's Office"; - name = "Head of Personnel's Fax Machine" - }, +/obj/machinery/fax/heads/hop, /turf/open/floor/carpet/green, /area/station/command/heads_quarters/hop) "vlJ" = ( @@ -62090,16 +62075,13 @@ /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) "vno" = ( -/obj/machinery/fax{ - fax_name = "Chief Engineer's Office"; - name = "Chief Engineer's Fax Machine" - }, /obj/structure/table/reinforced, /obj/machinery/light/directional/east, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 5 }, /obj/structure/cable, +/obj/machinery/fax/heads/ce, /turf/open/floor/iron, /area/station/command/heads_quarters/ce) "vnr" = ( @@ -65330,16 +65312,13 @@ /turf/open/floor/plating, /area/station/maintenance/central/greater) "wum" = ( -/obj/machinery/fax{ - fax_name = "Head of Security's Office"; - name = "Head of Security's Fax Machine" - }, /obj/structure/table/wood/fancy/red, /obj/structure/secure_safe/hos{ pixel_x = 36; pixel_y = 28 }, /obj/machinery/airalarm/directional/north, +/obj/machinery/fax/heads/hos, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) "wun" = ( diff --git a/code/__DEFINES/dcs/signals/signals_fax.dm b/code/__DEFINES/dcs/signals/signals_fax.dm new file mode 100644 index 00000000000..3cb78d60775 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_fax.dm @@ -0,0 +1 @@ +#define COMSIG_FAX_MESSAGE_RECEIVED "fax_message_received" diff --git a/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/code/modules/modular_computers/computers/item/role_tablet_presets.dm index 2f655ac1d0c..47e10bf5372 100644 --- a/code/modules/modular_computers/computers/item/role_tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/role_tablet_presets.dm @@ -7,11 +7,15 @@ greyscale_config = /datum/greyscale_config/tablet/head greyscale_colors = "#67A364#a92323" max_capacity = parent_type::max_capacity * 2 + /// Fax type for a relevant head's tp connect their PDA to (for use with fax notification app) + var/fax_type = null + var/static/list/datum/computer_file/head_programs = list( /datum/computer_file/program/status, /datum/computer_file/program/science, /datum/computer_file/program/robocontrol, /datum/computer_file/program/budgetorders, + /datum/computer_file/program/faxbond, ) /obj/item/modular_computer/pda/heads/Initialize(mapload) @@ -20,12 +24,19 @@ var/datum/computer_file/program/program_type = new programs store_file(program_type) + if (ispath(fax_type, /obj/machinery/fax)) + var/datum/computer_file/program/faxbond/fax_notifier = locate() in stored_files + var/list/faxes_list = SSmachines.get_machines_by_type(fax_type) + var/obj/machinery/fax/heads_fax = length(faxes_list) ? pick(faxes_list) : null //there really shouldnt be more than one + fax_notifier.connect_fax(heads_fax) + /obj/item/modular_computer/pda/heads/captain name = "captain PDA" icon_state = "/obj/item/modular_computer/pda/heads/captain" greyscale_config = /datum/greyscale_config/tablet/captain greyscale_colors = "#2C7CB2#FF0000#FFFFFF#FFD55B" inserted_item = /obj/item/pen/fountain/captain + fax_type = /obj/machinery/fax/heads/captain /obj/item/modular_computer/pda/heads/captain/Initialize(mapload) . = ..() @@ -42,6 +53,7 @@ icon_state = "/obj/item/modular_computer/pda/heads/hop" greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head greyscale_colors = "#374f7e#a52f29#a52f29" + fax_type = /obj/machinery/fax/heads/hop starting_programs = list( /datum/computer_file/program/records/security, /datum/computer_file/program/job_management, @@ -53,6 +65,7 @@ greyscale_config = /datum/greyscale_config/tablet/head greyscale_colors = "#EA3232#0000CC" inserted_item = /obj/item/pen/red/security + fax_type = /obj/machinery/fax/heads/hos starting_programs = list( /datum/computer_file/program/records/security, ) @@ -62,6 +75,7 @@ icon_state = "/obj/item/modular_computer/pda/heads/ce" greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head greyscale_colors = "#D99A2E#69DBF3#FAFAFA" + fax_type = /obj/machinery/fax/heads/ce starting_programs = list( /datum/computer_file/program/atmosscan, /datum/computer_file/program/alarm_monitor, @@ -73,6 +87,7 @@ icon_state = "/obj/item/modular_computer/pda/heads/cmo" greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head greyscale_colors = "#FAFAFA#000099#3F96CC" + fax_type = /obj/machinery/fax/heads/cmo starting_programs = list( /datum/computer_file/program/maintenance/phys_scanner, /datum/computer_file/program/records/medical, @@ -84,6 +99,7 @@ greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head greyscale_colors = "#FAFAFA#000099#B347BC" inserted_item = /obj/item/pen/fountain + fax_type = /obj/machinery/fax/heads/rd starting_programs = list( /datum/computer_file/program/borg_monitor, /datum/computer_file/program/scipaper_program, @@ -97,6 +113,7 @@ greyscale_colors = "#c4b787#18191e#8b4c31" inserted_item = /obj/item/pen/survival stored_paper = 20 + fax_type = /obj/machinery/fax/heads/qm starting_programs = list( /datum/computer_file/program/shipping, /datum/computer_file/program/restock_tracker, diff --git a/code/modules/modular_computers/file_system/programs/faxnotif.dm b/code/modules/modular_computers/file_system/programs/faxnotif.dm new file mode 100644 index 00000000000..5cadc4b4d1f --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/faxnotif.dm @@ -0,0 +1,119 @@ +/datum/computer_file/program/faxbond + filename = "faxbond" + filedesc = "FaxBond" + can_run_on_flags = PROGRAM_PDA + downloader_category = PROGRAM_CATEGORY_DEVICE + program_open_overlay = "generic" + extended_desc = "A lightweight piece of software designed to decrease fax response time. \ + Will send a notification as soon as one of connected faxes receives a message. \ + Recommended by 9 out of 10 CentCom officers." + size = 1 + tgui_id = "NtosFaxBond" + program_icon = "fa-fax" + /// All relevant info of every connected fax, including weak ref for cleaning after ourself + name, area name and muted bool + var/list/connected_faxes = list() + +/** + * Proc for subscribing to faxes. Registers needed signal and updates fax related vars for program. Includes type checking. + * Arguments: + * * target - [/datum/computer_file/program/proc/tap] proc target, can be anything + */ +/datum/computer_file/program/faxbond/proc/connect_fax(obj/machinery/fax/target) + if(!istype(target)) + return FALSE + + var/our_id = target.fax_id + + if(!connected_faxes[our_id]) + RegisterSignal(target, COMSIG_FAX_MESSAGE_RECEIVED, PROC_REF(on_fax_message_received)) + + var/list/fax_info = list() + var/area/our_area = get_area(target) + fax_info["ref"] = WEAKREF(target) + fax_info["name"] = target.fax_name + fax_info["area_name"] = our_area.name + fax_info["muted"] = FALSE + connected_faxes[our_id] += fax_info + + return TRUE + +/** + * Disconnects a fax given its ID (if it was connected before), removing it from a list and unregistering relevant signal + * Arguments: + * * fax_id - fax id to disconnect from our PDA + */ +/datum/computer_file/program/faxbond/proc/disconnect_fax(fax_id) + if(!connected_faxes[fax_id]) + return + + var/list/fax_info = connected_faxes[fax_id] + var/datum/weakref/fax_ref = fax_info["ref"] + var/obj/machinery/fax/our_fax = fax_ref.resolve() + if (our_fax) + UnregisterSignal(our_fax, COMSIG_FAX_MESSAGE_RECEIVED) + + connected_faxes -= fax_id + + +/** + * Signal handler for [COMSIG_FAX_MESSAGE_RECEIVED]. + * Arguments: + * * receiver - [/obj/machinery/fax] that received a message + * * message_source - name of a sender + */ +/datum/computer_file/program/faxbond/proc/on_fax_message_received(obj/machinery/fax/receiver, message_source) + SIGNAL_HANDLER + + var/id = receiver.fax_id + var/list/fax_info = connected_faxes[id] + + if (fax_info["muted"]) + return + + var/datum/computer_file/program/messenger/messenger = locate() in computer.stored_files + var/datum/signal/subspace/messaging/tablet_message/signal = new(receiver, list( + "fakename" = "Fax Notificator", + "fakejob" = "PDA Program", + "message" = "Your fax [receiver.fax_name] has received a new message from [message_source]", + "targets" = list(messenger), + "automated" = TRUE + )) + INVOKE_ASYNC(signal, TYPE_PROC_REF(/datum/signal/subspace, send_to_receivers)) + +/datum/computer_file/program/faxbond/Destroy() + . = ..() + for(var/fax in connected_faxes) + disconnect_fax(fax) + +/datum/computer_file/program/faxbond/tap(atom/tapped_atom, mob/living/user, list/modifiers) + return connect_fax(tapped_atom) + +/datum/computer_file/program/faxbond/ui_data(mob/user) + var/list/data = list() + + data["faxes_info"] = list() + for(var/fax_id in connected_faxes) + var/list/fax_info = connected_faxes[fax_id] + var/list/fax_data = list( + "id" = fax_id, + "name" = fax_info["name"], + "location" = fax_info["area_name"], + "muted" = fax_info["muted"], + ) + data["faxes_info"] += list(fax_data) + return data + +/datum/computer_file/program/faxbond/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + switch(action) + if("unsubscribe") + disconnect_fax(params["id"]) + return TRUE + if("mute") + var/list/fax_info = connected_faxes[params["id"]] + if (!fax_info) + return FALSE + fax_info["muted"] = !fax_info["muted"] + return TRUE diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm index 1761a7fe69f..5336edcdcc2 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -70,6 +70,41 @@ GLOBAL_VAR_INIT(fax_autoprinting, FALSE) fax_name = "[current_area.name]" return ..() +/obj/machinery/fax/heads + abstract_type = /obj/machinery/fax/heads + +/obj/machinery/fax/heads/Initialize(mapload) + . = ..() + REGISTER_REQUIRED_MAP_ITEM(1, 1) + +/obj/machinery/fax/heads/captain + name = "Captain's Fax Machine" + fax_name = "Captain's Office" + +/obj/machinery/fax/heads/hop + name = "Head of Personnel's Fax Machine" + fax_name = "Head of Personnel's Office" + +/obj/machinery/fax/heads/hos + name = "Head of Security's Fax Machine" + fax_name = "Head of Security's Office" + +/obj/machinery/fax/heads/cmo + name = "Chief Medical Officer's Fax Machine" + fax_name = "Chief Medical Officer's Office" + +/obj/machinery/fax/heads/rd + name = "Research Director's Fax Machine" + fax_name = "Research Director's Office" + +/obj/machinery/fax/heads/ce + name = "Chief Engineer's Fax Machine" + fax_name = "Chief Engineer's Office" + +/obj/machinery/fax/heads/qm + name = "Quartermaster's Fax Machine" + fax_name = "Quartermaster's Office" + /obj/machinery/fax/admin/syndicate name = "Syndicate Fax Machine" @@ -401,6 +436,7 @@ GLOBAL_VAR_INIT(fax_autoprinting, FALSE) say("Received correspondence from [sender_name].") history_add("Receive", sender_name) addtimer(CALLBACK(src, PROC_REF(vend_item), loaded), 1.9 SECONDS) + SEND_SIGNAL(src, COMSIG_FAX_MESSAGE_RECEIVED, sender_name) /** * Procedure for animating an object entering or leaving the fax machine. diff --git a/code/modules/unit_tests/required_map_items.dm b/code/modules/unit_tests/required_map_items.dm index 4d65d7651e1..33ec9469ed0 100644 --- a/code/modules/unit_tests/required_map_items.dm +++ b/code/modules/unit_tests/required_map_items.dm @@ -16,6 +16,7 @@ /datum/unit_test/maptest_required_map_items/proc/setup_expected_types() expected_types += subtypesof(/obj/item/stamp/head) expected_types += subtypesof(/obj/machinery/modular_computer/preset/cargochat) + expected_types += subtypesof(/obj/machinery/fax/heads) expected_types += /mob/living/basic/parrot/poly expected_types += /mob/living/basic/pet/dog/corgi/ian diff --git a/tgstation.dme b/tgstation.dme index eeb8daccf82..dbf5c85039a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -338,6 +338,7 @@ #include "code\__DEFINES\dcs\signals\signals_cytology.dm" #include "code\__DEFINES\dcs\signals\signals_datum.dm" #include "code\__DEFINES\dcs\signals\signals_event.dm" +#include "code\__DEFINES\dcs\signals\signals_fax.dm" #include "code\__DEFINES\dcs\signals\signals_fish.dm" #include "code\__DEFINES\dcs\signals\signals_food.dm" #include "code\__DEFINES\dcs\signals\signals_gib.dm" @@ -5858,6 +5859,7 @@ #include "code\modules\modular_computers\file_system\programs\crewmanifest.dm" #include "code\modules\modular_computers\file_system\programs\dept_order.dm" #include "code\modules\modular_computers\file_system\programs\emojipedia.dm" +#include "code\modules\modular_computers\file_system\programs\faxnotif.dm" #include "code\modules\modular_computers\file_system\programs\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\frontier.dm" #include "code\modules\modular_computers\file_system\programs\jobmanagement.dm" diff --git a/tgui/packages/tgui/interfaces/NtosFaxBond.tsx b/tgui/packages/tgui/interfaces/NtosFaxBond.tsx new file mode 100644 index 00000000000..447400e656d --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosFaxBond.tsx @@ -0,0 +1,85 @@ +import { Button, NoticeBox, Section, Stack, Table } from 'tgui-core/components'; +import type { BooleanLike } from 'tgui-core/react'; +import { useBackend } from '../backend'; +import { NtosWindow } from '../layouts'; + +type FaxInfoList = { + id: string; + name: string; + location: string; + muted: BooleanLike; +}; + +type Data = { + faxes_info: FaxInfoList[]; +}; + +export const NtosFaxBond = (props) => { + return ( + + + + + + ); +}; + +export const NtosFaxBondContent = (props) => { + const { act, data } = useBackend(); + const { faxes_info = [] } = data; + return ( + <> + + Scan any fax to be notified when it receives a message. + + {!!faxes_info.length && ( +
+ + + ID + Name + Location + + + {faxes_info.map((fax) => ( + + + {fax.id} + + + {fax.name} + + + {fax.location} + + + +
+
+ )} + + ); +};