diff --git a/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm b/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm index 056bd39bf62..e7a18109475 100644 --- a/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm +++ b/_maps/RandomRuins/IceRuins/icemoon_surface_engioutpost.dmm @@ -532,13 +532,13 @@ /turf/open/floor/plating, /area/ruin/planetengi) "cI" = ( -/obj/item/pda/clear{ +/obj/item/modular_computer/tablet/pda/clear{ note = "Chief's asked me to check on the machinery inside PDA. He's also worried about Build, but i'm sure Harry'll handle the construction. I just need to work on Internals. Fuck i'm hungry" }, /turf/open/floor/iron, /area/ruin/planetengi) "cJ" = ( -/obj/item/pda/engineering{ +/obj/item/modular_computer/tablet/pda/engineering{ note = "To-do: Check on SM status. Get a pint at eat. Nag the research manager for RCDs." }, /turf/open/floor/iron, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm index 5394b2d4f93..984bfe87aa1 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1/commswilding_3.dmm @@ -120,7 +120,7 @@ dir = 8; pixel_x = -24 }, -/obj/item/pda/chameleon/broken{ +/obj/item/modular_computer/tablet/pda/chameleon/broken{ pixel_x = 5; pixel_y = 4 }, diff --git a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm index c895f7ba7a0..acfbced15ce 100644 --- a/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm +++ b/_maps/RandomRuins/SpaceRuins/bigderelict1.dmm @@ -1136,7 +1136,7 @@ /area/ruin/space/has_grav/derelictoutpost/cargostorage) "eC" = ( /obj/structure/closet/crate, -/obj/item/pda/clear, +/obj/item/modular_computer/tablet/pda/clear, /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/ruin/space/has_grav/derelictoutpost/cargostorage) diff --git a/_maps/RandomRuins/SpaceRuins/derelict7.dmm b/_maps/RandomRuins/SpaceRuins/derelict7.dmm index 15efea7ef6d..d10b6e4a2bb 100644 --- a/_maps/RandomRuins/SpaceRuins/derelict7.dmm +++ b/_maps/RandomRuins/SpaceRuins/derelict7.dmm @@ -323,7 +323,7 @@ /obj/effect/turf_decal/trimline/neutral/warning{ dir = 1 }, -/obj/item/cartridge/signal, +/obj/item/computer_hardware/hard_drive/role/signal, /turf/open/floor/iron/dark/side/airless{ dir = 1 }, diff --git a/_maps/RandomRuins/SpaceRuins/forgottenship.dmm b/_maps/RandomRuins/SpaceRuins/forgottenship.dmm index abe021aa747..4b6e77ad1b9 100644 --- a/_maps/RandomRuins/SpaceRuins/forgottenship.dmm +++ b/_maps/RandomRuins/SpaceRuins/forgottenship.dmm @@ -435,7 +435,7 @@ }, /obj/item/toy/nuke, /obj/item/clothing/under/chameleon, -/obj/item/pda/chameleon, +/obj/item/modular_computer/tablet/pda/chameleon, /obj/item/clothing/mask/chameleon, /obj/item/card/id/advanced/chameleon, /turf/open/floor/mineral/plastitanium, diff --git a/_maps/RandomZLevels/SnowCabin.dmm b/_maps/RandomZLevels/SnowCabin.dmm index 5132bd764d3..3c060629625 100644 --- a/_maps/RandomZLevels/SnowCabin.dmm +++ b/_maps/RandomZLevels/SnowCabin.dmm @@ -959,12 +959,11 @@ /area/awaymission/cabin/snowforest/sovietsurface) "dm" = ( /obj/structure/table/reinforced, -/obj/item/pda/syndicate{ - background_color = "#0039A6"; - default_cartridge = /obj/item/cartridge/virus/mime; +/obj/item/modular_computer/tablet/pda/syndicate{ + default_disk = /obj/item/computer_hardware/hard_drive/role/virus/mime; desc = "A portable microcomputer by Thinktronic Systems, LTD. Seems like it may have useful information on it."; - name = "soviet PDA"; - note = "TRANSLATED TO GALACTIC COMMON:
My partner has left to help those Nanotrasen fucks three days ago. They said that a distress signal came from down south and they had to check it out. How fucking long does it take to investigate a mining outpost? Either those Nanotrasen fuckers betrayed us or something really did go wrong. Either way, I'm leaving before this becomes an issue for me and anyone else here. That dumb idiot." + name = "soviet tablet"; + note = "TRANSLATED TO GALACTIC COMMON: My partner has left to help those Nanotrasen fucks three days ago. They said that a distress signal came from down south and they had to check it out. How fucking long does it take to investigate a mining outpost? Either those Nanotrasen fuckers betrayed us or something really did go wrong. Either way, I'm leaving before this becomes an issue for me and anyone else here. That dumb idiot." }, /turf/open/floor/plating/snowed/snow_cabin, /area/awaymission/cabin/snowforest/sovietsurface) @@ -3563,12 +3562,11 @@ /area/awaymission/cabin/caves) "nb" = ( /obj/effect/turf_decal/weather/snow, -/obj/item/pda/syndicate{ - background_color = "#0039A6"; - default_cartridge = /obj/item/cartridge/virus/clown; +/obj/item/modular_computer/tablet/pda/syndicate{ + default_disk = /obj/item/computer_hardware/hard_drive/role/virus/clown; desc = "A portable microcomputer by Thinktronic Systems, LTD. Seems like it may have useful information on it."; - name = "soviet PDA"; - note = "TRANSLATED TO GALACTIC COMMON:
DO NOT GO SOUTH." + name = "soviet tablet"; + note = "TRANSLATED TO GALACTIC COMMON: DO NOT GO SOUTH." }, /obj/effect/decal/remains/human{ color = "#72e4fa" diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index 3d405d7d6ae..973d12d5af1 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -2893,11 +2893,8 @@ /area/awaymission/moonoutpost19/research) "hr" = ( /obj/structure/table, -/obj/item/cartridge/signal/ordnance, -/obj/item/cartridge/signal/ordnance{ - pixel_x = -4; - pixel_y = 2 - }, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/cafeteria{ dir = 5 diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm index ebf98cfda57..17e3739055d 100644 --- a/_maps/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/undergroundoutpost45.dmm @@ -6061,11 +6061,8 @@ /area/awaymission/undergroundoutpost45/research) "nk" = ( /obj/structure/table, -/obj/item/cartridge/signal/ordnance, -/obj/item/cartridge/signal/ordnance{ - pixel_x = -4; - pixel_y = 2 - }, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/cafeteria{ dir = 5; diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index a91ab5a90b2..91862a7979d 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -35034,15 +35034,9 @@ "hYe" = ( /obj/structure/table/glass, /obj/item/folder/blue, -/obj/item/cartridge/medical{ - pixel_x = -3 - }, -/obj/item/cartridge/medical{ - pixel_x = 3 - }, -/obj/item/cartridge/chemistry{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/chemistry, /obj/effect/turf_decal/tile/blue{ dir = 4 }, @@ -56416,15 +56410,9 @@ /area/service/hydroponics) "opa" = ( /obj/structure/table/reinforced, -/obj/item/cartridge/quartermaster{ - pixel_x = -6 - }, -/obj/item/cartridge/quartermaster{ - pixel_x = 6 - }, -/obj/item/cartridge/quartermaster{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, /obj/item/gps/mining, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, @@ -67582,31 +67570,15 @@ /turf/open/floor/iron, /area/medical/medbay/central) "rFD" = ( -/obj/item/cartridge/atmos{ - pixel_x = -2; - pixel_y = 8 - }, -/obj/item/cartridge/atmos{ - pixel_x = -2; - pixel_y = 4 - }, -/obj/item/cartridge/atmos{ - pixel_x = -2 - }, +/obj/item/computer_hardware/hard_drive/role/atmos, +/obj/item/computer_hardware/hard_drive/role/atmos, +/obj/item/computer_hardware/hard_drive/role/atmos, /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/bot, -/obj/item/cartridge/engineering{ - pixel_x = 6; - pixel_y = 8 - }, -/obj/item/cartridge/engineering{ - pixel_x = 6; - pixel_y = 4 - }, -/obj/item/cartridge/engineering{ - pixel_x = 6 - }, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, /obj/structure/rack, /turf/open/floor/iron/dark, /area/command/heads_quarters/ce) @@ -71629,15 +71601,9 @@ /area/command/heads_quarters/hop) "sNs" = ( /obj/structure/table, -/obj/item/cartridge/signal/ordnance{ - pixel_x = 6 - }, -/obj/item/cartridge/signal/ordnance{ - pixel_x = -6 - }, -/obj/item/cartridge/signal/ordnance{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /obj/machinery/camera/directional/east{ c_tag = "Science - Research Director's Office"; name = "science camera"; diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 97637f21f2c..fafe1c3c606 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -27314,15 +27314,9 @@ /area/service/library) "mwr" = ( /obj/structure/table/glass, -/obj/item/cartridge/medical{ - pixel_x = -3 - }, -/obj/item/cartridge/medical{ - pixel_x = 3 - }, -/obj/item/cartridge/chemistry{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/chemistry, /obj/machinery/status_display/evac/directional/north, /obj/effect/turf_decal/tile/blue/full, /turf/open/floor/iron/dark, @@ -32973,15 +32967,9 @@ }, /obj/structure/table, /obj/item/coin/silver, -/obj/item/cartridge/quartermaster, -/obj/item/cartridge/quartermaster{ - pixel_x = 6; - pixel_y = 5 - }, -/obj/item/cartridge/quartermaster{ - pixel_x = -4; - pixel_y = 7 - }, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, /obj/item/clipboard, /turf/open/floor/iron, /area/cargo/qm) @@ -45303,18 +45291,10 @@ /area/command/meeting_room) "vkB" = ( /obj/structure/table/reinforced, -/obj/item/cartridge/engineering{ - pixel_x = 4; - pixel_y = 5 - }, -/obj/item/cartridge/engineering{ - pixel_x = -3; - pixel_y = 2 - }, -/obj/item/cartridge/engineering{ - pixel_x = 3 - }, -/obj/item/cartridge/atmos, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/atmos, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -47744,15 +47724,9 @@ /area/maintenance/fore/lesser) "wvC" = ( /obj/structure/table, -/obj/item/cartridge/signal/ordnance{ - pixel_x = 4; - pixel_y = 6 - }, -/obj/item/cartridge/signal/ordnance{ - pixel_x = -4; - pixel_y = 2 - }, -/obj/item/cartridge/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /turf/open/floor/iron/cafeteria, /area/command/heads_quarters/rd) "wvQ" = ( diff --git a/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm b/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm index ea9d4697155..ffdafccae14 100644 --- a/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm +++ b/_maps/map_files/IceBoxStation/IcemoonUnderground_Above.dmm @@ -4869,7 +4869,7 @@ "nZ" = ( /obj/structure/table/wood, /obj/item/taperecorder, -/obj/item/cartridge/lawyer, +/obj/item/computer_hardware/hard_drive/role/lawyer, /obj/machinery/computer/security/telescreen/prison{ pixel_y = 32 }, diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 99a821a18fa..f72b00002b6 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -30304,9 +30304,9 @@ /obj/structure/table, /obj/item/clipboard, /obj/item/folder/yellow, -/obj/item/cartridge/quartermaster, -/obj/item/cartridge/quartermaster, -/obj/item/cartridge/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, /obj/item/pen/fountain, /turf/open/floor/carpet/orange, /area/cargo/qm) @@ -43160,14 +43160,10 @@ "jSV" = ( /obj/structure/table, /obj/item/clipboard, -/obj/item/cartridge/roboticist{ - pixel_x = -3 - }, -/obj/item/cartridge/signal/ordnance{ - pixel_x = 6 - }, -/obj/item/cartridge/signal/ordnance, -/obj/item/cartridge/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/roboticist, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /obj/item/circuitboard/aicore{ pixel_y = 5 }, @@ -46608,21 +46604,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/item/cartridge/medical{ - pixel_x = 6; - pixel_y = 2 - }, -/obj/item/cartridge/medical{ - pixel_x = 5; - pixel_y = 1 - }, -/obj/item/cartridge/medical{ - pixel_x = 4 - }, -/obj/item/cartridge/chemistry{ - pixel_x = -6; - pixel_y = 8 - }, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/chemistry, /obj/item/clothing/neck/stethoscope{ pixel_y = 5 }, @@ -60426,7 +60411,7 @@ pixel_x = 5 }, /obj/structure/table, -/obj/item/cartridge/lawyer, +/obj/item/computer_hardware/hard_drive/role/lawyer, /obj/effect/turf_decal/bot, /obj/structure/mirror/directional/north, /turf/open/floor/iron/dark, @@ -70880,17 +70865,9 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/item/cartridge/engineering{ - pixel_x = 6; - pixel_y = 6 - }, -/obj/item/cartridge/engineering{ - pixel_x = 8 - }, -/obj/item/cartridge/atmos{ - pixel_x = -6; - pixel_y = 4 - }, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/atmos, /obj/item/folder, /obj/item/stamp/ce, /turf/open/floor/iron/dark, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 172cff6c83d..713bad6449b 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -10322,19 +10322,11 @@ /turf/closed/wall/r_wall, /area/maintenance/solars/starboard/aft) "cLe" = ( -/obj/item/cartridge/engineering{ - pixel_x = 4; - pixel_y = 5 - }, -/obj/item/cartridge/engineering{ - pixel_x = -3; - pixel_y = 2 - }, -/obj/item/cartridge/engineering{ - pixel_x = 3 - }, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, /obj/structure/table/reinforced, -/obj/item/cartridge/atmos, +/obj/item/computer_hardware/hard_drive/role/atmos, /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 4 }, @@ -32537,10 +32529,7 @@ "kMr" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/table/wood, -/obj/item/cartridge/detective{ - pixel_x = 7; - pixel_y = 8 - }, +/obj/item/computer_hardware/hard_drive/role/detective, /obj/item/folder/red{ pixel_x = -7; pixel_y = 6 @@ -32548,13 +32537,8 @@ /obj/item/folder/red{ pixel_x = -7 }, -/obj/item/cartridge/detective{ - pixel_x = 7; - pixel_y = 4 - }, -/obj/item/cartridge/detective{ - pixel_x = 7 - }, +/obj/item/computer_hardware/hard_drive/role/detective, +/obj/item/computer_hardware/hard_drive/role/detective, /obj/structure/cable, /turf/open/floor/iron/dark, /area/command/heads_quarters/hos) @@ -44235,15 +44219,9 @@ /obj/effect/turf_decal/siding{ dir = 4 }, -/obj/item/cartridge/signal/ordnance{ - pixel_x = 6 - }, -/obj/item/cartridge/signal/ordnance{ - pixel_x = -6 - }, -/obj/item/cartridge/signal/ordnance{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /turf/open/floor/iron/dark, /area/command/heads_quarters/rd) "oRu" = ( @@ -49758,17 +49736,9 @@ pixel_x = -10; pixel_y = 9 }, -/obj/item/cartridge/quartermaster{ - pixel_x = 9 - }, -/obj/item/cartridge/quartermaster{ - pixel_x = 5; - pixel_y = 11 - }, -/obj/item/cartridge/quartermaster{ - pixel_x = 8; - pixel_y = 4 - }, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, /turf/open/floor/wood, /area/cargo/qm) "qWo" = ( @@ -51213,7 +51183,7 @@ }, /obj/item/pen, /obj/item/taperecorder, -/obj/item/cartridge/lawyer, +/obj/item/computer_hardware/hard_drive/role/lawyer, /obj/machinery/button/door/directional/south{ id = "lawyer_shutters"; name = "law office shutter control"; @@ -53927,15 +53897,9 @@ /area/service/chapel/funeral) "sEP" = ( /obj/structure/table/glass, -/obj/item/cartridge/medical{ - pixel_x = -3 - }, -/obj/item/cartridge/medical{ - pixel_x = 3 - }, -/obj/item/cartridge/chemistry{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/chemistry, /obj/machinery/light_switch/directional/north, /obj/machinery/vending/wallmed/directional/west, /obj/effect/turf_decal/tile/blue/anticorner/contrasted{ diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index df2ba83c060..3821946e213 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -5590,15 +5590,9 @@ /area/tdome/observation) "pP" = ( /obj/structure/table/reinforced, -/obj/item/cartridge/quartermaster{ - pixel_x = -6 - }, -/obj/item/cartridge/quartermaster{ - pixel_x = 6 - }, -/obj/item/cartridge/quartermaster{ - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, /obj/item/gps/mining, /obj/effect/turf_decal/stripes/line{ dir = 6 diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index ac80a0f2d53..7c5a54e22f6 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -11826,15 +11826,9 @@ "cWa" = ( /obj/structure/table/reinforced, /obj/structure/window/reinforced, -/obj/item/cartridge/signal/ordnance{ - pixel_x = -4; - pixel_y = 2 - }, -/obj/item/cartridge/signal/ordnance, -/obj/item/cartridge/signal/ordnance{ - pixel_x = 4; - pixel_y = 6 - }, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, +/obj/item/computer_hardware/hard_drive/role/signal/ordnance, /obj/effect/landmark/event_spawn, /turf/open/floor/iron/cafeteria{ dir = 5 @@ -52347,18 +52341,10 @@ /area/ai_monitored/turret_protected/aisat/hallway) "rxV" = ( /obj/structure/table/reinforced, -/obj/item/cartridge/engineering{ - pixel_x = 4; - pixel_y = 5 - }, -/obj/item/cartridge/engineering{ - pixel_x = 3 - }, -/obj/item/cartridge/engineering{ - pixel_x = -3; - pixel_y = 2 - }, -/obj/item/cartridge/atmos, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/engineering, +/obj/item/computer_hardware/hard_drive/role/atmos, /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 }, @@ -60060,15 +60046,9 @@ /area/security/brig) "umv" = ( /obj/structure/table/glass, -/obj/item/cartridge/chemistry{ - pixel_y = 6 - }, -/obj/item/cartridge/medical{ - pixel_x = 3 - }, -/obj/item/cartridge/medical{ - pixel_x = -3 - }, +/obj/item/computer_hardware/hard_drive/role/chemistry, +/obj/item/computer_hardware/hard_drive/role/medical, +/obj/item/computer_hardware/hard_drive/role/medical, /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/dark, /area/command/heads_quarters/cmo) @@ -63705,14 +63685,8 @@ /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 8 }, -/obj/item/cartridge/quartermaster{ - pixel_x = 6; - pixel_y = 5 - }, -/obj/item/cartridge/quartermaster{ - pixel_x = -4; - pixel_y = 7 - }, +/obj/item/computer_hardware/hard_drive/role/quartermaster, +/obj/item/computer_hardware/hard_drive/role/quartermaster, /obj/item/clipboard, /turf/open/floor/iron, /area/cargo/qm) diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index 118d5d05a34..3e39f21b400 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -474,36 +474,36 @@ * Used to see pda_region in [/datum/controller/subsystem/id_access/proc/setup_tgui_lists] */ #define PDA_PAINTING_REGIONS list( \ - /obj/item/pda = list(REGION_GENERAL), \ - /obj/item/pda/clown = list(REGION_GENERAL), \ - /obj/item/pda/mime = list(REGION_GENERAL), \ - /obj/item/pda/medical = list(REGION_MEDBAY), \ - /obj/item/pda/viro = list(REGION_MEDBAY), \ - /obj/item/pda/engineering = list(REGION_ENGINEERING), \ - /obj/item/pda/security = list(REGION_SECURITY), \ - /obj/item/pda/detective = list(REGION_SECURITY), \ - /obj/item/pda/warden = list(REGION_SECURITY), \ - /obj/item/pda/janitor = list(REGION_GENERAL), \ - /obj/item/pda/science = list(REGION_RESEARCH), \ - /obj/item/pda/heads/hop = list(REGION_COMMAND), \ - /obj/item/pda/heads/hos = list(REGION_COMMAND), \ - /obj/item/pda/heads/cmo = list(REGION_COMMAND), \ - /obj/item/pda/heads/ce = list(REGION_COMMAND), \ - /obj/item/pda/heads/rd = list(REGION_COMMAND), \ - /obj/item/pda/captain = list(REGION_COMMAND), \ - /obj/item/pda/cargo = list(REGION_SUPPLY), \ - /obj/item/pda/quartermaster = list(REGION_SUPPLY), \ - /obj/item/pda/shaftminer = list(REGION_SUPPLY), \ - /obj/item/pda/chaplain = list(REGION_GENERAL), \ - /obj/item/pda/lawyer = list(REGION_GENERAL, REGION_SECURITY), \ - /obj/item/pda/botanist = list(REGION_GENERAL), \ - /obj/item/pda/roboticist = list(REGION_RESEARCH), \ - /obj/item/pda/curator = list(REGION_GENERAL), \ - /obj/item/pda/cook = list(REGION_GENERAL), \ - /obj/item/pda/bar = list(REGION_GENERAL), \ - /obj/item/pda/atmos = list(REGION_ENGINEERING), \ - /obj/item/pda/chemist = list(REGION_MEDBAY), \ - /obj/item/pda/geneticist = list(REGION_RESEARCH), \ + /obj/item/modular_computer/tablet/pda = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/clown = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/mime = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/medical = list(REGION_MEDBAY), \ + /obj/item/modular_computer/tablet/pda/viro = list(REGION_MEDBAY), \ + /obj/item/modular_computer/tablet/pda/engineering = list(REGION_ENGINEERING), \ + /obj/item/modular_computer/tablet/pda/security = list(REGION_SECURITY), \ + /obj/item/modular_computer/tablet/pda/detective = list(REGION_SECURITY), \ + /obj/item/modular_computer/tablet/pda/warden = list(REGION_SECURITY), \ + /obj/item/modular_computer/tablet/pda/janitor = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/science = list(REGION_RESEARCH), \ + /obj/item/modular_computer/tablet/pda/heads/hop = list(REGION_COMMAND), \ + /obj/item/modular_computer/tablet/pda/heads/hos = list(REGION_COMMAND), \ + /obj/item/modular_computer/tablet/pda/heads/cmo = list(REGION_COMMAND), \ + /obj/item/modular_computer/tablet/pda/heads/ce = list(REGION_COMMAND), \ + /obj/item/modular_computer/tablet/pda/heads/rd = list(REGION_COMMAND), \ + /obj/item/modular_computer/tablet/pda/captain = list(REGION_COMMAND), \ + /obj/item/modular_computer/tablet/pda/cargo = list(REGION_SUPPLY), \ + /obj/item/modular_computer/tablet/pda/quartermaster = list(REGION_SUPPLY), \ + /obj/item/modular_computer/tablet/pda/shaftminer = list(REGION_SUPPLY), \ + /obj/item/modular_computer/tablet/pda/chaplain = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/lawyer = list(REGION_GENERAL, REGION_SECURITY), \ + /obj/item/modular_computer/tablet/pda/botanist = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/roboticist = list(REGION_RESEARCH), \ + /obj/item/modular_computer/tablet/pda/curator = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/cook = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/bar = list(REGION_GENERAL), \ + /obj/item/modular_computer/tablet/pda/atmos = list(REGION_ENGINEERING), \ + /obj/item/modular_computer/tablet/pda/chemist = list(REGION_MEDBAY), \ + /obj/item/modular_computer/tablet/pda/geneticist = list(REGION_RESEARCH), \ ) /// All regions that make up the station area. Helper define to quickly designate a region as part of the station or not. Access via SSid_access.station_regions. diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index edec22ac708..300ff4f16b5 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -268,10 +268,10 @@ // /obj/item/pda signals ///called on pda when the user changes the ringtone: (mob/living/user, new_ringtone) -#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" +#define COMSIG_TABLET_CHANGE_ID "comsig_tablet_change_id" #define COMPONENT_STOP_RINGTONE_CHANGE (1<<0) -#define COMSIG_PDA_CHECK_DETONATE "pda_check_detonate" - #define COMPONENT_PDA_NO_DETONATE (1<<0) +#define COMSIG_TABLET_CHECK_DETONATE "pda_check_detonate" + #define COMPONENT_TABLET_NO_DETONATE (1<<0) // /obj/item/radio signals diff --git a/code/__DEFINES/devices.dm b/code/__DEFINES/devices.dm index a6ecf11e56e..d76f56168a9 100644 --- a/code/__DEFINES/devices.dm +++ b/code/__DEFINES/devices.dm @@ -1,44 +1,18 @@ -// PDA defines // -#define CART_SECURITY (1<<0) -#define CART_ENGINE (1<<1) -#define CART_ATMOS (1<<2) -#define CART_MEDICAL (1<<3) -#define CART_MANIFEST (1<<4) -#define CART_CLOWN (1<<5) -#define CART_MIME (1<<6) -#define CART_REAGENT_SCANNER (1<<7) -#define CART_STATUS_DISPLAY (1<<10) -#define CART_QUARTERMASTER (1<<11) +// Role disk defines -/// PDA ui menu defines -#define PDA_UI_HUB 0 -#define PDA_UI_NOTEKEEPER 1 -#define PDA_UI_MESSENGER 2 -#define PDA_UI_READ_MESSAGES 21 -#define PDA_UI_ATMOS_SCAN 3 -#define PDA_UI_SKILL_TRACKER 4 -/// mode is divided by on return -#define PDA_UI_RETURN_DIVIDER 10 -/// if the new mode from return is between these, go straight to the hub. -#define PDA_UI_REDIRECT_HUB_MIN 4 -#define PDA_UI_REDIRECT_HUB_MAX 9 -#define PDA_UI_CREW_MANIFEST 41 -#define PDA_UI_STATUS_DISPLAY 42 -#define PDA_UI_POWER_MONITOR 43 -#define PDA_UI_POWER_MONITOR_SELECTED 433 -#define PDA_UI_MED_RECORDS 44 -#define PDA_UI_MED_RECORD_SELECTED 441 -#define PDA_UI_SEC_RECORDS 45 -#define PDA_UI_SEC_RECORD_SELECTED 451 -#define PDA_UI_SUPPLY_RECORDS 46 -#define PDA_UI_SILO_LOGS 47 -#define PDA_UI_BOTS_ACCESS 48 -#define PDA_UI_EMOJI_GUIDE 49 -#define PDA_UI_SIGNALER 50 - - -// Used by PDA and cartridge code to reduce repetitiveness of spritesheets -#define PDAIMG(what) {""} +#define DISK_POWER (1<<0) +#define DISK_ATMOS (1<<1) +#define DISK_MED (1<<2) +#define DISK_CHEM (1<<3) +#define DISK_MANIFEST (1<<4) +#define DISK_NEWS (1<<5) +#define DISK_SIGNAL (1<<6) +#define DISK_STATUS (1<<7) +#define DISK_CARGO (1<<8) +#define DISK_ROBOS (1<<9) +#define DISK_JANI (1<<10) +#define DISK_SEC (1<<11) +#define DISK_BUDGET (1<<12) // Used to stringify message targets before sending the signal datum. #define STRINGIFY_PDA_TARGET(name, job) "[name] ([job])" diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 5c18965d913..97793291f6d 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -163,13 +163,12 @@ #define ui_ai_announcement "SOUTH:6,WEST+7" #define ui_ai_shuttle "SOUTH:6,WEST+8" #define ui_ai_state_laws "SOUTH:6,WEST+9" -#define ui_ai_pda_send "SOUTH:6,WEST+10" -#define ui_ai_pda_log "SOUTH:6,WEST+11" -#define ui_ai_take_picture "SOUTH:6,WEST+12" -#define ui_ai_view_images "SOUTH:6,WEST+13" -#define ui_ai_sensor "SOUTH:6,WEST+14" -#define ui_ai_multicam "SOUTH+1:6,WEST+13" -#define ui_ai_add_multicam "SOUTH+1:6,WEST+14" +#define ui_ai_mod_int "SOUTH:6,WEST+10" +#define ui_ai_take_picture "SOUTH:6,WEST+11" +#define ui_ai_view_images "SOUTH:6,WEST+12" +#define ui_ai_sensor "SOUTH:6,WEST+13" +#define ui_ai_multicam "SOUTH+1:6,WEST+12" +#define ui_ai_add_multicam "SOUTH+1:6,WEST+13" #define ui_ai_language_menu "SOUTH+1:8,WEST+11:30" //pAI @@ -182,14 +181,13 @@ #define ui_pai_host_monitor "SOUTH:6,WEST+6" #define ui_pai_crew_manifest "SOUTH:6,WEST+7" #define ui_pai_state_laws "SOUTH:6,WEST+8" -#define ui_pai_pda_send "SOUTH:6,WEST+9" -#define ui_pai_pda_log "SOUTH:6,WEST+10" -#define ui_pai_internal_gps "SOUTH:6,WEST+11" -#define ui_pai_take_picture "SOUTH:6,WEST+12" -#define ui_pai_view_images "SOUTH:6,WEST+13" -#define ui_pai_radio "SOUTH:6,WEST+14" -#define ui_pai_language_menu "SOUTH+1:8,WEST+13:31" -#define ui_pai_navigate_menu "SOUTH+1:8,WEST+13:31" +#define ui_pai_mod_int "SOUTH:6,WEST+9" +#define ui_pai_internal_gps "SOUTH:6,WEST+10" +#define ui_pai_take_picture "SOUTH:6,WEST+11" +#define ui_pai_view_images "SOUTH:6,WEST+12" +#define ui_pai_radio "SOUTH:6,WEST+13" +#define ui_pai_language_menu "SOUTH+1:8,WEST+12:31" +#define ui_pai_navigate_menu "SOUTH+1:8,WEST+12:31" //Ghosts #define ui_ghost_spawners_menu "SOUTH:6,CENTER-3:24" diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index 249c178b52d..4201979ccbd 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -59,9 +59,11 @@ //Modular computer part defines #define MC_CPU "CPU" #define MC_HDD "HDD" +#define MC_HDD_JOB "HDD_JOB" #define MC_SDD "SDD" #define MC_CARD "CARD" #define MC_CARD2 "CARD2" +#define MC_CART "CART" #define MC_NET "NET" #define MC_PRINT "PRINT" #define MC_CELL "CELL" @@ -69,6 +71,7 @@ #define MC_AI "AI" #define MC_SENSORS "SENSORS" #define MC_SIGNALER "SIGNALER" +#define MC_IDENTIFY "IDENTIFY" //NTNet stuff, for modular computers // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 2a0db3544e6..8545b04d6f3 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -128,11 +128,11 @@ GLOBAL_VAR_INIT(cmp_field, "name") /proc/cmp_typepaths_asc(A, B) return sorttext("[B]","[A]") -/proc/cmp_pdaname_asc(obj/item/pda/A, obj/item/pda/B) - return sorttext(B.owner, A.owner) +/proc/cmp_pdaname_asc(obj/item/modular_computer/A, obj/item/modular_computer/B) + return sorttext(B?.saved_identification, A?.saved_identification) -/proc/cmp_pdajob_asc(obj/item/pda/A, obj/item/pda/B) - return sorttext(B.ownjob, A.ownjob) +/proc/cmp_pdajob_asc(obj/item/modular_computer/A, obj/item/modular_computer/B) + return sorttext(B?.saved_job, A?.saved_job) /proc/cmp_num_string_asc(A, B) return text2num(A) - text2num(B) diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index 64afd556a2a..b137ba3779a 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -139,7 +139,7 @@ GLOBAL_LIST_INIT(phobia_objs, list( /obj/item/gun/magic/staff/honk, /obj/item/instrument/bikehorn, /obj/item/megaphone/clown, - /obj/item/pda/clown, + /obj/item/modular_computer/tablet/pda/clown, /obj/item/pneumatic_cannon/pie, /obj/item/stack/ore/bananium, /obj/item/stack/tile/mineral/bananium, diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 1713a857058..fabbdae41ab 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -48,6 +48,17 @@ var/mob/living/silicon/ai/AI = usr AI.toggle_camera_light() +/atom/movable/screen/ai/modpc + name = "Messenger" + icon_state = "pda_send" + var/mob/living/silicon/ai/robot + +/atom/movable/screen/ai/modpc/Click() + . = ..() + if(.) + return + robot.modularInterface?.interact(robot) + /atom/movable/screen/ai/crew_monitor name = "Crew Monitoring Console" icon_state = "crew_monitor" @@ -108,26 +119,6 @@ var/mob/living/silicon/ai/AI = usr AI.checklaws() -/atom/movable/screen/ai/pda_msg_send - name = "PDA - Send Message" - icon_state = "pda_send" - -/atom/movable/screen/ai/pda_msg_send/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.cmd_send_pdamesg(usr) - -/atom/movable/screen/ai/pda_msg_show - name = "PDA - Show Message Log" - icon_state = "pda_receive" - -/atom/movable/screen/ai/pda_msg_show/Click() - if(..()) - return - var/mob/living/silicon/ai/AI = usr - AI.cmd_show_message_log(usr) - /atom/movable/screen/ai/image_take name = "Take Image" icon_state = "take_picture" @@ -190,6 +181,7 @@ /datum/hud/ai/New(mob/owner) ..() var/atom/movable/screen/using + var/mob/living/silicon/ai/myai = mymob // Language menu using = new /atom/movable/screen/language_menu @@ -257,17 +249,14 @@ using.hud = src static_inventory += using -//PDA message - using = new /atom/movable/screen/ai/pda_msg_send() - using.screen_loc = ui_ai_pda_send - using.hud = src - static_inventory += using - -//PDA log - using = new /atom/movable/screen/ai/pda_msg_show() - using.screen_loc = ui_ai_pda_log +// Modular Interface + using = new /atom/movable/screen/ai/modpc() + using.screen_loc = ui_ai_mod_int using.hud = src static_inventory += using + myai.interfaceButton = using + var/atom/movable/screen/ai/modpc/tabletbutton = using + tabletbutton.robot = myai //Take image using = new /atom/movable/screen/ai/image_take() diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm index 069a5e093d7..fdd97191f36 100644 --- a/code/_onclick/hud/pai.dm +++ b/code/_onclick/hud/pai.dm @@ -119,27 +119,16 @@ var/mob/living/silicon/pai/pAI = usr pAI.checklaws() -/atom/movable/screen/pai/pda_msg_send - name = "PDA - Send Message" +/atom/movable/screen/pai/modpc + name = "Messenger" icon_state = "pda_send" - required_software = "digital messenger" + var/mob/living/silicon/pai/pAI -/atom/movable/screen/pai/pda_msg_send/Click() - if(!..()) +/atom/movable/screen/pai/modpc/Click() + . = ..() + if(!.) // this works for some reason. return - var/mob/living/silicon/pai/pAI = usr - pAI.cmd_send_pdamesg(usr) - -/atom/movable/screen/pai/pda_msg_show - name = "PDA - Show Message Log" - icon_state = "pda_receive" - required_software = "digital messenger" - -/atom/movable/screen/pai/pda_msg_show/Click() - if(!..()) - return - var/mob/living/silicon/pai/pAI = usr - pAI.cmd_show_message_log(usr) + pAI.modularInterface?.interact(pAI) /atom/movable/screen/pai/internal_gps name = "Internal GPS" @@ -191,6 +180,7 @@ /datum/hud/pai/New(mob/living/silicon/pai/owner) ..() var/atom/movable/screen/using + var/mob/living/silicon/pai/mypai = mymob // Software menu using = new /atom/movable/screen/pai/software @@ -247,15 +237,13 @@ using.screen_loc = ui_pai_state_laws static_inventory += using -// PDA message - using = new /atom/movable/screen/pai/pda_msg_send() - using.screen_loc = ui_pai_pda_send - static_inventory += using - -// PDA log - using = new /atom/movable/screen/pai/pda_msg_show() - using.screen_loc = ui_pai_pda_log +// Modular Interface + using = new /atom/movable/screen/pai/modpc() + using.screen_loc = ui_pai_mod_int static_inventory += using + mypai.interfaceButton = using + var/atom/movable/screen/pai/modpc/tabletbutton = using + tabletbutton.pAI = mypai // Internal GPS using = new /atom/movable/screen/pai/internal_gps() diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index a1cb891362c..ac189048e09 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -130,14 +130,14 @@ static_inventory += using //Borg Integrated Tablet - using = new /atom/movable/screen/robot/modPC() + using = new /atom/movable/screen/robot/modpc() using.screen_loc = ui_borg_tablet using.hud = src static_inventory += using robit.interfaceButton = using if(robit.modularInterface) using.vis_contents += robit.modularInterface - var/atom/movable/screen/robot/modPC/tabletbutton = using + var/atom/movable/screen/robot/modpc/tabletbutton = using tabletbutton.robot = robit //Alerts @@ -297,18 +297,18 @@ robot = null return ..() -/atom/movable/screen/robot/modPC +/atom/movable/screen/robot/modpc name = "Modular Interface" icon_state = "template" var/mob/living/silicon/robot/robot -/atom/movable/screen/robot/modPC/Click() +/atom/movable/screen/robot/modpc/Click() . = ..() if(.) return robot.modularInterface?.interact(robot) -/atom/movable/screen/robot/modPC/Destroy() +/atom/movable/screen/robot/modpc/Destroy() if(robot) robot.interfaceButton = null robot = null diff --git a/code/controllers/subsystem/id_access.dm b/code/controllers/subsystem/id_access.dm index 81c3ad1b27a..8604d253a4d 100644 --- a/code/controllers/subsystem/id_access.dm +++ b/code/controllers/subsystem/id_access.dm @@ -211,7 +211,7 @@ SUBSYSTEM_DEF(id_access) var/datum/id_trim/trim = trim_singletons_by_path[trim_path] centcom_job_templates[trim_path] = trim.assignment - var/list/all_pda_paths = typesof(/obj/item/pda) + var/list/all_pda_paths = typesof(/obj/item/modular_computer/tablet/pda) var/list/pda_regions = PDA_PAINTING_REGIONS for(var/pda_path in all_pda_paths) if(!(pda_path in pda_regions)) @@ -225,7 +225,7 @@ SUBSYSTEM_DEF(id_access) if(!(whitelisted_region in manager_regions)) continue var/list/manager_pdas = manager_info["pdas"] - var/obj/item/pda/fake_pda = pda_path + var/obj/item/modular_computer/tablet/pda/fake_pda = pda_path manager_pdas[pda_path] = initial(fake_pda.name) station_pda_templates[pda_path] = initial(fake_pda.name) diff --git a/code/controllers/subsystem/wardrobe.dm b/code/controllers/subsystem/wardrobe.dm index 55ab24c3d69..e255b66223f 100644 --- a/code/controllers/subsystem/wardrobe.dm +++ b/code/controllers/subsystem/wardrobe.dm @@ -43,7 +43,6 @@ SUBSYSTEM_DEF(wardrobe) setup_callbacks() load_outfits() load_species() - load_pda_nicknacks() load_storage_contents() hard_refresh_queue() stock_hit = 0 @@ -304,9 +303,6 @@ SUBSYSTEM_DEF(wardrobe) /// Mind this /datum/controller/subsystem/wardrobe/proc/setup_callbacks() var/list/play_with = new /list(WARDROBE_CALLBACK_REMOVE) // Turns out there's a global list of pdas. Let's work around that yeah? - play_with[WARDROBE_CALLBACK_INSERT] = CALLBACK(null, /obj/item/pda/proc/display_pda) - play_with[WARDROBE_CALLBACK_REMOVE] = CALLBACK(null, /obj/item/pda/proc/cloak_pda) - initial_callbacks[/obj/item/pda] = play_with play_with = new /list(WARDROBE_CALLBACK_REMOVE) // Don't want organs rotting on the job play_with[WARDROBE_CALLBACK_INSERT] = CALLBACK(null, /obj/item/organ/proc/enter_wardrobe) @@ -336,19 +332,11 @@ SUBSYSTEM_DEF(wardrobe) canonize_type(species_request) CHECK_TICK -/datum/controller/subsystem/wardrobe/proc/load_pda_nicknacks() - for(var/obj/item/pda/pager as anything in typesof(/obj/item/pda)) - var/obj/item/pda/flip_phone = new pager() - for(var/datum/outfit_item_type as anything in flip_phone.get_types_to_preload()) - canonize_type(outfit_item_type) - qdel(flip_phone) - CHECK_TICK - /datum/controller/subsystem/wardrobe/proc/load_storage_contents() for(var/obj/item/storage/crate as anything in subtypesof(/obj/item/storage)) if(!initial(crate.preload)) continue - var/obj/item/pda/another_crate = new crate() + var/obj/item/storage/another_crate = new crate() //Unlike other uses, I really don't want people being lazy with this one. var/list/somehow_more_boxes = another_crate.get_types_to_preload() if(!length(somehow_more_boxes)) diff --git a/code/datums/action.dm b/code/datums/action.dm index 4c97a81bcd3..0b180de7773 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -240,9 +240,9 @@ name = "Toggle Light" /datum/action/item_action/toggle_light/Trigger(trigger_flags) - if(istype(target, /obj/item/pda)) - var/obj/item/pda/P = target - P.toggle_light(owner) + if(istype(target, /obj/item/modular_computer)) + var/obj/item/modular_computer/mc = target + mc.toggle_flashlight() return ..() diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 1e24cb536be..60b50f7cb34 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -58,9 +58,9 @@ RegisterSignal(parent, COMSIG_IMPLANT_IMPLANTING, .proc/implanting) RegisterSignal(parent, COMSIG_IMPLANT_OTHER, .proc/old_implant) RegisterSignal(parent, COMSIG_IMPLANT_EXISTING_UPLINK, .proc/new_implant) - else if(istype(parent, /obj/item/pda)) - RegisterSignal(parent, COMSIG_PDA_CHANGE_RINGTONE, .proc/new_ringtone) - RegisterSignal(parent, COMSIG_PDA_CHECK_DETONATE, .proc/check_detonate) + else if(istype(parent, /obj/item/modular_computer/tablet)) + RegisterSignal(parent, COMSIG_TABLET_CHANGE_ID, .proc/new_ringtone) + RegisterSignal(parent, COMSIG_TABLET_CHECK_DETONATE, .proc/check_detonate) else if(istype(parent, /obj/item/radio)) RegisterSignal(parent, COMSIG_RADIO_NEW_FREQUENCY, .proc/new_frequency) else if(istype(parent, /obj/item/pen)) @@ -329,23 +329,21 @@ /datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text) SIGNAL_HANDLER - var/obj/item/pda/master = parent if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code))) if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code))) failsafe(user) return COMPONENT_STOP_RINGTONE_CHANGE + to_chat(user, span_notice("Unlock failure.")) return locked = FALSE interact(null, user) - to_chat(user, span_hear("The PDA softly beeps.")) - user << browse(null, "window=pda") - master.ui_mode = PDA_UI_HUB + to_chat(user, span_hear("The computer softly beeps.")) return COMPONENT_STOP_RINGTONE_CHANGE /datum/component/uplink/proc/check_detonate() SIGNAL_HANDLER - return COMPONENT_PDA_NO_DETONATE + return COMPONENT_TABLET_NO_DETONATE // Radio signal responses @@ -385,7 +383,7 @@ /datum/component/uplink/proc/setup_unlock_code() unlock_code = generate_code() var/obj/item/P = parent - if(istype(parent,/obj/item/pda)) + if(istype(parent,/obj/item/modular_computer/tablet)) unlock_note = "Uplink Passcode: [unlock_code] ([P.name])." else if(istype(parent,/obj/item/radio)) unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])." @@ -393,7 +391,7 @@ unlock_note = "Uplink Degrees: [english_list(unlock_code)] ([P.name])." /datum/component/uplink/proc/generate_code() - if(istype(parent,/obj/item/pda)) + if(istype(parent,/obj/item/modular_computer/tablet)) return "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" else if(istype(parent,/obj/item/radio)) return return_unused_frequency() diff --git a/code/datums/greyscale/config_types/greyscale_configs.dm b/code/datums/greyscale/config_types/greyscale_configs.dm index 9943bc62b12..c668c238785 100644 --- a/code/datums/greyscale/config_types/greyscale_configs.dm +++ b/code/datums/greyscale/config_types/greyscale_configs.dm @@ -107,40 +107,40 @@ icon_file = 'icons/mob/inhands/clothing_righthand.dmi' json_config = 'code/datums/greyscale/json_configs/jumpsuit_prison_inhand.json' -/datum/greyscale_config/pda +/datum/greyscale_config/tablet name = "PDA" - icon_file = 'icons/obj/pda.dmi' + icon_file = 'icons/obj/modular_tablet.dmi' json_config = 'code/datums/greyscale/json_configs/pda.json' -/datum/greyscale_config/pda/chaplain +/datum/greyscale_config/tablet/chaplain name = "Chaplain PDA" json_config = 'code/datums/greyscale/json_configs/pda_chaplain.json' -/datum/greyscale_config/pda/captain +/datum/greyscale_config/tablet/captain name = "Captain PDA" json_config = 'code/datums/greyscale/json_configs/pda_captain.json' -/datum/greyscale_config/pda/clown +/datum/greyscale_config/tablet/clown name = "Clown PDA" json_config = 'code/datums/greyscale/json_configs/pda_clown.json' -/datum/greyscale_config/pda/head +/datum/greyscale_config/tablet/head name = "Head PDA" json_config = 'code/datums/greyscale/json_configs/pda_head.json' -/datum/greyscale_config/pda/mime +/datum/greyscale_config/tablet/mime name = "Mime PDA" json_config = 'code/datums/greyscale/json_configs/pda_mime.json' -/datum/greyscale_config/pda/stripe_split +/datum/greyscale_config/tablet/stripe_split name = "Split Stripe PDA" json_config = 'code/datums/greyscale/json_configs/pda_stripe_split.json' -/datum/greyscale_config/pda/stripe_thick +/datum/greyscale_config/tablet/stripe_thick name = "Thick Stripe PDA" json_config = 'code/datums/greyscale/json_configs/pda_stripe_thick.json' -/datum/greyscale_config/pda/stripe_thick/head +/datum/greyscale_config/tablet/stripe_thick/head name = "Head Thick Stripe PDA" json_config = 'code/datums/greyscale/json_configs/pda_stripe_thick_head.json' diff --git a/code/datums/greyscale/json_configs/pda_clown.json b/code/datums/greyscale/json_configs/pda_clown.json index 0d31131b2c8..e9be8922369 100644 --- a/code/datums/greyscale/json_configs/pda_clown.json +++ b/code/datums/greyscale/json_configs/pda_clown.json @@ -2,24 +2,7 @@ "pda": [ { "type": "icon_state", - "icon_state": "pda_base", - "blend_mode": "overlay", - "color_ids": [ 1 ] - }, - { - "type": "icon_state", - "icon_state": "pda_stripe_clown", - "blend_mode": "overlay" - }, - { - "type": "icon_state", - "icon_state": "pda_buttons", - "blend_mode": "overlay", - "color_ids": [ 2 ] - }, - { - "type": "icon_state", - "icon_state": "pda_screen_borders", + "icon_state": "pda-clown", "blend_mode": "overlay" } ] diff --git a/code/datums/mind.dm b/code/datums/mind.dm index ecd09ff854d..8a26ef8f2c8 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -384,7 +384,7 @@ return var/list/all_contents = traitor_mob.get_all_contents() - var/obj/item/pda/PDA = locate() in all_contents + var/obj/item/modular_computer/tablet/pda/PDA = locate() in all_contents var/obj/item/radio/R = locate() in all_contents var/obj/item/pen/P @@ -437,7 +437,7 @@ if(uplink_loc == R) unlock_text = "Your Uplink is cunningly disguised as your [R.name]. Simply dial the frequency [format_frequency(new_uplink.unlock_code)] to unlock its hidden features." else if(uplink_loc == PDA) - unlock_text = "Your Uplink is cunningly disguised as your [PDA.name]. Simply enter the code \"[new_uplink.unlock_code]\" into the ringtone select to unlock its hidden features." + unlock_text = "Your Uplink is cunningly disguised as your [PDA.name]. Simply enter the code \"[new_uplink.unlock_code]\" into the ring tone selection to unlock its hidden features." else if(uplink_loc == P) unlock_text = "Your Uplink is cunningly disguised as your [P.name]. Simply twist the top of the pen [english_list(new_uplink.unlock_code)] from its starting position to unlock its hidden features." new_uplink.unlock_text = unlock_text diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index dca34cb0768..cca8d6cf79f 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -1,6 +1,6 @@ /// Basic machine used to paint PDAs and re-trim ID cards. /obj/machinery/pdapainter - name = "\improper PDA & ID Painter" + name = "\improper Tablet & ID Painter" desc = "A painting machine that can be used to paint PDAs and trim IDs. To use, simply insert the item and choose the desired preset." icon = 'icons/obj/pda.dmi' icon_state = "pdapainter" @@ -10,16 +10,14 @@ /// Current ID card inserted into the machine. var/obj/item/card/id/stored_id_card = null /// Current PDA inserted into the machine. - var/obj/item/pda/stored_pda = null + var/obj/item/modular_computer/tablet/pda/stored_pda = null /// A blacklist of PDA types that we should not be able to paint. var/static/list/pda_type_blacklist = list( - /obj/item/pda/ai/pai, - /obj/item/pda/ai, - /obj/item/pda/heads, - /obj/item/pda/clear, - /obj/item/pda/syndicate, - /obj/item/pda/chameleon, - /obj/item/pda/chameleon/broken) + /obj/item/modular_computer/tablet/pda/heads, + /obj/item/modular_computer/tablet/pda/clear, + /obj/item/modular_computer/tablet/pda/syndicate, + /obj/item/modular_computer/tablet/pda/chameleon, + /obj/item/modular_computer/tablet/pda/chameleon/broken) /// A list of the PDA types that this machine can currently paint. var/list/pda_types = list() /// A list of the card trims that this machine can currently imprint onto a card. @@ -132,11 +130,7 @@ to_chat(user, span_warning("The machine rejects your [O]. This ID card does not appear to be compatible with the PDA Painter.")) return - if(istype(O, /obj/item/pda/chameleon)) - to_chat(user, span_warning("The machine rejects your [O]. This PDA does not appear to be compatible with the PDA Painter.")) - return - - if(istype(O, /obj/item/pda)) + if(istype(O, /obj/item/modular_computer/tablet/pda)) insert_pda(O, user) return @@ -177,7 +171,7 @@ * * new_pda - The PDA to insert. * * user - The user to try and eject the PDA into the hands of. */ -/obj/machinery/pdapainter/proc/insert_pda(obj/item/pda/new_pda, mob/living/user) +/obj/machinery/pdapainter/proc/insert_pda(obj/item/modular_computer/tablet/pda/new_pda, mob/living/user) if(!istype(new_pda)) return FALSE @@ -296,7 +290,7 @@ return TRUE var/obj/item/held_item = usr.get_active_held_item() - if(istype(held_item, /obj/item/pda)) + if(istype(held_item, /obj/item/modular_computer/tablet/pda)) // If we successfully inserted, we've ejected the old item. Return early. if(insert_pda(held_item, usr)) return TRUE @@ -326,7 +320,7 @@ return TRUE var/selection = params["selection"] - var/obj/item/pda/pda_path = /obj/item/pda + var/obj/item/modular_computer/tablet/pda/pda_path = /obj/item/modular_computer/tablet/pda for(var/path in pda_types) if(pda_types[path] == selection) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 690227aea74..b7849522e05 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -326,7 +326,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0) return // OTHER - if((istype(I, /obj/item/paper) || istype(I, /obj/item/pda)) && isliving(user)) + if((istype(I, /obj/item/paper) || istype(I, /obj/item/modular_computer/tablet)) && isliving(user)) var/mob/living/paper_user = user var/itemname = "" @@ -335,10 +335,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0) var/obj/item/paper/pressed_paper = I itemname = pressed_paper.name info = pressed_paper.info - else - var/obj/item/pda/pressed_pda = I - itemname = pressed_pda.name - info = pressed_pda.notehtml + if(istype(I, /obj/item/modular_computer/tablet)) + var/obj/item/modular_computer/tablet/computer = I + itemname = computer.name + info = computer.note itemname = sanitize(itemname) to_chat(paper_user, span_notice("You hold \the [itemname] up to the camera...")) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index b1ee7941711..ab3a22ac153 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -895,7 +895,6 @@ #undef IMPORTANT_ACTION_COOLDOWN #undef EMERGENCY_ACCESS_COOLDOWN -#undef MAX_STATUS_LINE_LENGTH #undef STATE_BUYING_SHUTTLE #undef STATE_CHANGING_STATUS #undef STATE_MAIN diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index a11e4c4d637..834778083bb 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -869,14 +869,14 @@ What a mess.*/ if (!fine || QDELETED(usr) || QDELETED(src) || !canUseSecurityRecordsConsole(usr, t1, null, a2)) return var/datum/data/crime/crime = GLOB.data_core.createCrimeEntry(t1, "", authenticated, station_time_timestamp(), fine) - for (var/obj/item/pda/P in GLOB.PDAs) - if(P.owner == active1.fields["name"]) + for (var/obj/item/modular_computer/tablet in GLOB.TabletMessengers) + if(tablet.saved_identification == active1.fields["name"]) var/message = "You have been fined [fine] credits for '[t1]'. Fines may be paid at security." - var/datum/signal/subspace/messaging/pda/signal = new(src, list( + var/datum/signal/subspace/messaging/tablet_msg/signal = new(src, list( "name" = "Security Citation", "job" = "Citation Server", "message" = message, - "targets" = list(STRINGIFY_PDA_TARGET(P.owner, P.ownjob)), + "targets" = list(tablet), "automated" = TRUE )) signal.send_to_receivers() diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index a50ac2de09f..9162403cf5c 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -96,7 +96,7 @@ if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE) return // prevent intraction when T-scanner revealed - else if (istype(I, /obj/item/card/id)||istype(I, /obj/item/pda)) + else if (istype(I, /obj/item/card/id) || istype(I, /obj/item/modular_computer/tablet)) if(open) if (src.allowed(user)) src.locked = !src.locked diff --git a/code/game/machinery/telecomms/computers/message.dm b/code/game/machinery/telecomms/computers/message.dm index 96ce880a8ae..5f9cd39505a 100644 --- a/code/game/machinery/telecomms/computers/message.dm +++ b/code/game/machinery/telecomms/computers/message.dm @@ -33,11 +33,6 @@ var/message = "System bootup complete. Please select an option." // The message that shows on the main menu. var/auth = FALSE // Are they authenticated? var/optioncount = 7 - // Custom Message Properties - var/customsender = "System Administrator" - var/obj/item/pda/customrecepient = null - var/customjob = "Admin" - var/custommessage = "This is a test, please ignore." /obj/machinery/computer/message_monitor/screwdriver_act(mob/living/user, obj/item/I) if(obj_flags & EMAGGED) @@ -137,7 +132,7 @@ var/index = 0 dat += "
Back - Refresh

" dat += "" - for(var/datum/data_pda_msg/pda in linkedServer.pda_msgs) + for(var/datum/data_tablet_msg/pda in linkedServer.pda_msgs) index++ if(index > 3000) break @@ -188,24 +183,6 @@ 10010000001110100011010000110000101110100001000000111010
001101001011011010110010100101110"} - //Fake messages - if(MSG_MON_SCREEN_CUSTOM_MSG) - dat += "
Back - Reset

" - - dat += {"
XSenderRecipientMessage
- - - - "} - //Sender - Sender's Job - Recepient - Message - //Al Green- Your Dad - Your Mom - WHAT UP!? - - dat += {" - - - "} - dat += "
SenderSender's JobRecipientMessage
[customsender][customjob][customrecepient ? customrecepient.owner : "NONE"][custommessage]

Send" - //Request Console Logs if(MSG_MON_SCREEN_REQUEST_LOGS) @@ -249,12 +226,6 @@ /obj/machinery/computer/message_monitor/proc/UnmagConsole() obj_flags &= ~EMAGGED -/obj/machinery/computer/message_monitor/proc/ResetMessage() - customsender = "System Administrator" - customrecepient = null - custommessage = "This is a test, please ignore." - customjob = "Admin" - /obj/machinery/computer/message_monitor/Topic(href, href_list) if(..()) return @@ -350,7 +321,7 @@ if(screen == MSG_MON_SCREEN_LOGS) if(LINKED_SERVER_NONRESPONSIVE) message = noserver - else //if(istype(href_list["delete_logs"], /datum/data_pda_msg)) + else if(istype(href_list["delete_logs"], /datum/data_tablet_msg)) linkedServer.pda_msgs -= locate(href_list["delete_logs"]) in linkedServer.pda_msgs message = span_notice("NOTICE: Log Deleted!") //Delete the request console log. @@ -359,71 +330,9 @@ if(screen == MSG_MON_SCREEN_REQUEST_LOGS) if(LINKED_SERVER_NONRESPONSIVE) message = noserver - else //if(istype(href_list["delete_logs"], /datum/data_pda_msg)) + else if(istype(href_list["delete_logs"], /datum/data_tablet_msg)) linkedServer.rc_msgs -= locate(href_list["delete_requests"]) in linkedServer.rc_msgs message = span_notice("NOTICE: Log Deleted!") - //Create a custom message - if (href_list["msg"]) - if(LINKED_SERVER_NONRESPONSIVE) - message = noserver - else if(auth) - screen = MSG_MON_SCREEN_CUSTOM_MSG - //Fake messaging selection - KEY REQUIRED - if (href_list["select"]) - if(LINKED_SERVER_NONRESPONSIVE) - message = noserver - screen = MSG_MON_SCREEN_MAIN - else - switch(href_list["select"]) - - //Reset - if("Reset") - ResetMessage() - - //Select Your Name - if("Sender") - customsender = tgui_input_text(usr, "Please enter the sender's name.", "Sender") || customsender - - //Select Receiver - if("Recepient") - //Get out list of viable PDAs - var/list/obj/item/pda/sendPDAs = get_viewable_pdas() - if(GLOB.PDAs && length(GLOB.PDAs) > 0) - customrecepient = tgui_input_list(usr, "Select a PDA from the list", "PDA Selection", sendPDAs) - else - customrecepient = null - - //Enter custom job - if("RecJob") - customjob = tgui_input_text(usr, "Please enter the sender's job.", "Job") || customjob - - //Enter message - if("Message") - custommessage = tgui_input_text(usr, "Please enter your message.", "Message") || custommessage - - //Send message - if("Send") - if(isnull(customsender) || customsender == "") - customsender = "UNKNOWN" - - if(isnull(customrecepient)) - message = span_notice("NOTICE: No recepient selected!") - return attack_hand(usr) - - if(isnull(custommessage) || custommessage == "") - message = span_notice("NOTICE: No message entered!") - return attack_hand(usr) - - var/datum/signal/subspace/messaging/pda/signal = new(src, list( - "name" = "[customsender]", - "job" = "[customjob]", - "message" = custommessage, - "targets" = list(STRINGIFY_PDA_TARGET(customrecepient.owner, customrecepient.ownjob)) - )) - // this will log the signal and transmit it to the target - linkedServer.receive_information(signal, null) - usr.log_message("(PDA: [name] | [usr.real_name]) sent \"[custommessage]\" to [signal.format_target()]", LOG_PDA) - //Request Console Logs - KEY REQUIRED if(href_list["view_requests"]) diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index e188640677c..fbf385a9044 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -82,7 +82,8 @@ active_power_usage = 100 circuit = /obj/item/circuitboard/machine/telecomms/message_server - var/list/datum/data_pda_msg/pda_msgs = list() + var/list/datum/data_tablet_msg/pda_msgs = list() + var/list/datum/data_tablet_msg/modular_msgs = list() var/list/datum/data_rc_msg/rc_msgs = list() var/decryptkey = "password" var/calibrating = 15 MINUTES //Init reads this and adds world.time, then becomes 0 when that time has passed and the machine works @@ -95,9 +96,9 @@ if (calibrating) calibrating += world.time say("Calibrating... Estimated wait time: [rand(3, 9)] minutes.") - pda_msgs += new /datum/data_pda_msg("System Administrator", "system", "This is an automated message. System calibration started at [station_time_timestamp()]") + pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", "This is an automated message. System calibration started at [station_time_timestamp()].") else - pda_msgs += new /datum/data_pda_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE) + pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE) /obj/machinery/telecomms/message_server/Destroy() for(var/obj/machinery/computer/message_monitor/monitor in GLOB.telecomms_list) @@ -121,7 +122,7 @@ . = ..() if(calibrating && calibrating <= world.time) calibrating = 0 - pda_msgs += new /datum/data_pda_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE) + pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE) /obj/machinery/telecomms/message_server/receive_information(datum/signal/subspace/messaging/signal, obj/machinery/telecomms/machine_from) // can't log non-message signals @@ -129,16 +130,16 @@ return // log the signal - if(istype(signal, /datum/signal/subspace/messaging/pda)) - var/datum/signal/subspace/messaging/pda/PDAsignal = signal - var/datum/data_pda_msg/M = new(PDAsignal.format_target(), "[PDAsignal.data["name"]] ([PDAsignal.data["job"]])", PDAsignal.data["message"], PDAsignal.data["photo"]) - pda_msgs += M - signal.logged = M + if(istype(signal, /datum/signal/subspace/messaging/tablet_msg)) + var/datum/signal/subspace/messaging/tablet_msg/PDAsignal = signal + var/datum/data_tablet_msg/msg = new(PDAsignal.format_target(), "[PDAsignal.data["name"]] ([PDAsignal.data["job"]])", PDAsignal.data["message"], PDAsignal.data["photo"]) + pda_msgs += msg + signal.logged = msg else if(istype(signal, /datum/signal/subspace/messaging/rc)) - var/datum/data_rc_msg/M = new(signal.data["rec_dpt"], signal.data["send_dpt"], signal.data["message"], signal.data["stamped"], signal.data["verified"], signal.data["priority"]) - signal.logged = M + var/datum/data_rc_msg/msg = new(signal.data["rec_dpt"], signal.data["send_dpt"], signal.data["message"], signal.data["stamped"], signal.data["verified"], signal.data["priority"]) + signal.logged = msg if(signal.data["send_dpt"]) // don't log messages not from a department but allow them to work - rc_msgs += M + rc_msgs += msg signal.data["reject"] = FALSE // pass it along to either the hub or the broadcaster @@ -172,23 +173,23 @@ copy.levels = levels return copy -// PDA signal datum -/datum/signal/subspace/messaging/pda/proc/format_target() +// Tablet message signal datum +/datum/signal/subspace/messaging/tablet_msg/proc/format_target() if (length(data["targets"]) > 1) return "Everyone" - return data["targets"][1] + var/obj/item/modular_computer/target = data["targets"][1] + return "[target.saved_identification] ([target.saved_job])" -/datum/signal/subspace/messaging/pda/proc/format_message() - if (logged && data["photo"]) - return "\"[data["message"]]\" (Photo)" +/datum/signal/subspace/messaging/tablet_msg/proc/format_message() return "\"[data["message"]]\"" -/datum/signal/subspace/messaging/pda/broadcast() +/datum/signal/subspace/messaging/tablet_msg/broadcast() if (!logged) // Can only go through if a message server logs it return - for (var/obj/item/pda/P in GLOB.PDAs) - if ("[P.owner] ([P.ownjob])" in data["targets"]) - P.receive_message(src) + for (var/obj/item/modular_computer/comp in data["targets"]) + var/obj/item/computer_hardware/hard_drive/drive = comp.all_components[MC_HDD] + for(var/datum/computer_file/program/messenger/app in drive.stored_files) + app.receive_message(src) // Request Console signal datum /datum/signal/subspace/messaging/rc/broadcast() @@ -200,14 +201,14 @@ Console.createmessage(data["sender"], data["send_dpt"], data["message"], data["verified"], data["stamped"], data["priority"], data["notify_freq"]) // Log datums stored by the message server. -/datum/data_pda_msg +/datum/data_tablet_msg var/sender = "Unspecified" var/recipient = "Unspecified" var/message = "Blank" // transferred message var/datum/picture/picture // attached photo var/automated = 0 //automated message -/datum/data_pda_msg/New(param_rec, param_sender, param_message, param_photo) +/datum/data_tablet_msg/New(param_rec, param_sender, param_message, param_photo) if(param_rec) recipient = param_rec if(param_sender) @@ -217,7 +218,7 @@ if(param_photo) picture = param_photo -/datum/data_pda_msg/Topic(href,href_list) +/datum/data_tablet_msg/Topic(href,href_list) ..() if(href_list["photo"]) var/mob/M = usr diff --git a/code/game/objects/effects/spawners/random/contraband.dm b/code/game/objects/effects/spawners/random/contraband.dm index acda79a3abc..9b09568be52 100644 --- a/code/game/objects/effects/spawners/random/contraband.dm +++ b/code/game/objects/effects/spawners/random/contraband.dm @@ -55,7 +55,7 @@ /obj/item/restraints/handcuffs, /obj/item/paper/fluff/jobs/prisoner/letter, /obj/item/storage/wallet/random, - /obj/item/pda, + /obj/item/modular_computer/tablet/pda, /obj/item/radio/off, ) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 023184271f8..a6c311b1cdb 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -909,7 +909,7 @@ /obj/item/card/id/advanced/Moved(atom/OldLoc, Dir) . = ..() - if(istype(OldLoc, /obj/item/pda) || istype(OldLoc, /obj/item/storage/wallet)) + if(istype(OldLoc, /obj/item/storage/wallet)) UnregisterSignal(OldLoc, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) if(istype(OldLoc, /obj/item/computer_hardware/card_slot)) @@ -921,7 +921,7 @@ var/obj/item/modular_computer/tablet/slot_holder = slot.holder UnregisterSignal(slot_holder, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) - if(istype(loc, /obj/item/pda) || istype(loc, /obj/item/storage/wallet)) + if(istype(loc, /obj/item/storage/wallet)) RegisterSignal(loc, COMSIG_ITEM_EQUIPPED, .proc/update_intern_status) RegisterSignal(loc, COMSIG_ITEM_DROPPED, .proc/remove_intern_status) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm deleted file mode 100644 index a2ef23449fc..00000000000 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ /dev/null @@ -1,1298 +0,0 @@ - -//The advanced pea-green monochrome lcd of tomorrow. - -GLOBAL_LIST_EMPTY(PDAs) - -#define PDA_SCANNER_NONE 0 -#define PDA_SCANNER_MEDICAL 1 -#define PDA_SCANNER_FORENSICS 2 //unused -#define PDA_SCANNER_REAGENT 3 -#define PDA_SCANNER_GAS 5 -#define PDA_SPAM_DELAY 2 MINUTES - -/obj/item/pda - name = "\improper standard PDA" - desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." - icon = 'icons/obj/pda.dmi' - icon_state = "pda" - inhand_icon_state = "electronic" - worn_icon_state = "pda" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - greyscale_config = /datum/greyscale_config/pda - greyscale_colors = "#999875#a92323" - item_flags = NOBLUDGEON - w_class = WEIGHT_CLASS_TINY - slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT - actions_types = list(/datum/action/item_action/toggle_light) - armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 100, ACID = 100) - resistance_flags = FIRE_PROOF | ACID_PROOF - light_system = MOVABLE_LIGHT_DIRECTIONAL - light_range = 2.3 - light_power = 0.6 - light_color = "#FFCC66" - light_on = FALSE - custom_materials = list(/datum/material/iron=300, /datum/material/glass=100, /datum/material/plastic=100) - - /// String name of owner - var/owner = null - /// Typepath of the default cartridge to use - var/default_cartridge = 0 - /// Current cartridge - var/obj/item/cartridge/cartridge = null - /// Controls what menu the PDA will display. 0 is hub; the rest are either built in or based on cartridge. - var/ui_mode = PDA_UI_HUB - /// Icon to be overlayed for message alerts. Taken from the pda icon file. - var/icon_alert = "pda-r" - /// Icon to be overlayed when an active pAI is slotted in. - var/icon_pai = "pai_overlay" - /// Same as above but for an inactive pAI. - var/icon_inactive_pai = "pai_off_overlay" - /** - * This int tells DM which font is currently selected and lets DM know when the last font has been selected - * so that it can cycle back to the first font when "toggle font" is pressed again. - */ - var/font_index = 0 - /// The currently selected font. - var/font_mode = "font-family:monospace;" - /// The currently selected background color. - var/background_color = "#808000" - - #define FONT_MONO "font-family:monospace;" - #define FONT_SHARE "font-family:\"Share Tech Mono\", monospace;letter-spacing:0px;" - #define FONT_ORBITRON "font-family:\"Orbitron\", monospace;letter-spacing:0px; font-size:15px" - #define FONT_VT "font-family:\"VT323\", monospace;letter-spacing:1px;" - #define MODE_MONO 0 - #define MODE_SHARE 1 - #define MODE_ORBITRON 2 - #define MODE_VT 3 - - //Secondary variables - var/scanmode = PDA_SCANNER_NONE - var/silent = FALSE //To beep or not to beep, that is the question - var/toff = FALSE //If TRUE, messenger disabled - var/tnote = null //Current Texts - var/last_text //No text spamming - var/last_everyone //No text for everyone spamming - var/last_noise //Also no honk spamming that's bad too - var/ttone = "beep" //The ringtone! - var/honkamt = 0 //How many honks left when infected with honk.exe - var/mimeamt = 0 //How many silence left when infected with mime.exe - var/note = "Congratulations, your station has chosen the Thinktronic 5230 Personal Data Assistant!" //Current note in the notepad function - var/notehtml = "" - var/notescanned = FALSE // True if what is in the notekeeper was from a paper. - var/hidden = FALSE // Is the PDA hidden from the PDA list? - var/emped = FALSE - var/equipped = FALSE //used here to determine if this is the first time its been picked up - var/allow_emojis = FALSE //if the pda can send emojis and actually have them parsed as such - var/sort_by_job = FALSE // If this is TRUE, will sort PDA list by job. - - var/obj/item/card/id/id = null //Making it possible to slot an ID card into the PDA so it can function as both. - var/ownjob = null //related to above - ///account id of the ID held - var/account_id - - var/obj/item/paicard/pai = null // A slot for a personal AI device - - var/datum/picture/picture //Scanned photo - - var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette) - //This is the typepath to load "into" the pda - var/obj/item/insert_type = /obj/item/pen - //This is the currently inserted item - var/obj/item/inserted_item - var/underline_flag = TRUE //flag for underline - -/obj/item/pda/suicide_act(mob/living/carbon/user) - var/deathMessage = msg_input(user) - if (!deathMessage) - deathMessage = "i ded" - user.visible_message(span_suicide("[user] is sending a message to the Grim Reaper! It looks like [user.p_theyre()] trying to commit suicide!")) - tnote += "→ To The Grim Reaper:
[deathMessage]
"//records a message in their PDA as being sent to the grim reaper - return BRUTELOSS - -/obj/item/pda/examine(mob/user) - . = ..() - if(!id && !inserted_item) - return - - if(id) - . += span_notice("Alt-click to remove the ID.") //won't name ID on examine in case it's stolen - - if(inserted_item && (!isturf(loc))) - . += span_notice("Ctrl-click to remove [inserted_item].") //traitor pens are disguised so we're fine naming them on examine - - if((!isnull(cartridge))) - . += span_notice("Ctrl+Shift-click to remove the cartridge.") //won't name cart on examine in case it's Detomatix - -/obj/item/pda/Initialize(mapload) - . = ..() - - GLOB.PDAs += src - if(default_cartridge) - cartridge = SSwardrobe.provide_type(default_cartridge, src) - cartridge.host_pda = src - if(insert_type) - inserted_item = SSwardrobe.provide_type(insert_type, src) - RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, .proc/on_light_eater) - - update_appearance() - -/obj/item/pda/Destroy() - GLOB.PDAs -= src - if(istype(id)) - QDEL_NULL(id) - if(istype(cartridge)) - QDEL_NULL(cartridge) - if(istype(pai)) - QDEL_NULL(pai) - if(istype(inserted_item)) - QDEL_NULL(inserted_item) - return ..() - -/obj/item/pda/equipped(mob/user, slot) - . = ..() - if(!equipped) - if(user.client) - background_color = user.client.prefs.read_preference(/datum/preference/color/pda_color) - switch(user.client.prefs.read_preference(/datum/preference/choiced/pda_style)) - if(MONO) - font_index = MODE_MONO - font_mode = FONT_MONO - if(SHARE) - font_index = MODE_SHARE - font_mode = FONT_SHARE - if(ORBITRON) - font_index = MODE_ORBITRON - font_mode = FONT_ORBITRON - if(VT) - font_index = MODE_VT - font_mode = FONT_VT - else - font_index = MODE_MONO - font_mode = FONT_MONO - equipped = TRUE - -/obj/item/pda/Exited(atom/movable/gone, direction) - . = ..() - if(gone == cartridge) - cartridge.host_pda = null - cartridge = null - if(gone == inserted_item) - inserted_item = null - -/obj/item/pda/proc/update_label() - name = "PDA-[owner] ([ownjob])" //Name generalisation - -/obj/item/pda/GetAccess() - if(id) - return id.GetAccess() - else - return ..() - -/obj/item/pda/get_id_examine_strings(mob/user) - . = ..() - if(id) - . += "\The [src] is displaying [id]." - . += id.get_id_examine_strings(user) - -/obj/item/pda/GetID() - return id - -/obj/item/pda/RemoveID() - return do_remove_id() - -/obj/item/pda/InsertID(obj/item/inserting_item) - var/obj/item/card/inserting_id = inserting_item.RemoveID() - if(!inserting_id) - return - insert_id(inserting_id) - if(id == inserting_id) - return TRUE - return FALSE - -/obj/item/pda/update_overlays() - . = ..() - var/init_icon = initial(icon) - if(!init_icon) - return - if(id) - . += mutable_appearance(init_icon, "id_overlay") - if(inserted_item) - . += mutable_appearance(init_icon, "insert_overlay") - if(light_on) - . += mutable_appearance(init_icon, "light_overlay") - if(pai) - if(pai.pai) - . += mutable_appearance(init_icon, icon_pai) - else - . += mutable_appearance(init_icon, icon_inactive_pai) - -/obj/item/pda/MouseDrop(mob/over, src_location, over_location) - var/mob/M = usr - if((M == over) && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - return attack_self(M) - return ..() - - -/obj/item/pda/attack_self_tk(mob/user) - to_chat(user, span_warning("The PDA's capacitive touch screen doesn't seem to respond!")) - return COMPONENT_CANCEL_ATTACK_CHAIN - - -/obj/item/pda/interact(mob/user) - if(!ISADVANCEDTOOLUSER(user)) - to_chat(user, span_warning("You don't have the dexterity to do this!")) - return - - if(HAS_TRAIT(src, TRAIT_PDA_MESSAGE_MENU_RIGGED) && ui_mode == PDA_UI_MESSENGER) - explode(user, from_message_menu = TRUE) - return - - ..() - - var/datum/asset/spritesheet/assets = get_asset_datum(/datum/asset/spritesheet/simple/pda) - assets.send(user) - - var/datum/asset/spritesheet/emoji_s = get_asset_datum(/datum/asset/spritesheet/chat) - emoji_s.send(user) //Already sent by chat but no harm doing this - - user.set_machine(src) - - var/dat = "Personal Data Assistant" - dat += assets.css_tag() - dat += emoji_s.css_tag() - - dat += "[PDAIMG(refresh)]Refresh" - - if ((!isnull(cartridge)) && ui_mode == PDA_UI_HUB) - dat += " | [PDAIMG(eject)]Eject [cartridge]" - if (ui_mode != PDA_UI_HUB) - dat += " | [PDAIMG(menu)]Return" - - else - dat += "
" - dat += "
Toggle Font" - dat += " | Change Color" - dat += " | Toggle Underline" //underline button - - dat += "
" - - dat += "
" - - if (!owner) - dat += "Warning: No owner information entered. Please swipe card.

" - dat += "[PDAIMG(refresh)]Retry" - else - switch (ui_mode) - if (PDA_UI_HUB) - dat += "

PERSONAL DATA ASSISTANT v.1.2

" - dat += "Owner: [owner], [ownjob]
" - dat += text("ID: [id ? "[id.registered_name], [id.assignment]" : "----------"]") - dat += text("
[id ? "Update PDA Info" : ""]

") - - dat += "[station_time_timestamp()]
" //:[world.time / 100 % 6][world.time / 100 % 10]" - dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer+540]
" - dat += "It has been [ROUND_TIME] since the emergency shuttle was last called." - - - dat += "

" - - dat += "

General Functions

" - dat += "" - if (cartridge.access & CART_ENGINE) - dat += "

Engineering Functions

" - dat += "" - if (cartridge.access & CART_MEDICAL) - dat += "

Medical Functions

" - dat += "" - if (cartridge.access & CART_SECURITY) - dat += "

Security Functions

" - dat += "" - if(cartridge.access & CART_QUARTERMASTER) - dat += "

Quartermaster Functions:

" - dat += "" - dat += "" - - dat += "

Utilities

" - dat += "" - - if (PDA_UI_NOTEKEEPER) - dat += "

[PDAIMG(notes)] Notekeeper V2.2

" - dat += "Edit
" - if(notescanned) - dat += "(This is a scanned image, editing it may cause some text formatting to change.)
" - dat += "
[(!notehtml ? note : notehtml)]" - - if (PDA_UI_MESSENGER) - dat += "

[PDAIMG(mail)] SpaceMessenger V3.9.6

" - dat += "[PDAIMG(bell)]Ringer: [silent == 1 ? "Off" : "On"] | " - dat += "[PDAIMG(mail)]Send / Receive: [toff == 1 ? "Off" : "On"] | " - dat += "[PDAIMG(bell)]Set Ringtone | " - dat += "[PDAIMG(mail)]Messages
" - dat += "Sorted by: [sort_by_job ? "Job" : "Name"]" - - if(cartridge) - dat += cartridge.message_header() - - dat += "

[PDAIMG(menu)] Detected PDAs

" - - dat += "" - if (count == 0) - dat += "None detected.
" - else if(cartridge?.spam_enabled) - dat += "Send To All" - if(PDA_UI_SKILL_TRACKER) - dat += "

[PDAIMG(mail)] ExperTrak® Skill Tracker V4.26.2

" - dat += "Thank you for choosing ExperTrak® brand software! ExperTrak® inc. is proud to be a Nanotrasen employee expertise and effectiveness department subsidary!" - dat += "

This software is designed to track and monitor your skill development as a Nanotrasen employee. Your job performance across different fields has been quantified and categorized below.
" - var/datum/mind/targetmind = user.mind - if(targetmind) - for (var/type in GLOB.skill_types) - var/datum/skill/S = GetSkillRef(type) - var/lvl_num = targetmind.get_skill_level(type) - var/lvl_name = uppertext(targetmind.get_skill_level_name(type)) - var/exp = targetmind.get_skill_exp(type) - var/xp_prog_to_level = targetmind.exp_needed_to_level_up(type) - var/xp_req_to_level = 0 - if (xp_prog_to_level && lvl_num < length(SKILL_EXP_LIST)) // is it even possible to level up? - xp_req_to_level = SKILL_EXP_LIST[lvl_num+1] - SKILL_EXP_LIST[lvl_num] - dat += "
[S.name]" - dat += "
[S.desc]" - dat += "" - if(PDA_UI_READ_MESSAGES) - if(icon_alert && !istext(icon_alert)) - cut_overlay(icon_alert) - icon_alert = initial(icon_alert) - - dat += "

[PDAIMG(mail)] SpaceMessenger V3.9.6

" - dat += "[PDAIMG(blank)]Clear Messages" - - dat += "

[PDAIMG(mail)] Messages

" - - dat += tnote - dat += "
" - - if (PDA_UI_ATMOS_SCAN) - dat += "

[PDAIMG(atmos)] Atmospheric Readings

" - - var/turf/T = user.loc - if (isnull(T)) - dat += "Unable to obtain a reading.
" - else - var/datum/gas_mixture/environment = T.return_air() - var/list/env_gases = environment.gases - - var/pressure = environment.return_pressure() - var/total_moles = environment.total_moles() - - dat += "Air Pressure: [round(pressure,0.1)] kPa
" - - if (total_moles) - for(var/id in env_gases) - var/gas_level = env_gases[id][MOLES]/total_moles - if(gas_level > 0) - dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100, 0.01)]%
" - - dat += "Temperature: [round(environment.temperature-T0C)]°C
" - dat += "
" - else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub. - dat += cartridge.generate_menu() - - dat += "" - - if (underline_flag) - dat = replacetext(dat, "text-decoration:none", "text-decoration:underline") - if (!underline_flag) - dat = replacetext(dat, "text-decoration:underline", "text-decoration:none") - - user << browse(dat, "window=pda;size=400x450;border=1;can_resize=1;can_minimize=0") - onclose(user, "pda", src) - -/obj/item/pda/Topic(href, href_list) - ..() - var/mob/living/U = usr - //Looking for master was kind of pointless since PDAs don't appear to have one. - - if(!href_list["close"] && usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - add_fingerprint(U) - U.set_machine(src) - - var/choice = text2num(href_list["choice"]) || href_list["choice"] - switch(choice) - -//BASIC FUNCTIONS=================================== - - if("Refresh")//Refresh, goes to the end of the proc. - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - - if ("Toggle_Font") - //CODE REVISION 2 - font_index = (font_index + 1) % 4 - - switch(font_index) - if (MODE_MONO) - font_mode = FONT_MONO - if (MODE_SHARE) - font_mode = FONT_SHARE - if (MODE_ORBITRON) - font_mode = FONT_ORBITRON - if (MODE_VT) - font_mode = FONT_VT - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if ("Change_Color") - var/new_color = input("Please enter a color name or hex value (Default is \'#808000\').",background_color)as color - background_color = new_color - - if ("Toggle_Underline") - underline_flag = !underline_flag - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - - if("Return")//Return - ui_mode = round(ui_mode/PDA_UI_RETURN_DIVIDER) - if(ISINRANGE(ui_mode, PDA_UI_REDIRECT_HUB_MIN, PDA_UI_REDIRECT_HUB_MAX))//Fix for cartridges. Redirects to hub. - ui_mode = PDA_UI_HUB - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if ("Authenticate")//Checks for ID - id_check(U) - if("UpdateInfo") - ownjob = id.assignment - update_label() - if(!silent) - playsound(src, 'sound/machines/terminal_processing.ogg', 15, TRUE) - addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/machines/terminal_success.ogg', 15, TRUE), 1.3 SECONDS) - if("Eject")//Ejects the cart, only done from hub. - eject_cart(U) - if(!silent) - playsound(src, 'sound/machines/terminal_eject.ogg', 50, TRUE) - -//MENU FUNCTIONS=================================== - - if(PDA_UI_HUB) - ui_mode = PDA_UI_HUB - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if(PDA_UI_NOTEKEEPER) - ui_mode = PDA_UI_NOTEKEEPER - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if(PDA_UI_MESSENGER) - if(HAS_TRAIT(src, TRAIT_PDA_MESSAGE_MENU_RIGGED)) - explode(U, from_message_menu = TRUE) - return - ui_mode = PDA_UI_MESSENGER - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if(PDA_UI_READ_MESSAGES) - ui_mode = PDA_UI_READ_MESSAGES - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if(PDA_UI_ATMOS_SCAN) - ui_mode = PDA_UI_ATMOS_SCAN - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - - -//MAIN FUNCTIONS=================================== - - if("Light") - toggle_light(U) - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if("Medical Scan") - if(scanmode == PDA_SCANNER_MEDICAL) - scanmode = PDA_SCANNER_NONE - else if((!isnull(cartridge)) && (cartridge.access & CART_MEDICAL)) - scanmode = PDA_SCANNER_MEDICAL - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - if("Reagent Scan") - if(scanmode == PDA_SCANNER_REAGENT) - scanmode = PDA_SCANNER_NONE - else if((!isnull(cartridge)) && (cartridge.access & CART_REAGENT_SCANNER)) - scanmode = PDA_SCANNER_REAGENT - if("Honk") - if ( !(last_noise && world.time < last_noise + 20) ) - playsound(src, 'sound/items/bikehorn.ogg', 50, TRUE) - last_noise = world.time - if("Trombone") - if ( !(last_noise && world.time < last_noise + 20) ) - playsound(src, 'sound/misc/sadtrombone.ogg', 50, TRUE) - last_noise = world.time - if("Gas Scan") - if(scanmode == PDA_SCANNER_GAS) - scanmode = PDA_SCANNER_NONE - else if((!isnull(cartridge)) && (cartridge.access & CART_ATMOS)) - scanmode = PDA_SCANNER_GAS - if(!silent) - playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE) - - -//NOTEKEEPER FUNCTIONS=================================== - - if ("Edit") - var/n = tgui_input_text(U, "Please enter message", name, note, multiline = TRUE) - if (in_range(src, U) && loc == U) - if (ui_mode == PDA_UI_NOTEKEEPER && n) - note = n - notehtml = parsemarkdown(n, U) - notescanned = FALSE - else - U << browse(null, "window=pda") - return - -//MESSENGER FUNCTIONS=================================== - - if("Toggle Messenger") - toff = !toff - if("Toggle Ringer")//If viewing texts then erase them, if not then toggle silent status - silent = !silent - if("Clear")//Clears messages - tnote = null - if("Ringtone") - var/t = tgui_input_text(U, "Enter a new ringtone", "PDA Ringtone", ttone, 20) - if(in_range(src, U) && loc == U && t) - if(SEND_SIGNAL(src, COMSIG_PDA_CHANGE_RINGTONE, U, t) & COMPONENT_STOP_RINGTONE_CHANGE) - U << browse(null, "window=pda") - return - else - ttone = t - else - U << browse(null, "window=pda") - return - if("Message") - create_message(U, locate(href_list["target"]) in GLOB.PDAs) - if("Mess_us_up") - if(!HAS_TRAIT(src, TRAIT_PDA_CAN_EXPLODE)) //in case someone ever tries to call this with forged hrefs - return - explode(U, locate(href_list["target"])) - - if("Sorting Mode") - sort_by_job = !sort_by_job - - if("MessageAll") - if(cartridge?.spam_enabled) - send_to_all(U) - - if("cart") - if(cartridge) - cartridge.special(U, href_list) - else - U << browse(null, "window=pda") - return - -//pAI FUNCTIONS=================================== - - if("pai") - switch(href_list["option"]) - if("1") // Configure pAI device - pai.attack_self(U) - if("2") // Eject pAI device - usr.put_in_hands(pai) - pai.slotted = FALSE - to_chat(usr, span_notice("You remove the pAI from the [name].")) - -//SKILL FUNCTIONS=================================== - - if("SkillReward") - var/type = text2path(href_list["skill"]) - var/datum/skill/S = GetSkillRef(type) - var/datum/mind/mind = U.mind - var/new_level = mind.get_skill_level(type) - S.try_skill_reward(mind, new_level) - -//LINK FUNCTIONS=================================== - - else - ui_mode = max(choice, PDA_UI_HUB) - - else//If not in range, can't interact or not using the pda. - U.unset_machine() - U << browse(null, "window=pda") - return - -//EXTRA FUNCTIONS=================================== - - if (ui_mode == PDA_UI_MESSENGER || ui_mode == PDA_UI_READ_MESSAGES)//To clear message overlays. - update_appearance() - - if ((honkamt > 0) && (prob(60)))//For clown virus. - honkamt-- - playsound(src, 'sound/items/bikehorn.ogg', 30, TRUE) - - if(U.machine == src && href_list["skiprefresh"]!="1")//Final safety. - attack_self(U)//It auto-closes the menu prior if the user is not in range and so on. - else - U.unset_machine() - U << browse(null, "window=pda") - return - -/obj/item/pda/proc/remove_id(mob/user) - if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) - return - do_remove_id(user) - - -/obj/item/pda/proc/do_remove_id(mob/user) - if(!id) - return - if(user) - user.put_in_hands(id) - to_chat(user, span_notice("You remove the ID from the [name].")) - else - id.forceMove(get_turf(src)) - - . = id - id = null - updateSelfDialog() - update_appearance() - playsound(src, 'sound/machines/terminal_eject.ogg', 50, TRUE) - - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.wear_id == src) - H.sec_hud_set_ID() - - update_slot_icon() - - -/obj/item/pda/proc/msg_input(mob/living/U = usr, rigged = FALSE) - var/t = tgui_input_text(U, "Enter a message", "PDA Messaging") - if (!t || toff) - return - if(!U.canUseTopic(src, BE_CLOSE)) - return - if(emped) - t = Gibberish(t, TRUE) - return t - -/** - * Prompts the user to input and send a message to another PDA. - * the everyone arg is used for mass messaging from lawyer and captain carts. - * rigged for PDA bombs. fakename and fakejob for forged messages (also PDA bombs). - */ -/obj/item/pda/proc/send_message(mob/living/user, list/obj/item/pda/targets, everyone = FALSE, rigged = FALSE, fakename, fakejob) - var/message = msg_input(user, rigged) - if(!message || !targets.len) - return FALSE - if((last_text && world.time < last_text + 10) || (everyone && last_everyone && world.time < last_everyone + PDA_SPAM_DELAY)) - return FALSE - - var/turf/position = get_turf(src) - for(var/obj/item/jammer/jammer as anything in GLOB.active_jammers) - var/turf/jammer_turf = get_turf(jammer) - if(position?.z == jammer_turf.z && (get_dist(position, jammer_turf) <= jammer.range)) - return FALSE - - var/list/filter_result = CAN_BYPASS_FILTER(user) ? null : is_ic_filtered_for_pdas(message) - if (filter_result) - REPORT_CHAT_FILTER_TO_USER(user, filter_result) - return FALSE - - var/list/soft_filter_result = CAN_BYPASS_FILTER(user) ? null : is_soft_ic_filtered_for_pdas(message) - if (soft_filter_result) - if(tgui_alert(usr,"Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to send it?", "Soft Blocked Word", list("Yes", "No")) != "Yes") - return FALSE - message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[html_encode(message)]\"") - log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[message]\"") - - if(prob(1)) - message += "\nSent from my PDA" - // Send the signal - var/list/string_targets = list() - for (var/obj/item/pda/P in targets) - if (P.owner && P.ownjob) // != src is checked by the UI - string_targets += STRINGIFY_PDA_TARGET(P.owner, P.ownjob) - for (var/obj/machinery/computer/message_monitor/M in targets) - // In case of "Reply" to a message from a console, this will make the - // message be logged successfully. If the console is impersonating - // someone by matching their name and job, the reply will reach the - // impersonated PDA. - string_targets += STRINGIFY_PDA_TARGET(M.customsender, M.customjob) - if (!string_targets.len) - return FALSE - - var/datum/signal/subspace/messaging/pda/signal = new(src, list( - "name" = "[fakename || owner]", - "job" = "[fakejob || ownjob]", - "message" = message, - "targets" = string_targets, - "emojis" = allow_emojis, - "rigged" = rigged, - )) - if(rigged) //Will skip the message server and go straight to the hub so it can't be cheesed by disabling the message server machine - signal.data["rigged_user"] = REF(user) // Used for bomb logging - signal.server_type = /obj/machinery/telecomms/hub - signal.data["reject"] = FALSE // Do not refuse the message - if (picture) - signal.data["photo"] = picture - signal.send_to_receivers() - - // If it didn't reach, note that fact - if (!signal.data["done"]) - to_chat(user, span_notice("ERROR: Server isn't responding.")) - if(!silent) - playsound(src, 'sound/machines/terminal_error.ogg', 15, TRUE) - return FALSE - - var/target_text = signal.format_target() - if(allow_emojis) - message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat - signal.data["message"] = emoji_parse(signal.data["message"]) - - // Log it in our logs - tnote += "→ To [target_text]:
[signal.format_message()]
" - // Show it to ghosts - var/ghost_message = span_name("[owner] [rigged ? "Rigged" : ""] PDA Message --> [span_name("[target_text]")]: [signal.format_message()]") - for(var/mob/M in GLOB.player_list) - if(isobserver(M) && (M.client?.prefs.chat_toggles & CHAT_GHOSTPDA)) - to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]") - // Log in the talk log - user.log_talk(message, LOG_PDA, tag="[rigged ? "Rigged" : ""] PDA: [initial(name)] to [target_text]") - if(rigged) - log_bomber(user, "sent a rigged PDA message (Name: [fakename || owner]. Job: [fakejob || ownjob]) to [english_list(string_targets)] [!is_special_character(user) ? "(SENT BY NON-ANTAG)" : ""]") - to_chat(user, span_info("PDA message sent to [target_text]: \"[message]\"")) - if(!silent) - playsound(src, 'sound/machines/terminal_success.ogg', 15, TRUE) - // Reset the photo - picture = null - last_text = world.time - if (everyone) - last_everyone = world.time - return TRUE - -/obj/item/pda/proc/receive_message(datum/signal/subspace/messaging/pda/signal) - var/ref_target = signal.data["rigged"] ? signal.data["rigged_user"] : REF(signal.source) - tnote += "← From [signal.data["name"]] ([signal.data["job"]]):
[signal.format_message()]
" - - if (!silent) - if(HAS_TRAIT(SSstation, STATION_TRAIT_PDA_GLITCHED)) - playsound(src, pick('sound/machines/twobeep_voice1.ogg', 'sound/machines/twobeep_voice2.ogg'), 50, TRUE) - else - playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE) - audible_message("[icon2html(src, hearers(src))] *[ttone]*", null, 3) - //Search for holder of the PDA. - var/mob/living/L = null - if(loc && isliving(loc)) - L = loc - //Maybe they are a pAI! - else - L = get(src, /mob/living/silicon) - - if(L && (L.stat == CONSCIOUS || L.stat == SOFT_CRIT)) - var/reply = "(Reply)" - var/hrefstart - var/hrefend - if (isAI(L)) - hrefstart = "" - hrefend = "" - - if(signal.data["automated"]) - reply = "\[Automated Message\]" - - var/inbound_message = signal.format_message() - if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis - inbound_message = emoji_parse(inbound_message) - - to_chat(L, "[icon2html(src)] PDA message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [inbound_message] [reply]") - - update_appearance() - if(istext(icon_alert)) - icon_alert = mutable_appearance(initial(icon), icon_alert) - add_overlay(icon_alert) - -/obj/item/pda/proc/send_to_all(mob/living/U) - if (last_everyone && world.time < last_everyone + PDA_SPAM_DELAY) - to_chat(U,span_warning("Send To All function is still on cooldown.")) - return - send_message(U,get_viewable_pdas(), TRUE) - -/obj/item/pda/proc/create_message(mob/living/U, obj/item/pda/P) - send_message(U,list(P)) - -/obj/item/pda/AltClick(mob/user) - ..() - - if(id) - remove_id(user) - else - remove_pen(user) - -/obj/item/pda/CtrlClick(mob/user) - ..() - - if(isturf(loc)) //stops the user from dragging the PDA by ctrl-clicking it. - return - - remove_pen(user) - -/obj/item/pda/CtrlShiftClick(mob/user) - ..() - eject_cart(user) - -/obj/item/pda/verb/verb_toggle_light() - set name = "Toggle light" - set category = "Object" - set src in oview(1) - - toggle_light(usr) - -/obj/item/pda/verb/verb_remove_id() - set category = "Object" - set name = "Eject ID" - set src in usr - - if(id) - remove_id(usr) - else - to_chat(usr, span_warning("This PDA does not have an ID in it!")) - -/obj/item/pda/verb/verb_remove_pen() - set category = "Object" - set name = "Remove Pen" - set src in usr - - remove_pen(usr) - -/obj/item/pda/verb/verb_eject_cart() - set category = "Object" - set name = "Eject Cartridge" - set src in usr - - eject_cart(usr) - -/obj/item/pda/proc/toggle_light(mob/user) - if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE)) - return - if(light_on) - set_light_on(FALSE) - else if(light_range) - set_light_on(TRUE) - update_appearance() - update_action_buttons(force = TRUE) - -/// Special light eater handling -/obj/item/pda/proc/on_light_eater(obj/item/pda/source, datum/light_eater) - SIGNAL_HANDLER - set_light_on(FALSE) - set_light_range(0) //We won't be turning on again. - update_appearance() - visible_message(span_danger("The light in [src] shorts out!")) - return COMPONENT_BLOCK_LIGHT_EATER - -/obj/item/pda/proc/remove_pen(mob/user) - - if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) //TK doesn't work even with this removed but here for readability - return - - if(inserted_item) - to_chat(user, span_notice("You remove [inserted_item] from [src].")) - user.put_in_hands(inserted_item) //Don't need to manage the pen ref, handled on Exited() - update_appearance() - playsound(src, 'sound/machines/pda_button2.ogg', 50, TRUE) - else - to_chat(user, span_warning("This PDA does not have a pen in it!")) - -/obj/item/pda/proc/eject_cart(mob/user) - if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) //TK disabled to stop cartridge teleporting into hand - return - if (!isnull(cartridge)) - to_chat(user, span_notice("You eject [cartridge] from [src].")) - user.put_in_hands(cartridge) //We don't manage reference clearing here, dealt with in Exited() - scanmode = PDA_SCANNER_NONE - updateSelfDialog() - update_appearance() - -//trying to insert or remove an id -/obj/item/pda/proc/id_check(mob/user, obj/item/card/id/I) - if(!I) - if(id && (src in user.contents)) - remove_id(user) - return TRUE - else - var/obj/item/card/id/C = user.get_active_held_item() - if(istype(C)) - I = C - - if(I?.registered_name) - if(!user.transferItemToLoc(I, src)) - return FALSE - insert_id(I, user) - update_appearance() - playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE) - return TRUE - - -/obj/item/pda/proc/insert_id(obj/item/card/id/inserting_id, mob/user) - var/obj/old_id = id - id = inserting_id - if(ishuman(loc)) - var/mob/living/carbon/human/human_wearer = loc - if(human_wearer.wear_id == src) - human_wearer.sec_hud_set_ID() - if(old_id) - if(user) - user.put_in_hands(old_id) - else - old_id.forceMove(get_turf(src)) - - update_slot_icon() - - -/obj/item/pda/pre_attack(obj/target, mob/living/user, params) - if(!ismachinery(target)) - return ..() - var/obj/machinery/target_machine = target - if(!target_machine.panel_open && !istype(target, /obj/machinery/computer)) - return ..() - if(!istype(cartridge, /obj/item/cartridge/virus/clown)) - return ..() - var/obj/item/cartridge/virus/installed_cartridge = cartridge - - if(installed_cartridge.charges <=0) - to_chat(user, span_notice("Out of charges.")) - return ..() - to_chat(user, span_notice("You upload the virus to the airlock controller!")) - var/sig_list - if(istype(target,/obj/machinery/door/airlock)) - sig_list += list(COMSIG_AIRLOCK_OPEN, COMSIG_AIRLOCK_CLOSE) - else - sig_list += list(COMSIG_ATOM_ATTACK_HAND) - target.AddComponent(/datum/component/sound_player, uses = rand(15,20), signal_list = sig_list) - installed_cartridge.charges-- - return TRUE - - -// access to status display signals -/obj/item/pda/attackby(obj/item/C, mob/user, params) - if(istype(C, /obj/item/cartridge)) - if(!user.transferItemToLoc(C, src)) - return - eject_cart(user) - cartridge = C - cartridge.host_pda = src - to_chat(user, span_notice("You insert [cartridge] into [src].")) - updateSelfDialog() - update_appearance() - playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE) - - else if(istype(C, /obj/item/card/id)) - var/obj/item/card/id/idcard = C - if(!idcard.registered_name) - to_chat(user, span_warning("\The [src] rejects the ID!")) - if(!silent) - playsound(src, 'sound/machines/terminal_error.ogg', 50, TRUE) - return - if(!owner) - owner = idcard.registered_name - ownjob = idcard.assignment - update_label() - to_chat(user, span_notice("Card scanned.")) - if(!silent) - playsound(src, 'sound/machines/terminal_success.ogg', 50, TRUE) - else - if(!id_check(user, idcard)) - return - to_chat(user, span_notice("You put the ID into \the [src]'s slot.")) - updateSelfDialog()//Update self dialog on success. - - return //Return in case of failed check or when successful. - updateSelfDialog()//For the non-input related code. - else if(istype(C, /obj/item/paicard) && !pai) - if(!user.transferItemToLoc(C, src)) - return - pai = C - pai.slotted = TRUE - to_chat(user, span_notice("You slot \the [C] into [src].")) - update_appearance() - updateUsrDialog() - else if(is_type_in_list(C, contained_item)) //Checks if there is a pen - if(inserted_item) - to_chat(user, span_warning("There is already \a [inserted_item] in \the [src]!")) - else - if(!user.transferItemToLoc(C, src)) - return - to_chat(user, span_notice("You slide \the [C] into \the [src].")) - inserted_item = C - update_appearance() - playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE) - else if(istype(C, /obj/item/photo)) - var/obj/item/photo/P = C - picture = P.picture - to_chat(user, span_notice("You scan \the [C].")) - // Check to see if we have an ID inside, and a valid input for money - else if(id && iscash(C)) - id.attackby(C, user) // If we do, try and put that attacking object in - else - return ..() - -/obj/item/pda/attack(mob/living/carbon/C, mob/living/user) - if(istype(C)) - switch(scanmode) - - if(PDA_SCANNER_MEDICAL) - C.visible_message(span_notice("[user] analyzes [C]'s vitals.")) - healthscan(user, C, 1) - add_fingerprint(user) - -/obj/item/pda/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity) - . = ..() - if(!proximity) - return - switch(scanmode) - if(PDA_SCANNER_REAGENT) - if(!isnull(A.reagents)) - if(A.reagents.reagent_list.len > 0) - var/reagents_length = A.reagents.reagent_list.len - to_chat(user, span_notice("[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.")) - for (var/re in A.reagents.reagent_list) - to_chat(user, span_notice("\t [re]")) - else - to_chat(user, span_notice("No active chemical agents found in [A].")) - else - to_chat(user, span_notice("No significant chemical agents found in [A].")) - - if(PDA_SCANNER_GAS) - A.analyzer_act(user, src) - - if (!scanmode && istype(A, /obj/item/paper) && owner) - var/obj/item/paper/paper = A - if (!paper.get_info_length()) - to_chat(user, span_warning("Unable to scan! Paper is blank.")) - return - notehtml = paper.info - if(paper.add_info) - for(var/index in 1 to length(paper.add_info)) - var/list/style = paper.add_info_style[index] - notehtml += PAPER_MARK_TEXT(paper.add_info[index], style[ADD_INFO_COLOR], style[ADD_INFO_FONT]) - note = replacetext(notehtml, "
", "\[br\]") - note = replacetext(note, "
  • ", "\[*\]") - note = replacetext(note, "
      ", "\[list\]") - note = replacetext(note, "
    ", "\[/list\]") - note = html_encode(note) - notescanned = TRUE - to_chat(user, span_notice("Paper scanned. Saved to PDA's notekeeper.") ) - -/** - * Called when someone replies to a rigged PDA message. It explodes. - * from_message_menu : whether it's caused by the target opening the message menu too early. - */ -/obj/item/pda/proc/explode(mob/target, mob/bomber, from_message_menu = FALSE) - var/turf/T = get_turf(src) - - if(from_message_menu) - log_bomber(null, null, target, "'s PDA exploded as [target.p_they()] tried to open their PDA message menu because of a recent pda bomb.") - else - log_bomber(bomber, "successfully PDA-bombed", target, "as [target.p_they()] tried to reply to a rigged PDA message [bomber && !is_special_character(bomber) ? "(SENT BY NON-ANTAG)" : ""]") - - if (ismob(loc)) - var/mob/M = loc - M.show_message(span_userdanger("Your [src] explodes!"), MSG_VISUAL, span_warning("You hear a loud *pop*!"), MSG_AUDIBLE) - else - visible_message(span_danger("[src] explodes!"), span_warning("You hear a loud *pop*!")) - - target.client?.give_award(/datum/award/achievement/misc/clickbait, target) - - if(T) - T.hotspot_expose(700,125) - if(istype(cartridge, /obj/item/cartridge/virus/syndicate)) - explosion(src, devastation_range = -1, heavy_impact_range = 1, light_impact_range = 3, flash_range = 4) - else - explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flash_range = 3) - qdel(src) - -//AI verb and proc for sending PDA messages. - -/obj/item/pda/ai/verb/cmd_toggle_pda_receiver() - set category = "AI Commands" - set name = "PDA - Toggle Sender/Receiver" - - if(usr.stat == DEAD) - return //won't work if dead - var/mob/living/silicon/S = usr - if(istype(S) && !isnull(S.aiPDA)) - S.aiPDA.toff = !S.aiPDA.toff - to_chat(usr, span_notice("PDA sender/receiver toggled [(S.aiPDA.toff ? "Off" : "On")]!")) - else - to_chat(usr, "You do not have a PDA. You should make an issue report about this.") - -/obj/item/pda/ai/verb/cmd_toggle_pda_silent() - set category = "AI Commands" - set name = "PDA - Toggle Ringer" - - if(usr.stat == DEAD) - return //won't work if dead - var/mob/living/silicon/S = usr - if(istype(S) && !isnull(S.aiPDA)) - //0 - S.aiPDA.silent = !S.aiPDA.silent - to_chat(usr, span_notice("PDA ringer toggled [(S.aiPDA.silent ? "Off" : "On")]!")) - else - to_chat(usr, "You do not have a PDA. You should make an issue report about this.") - -/mob/living/silicon/proc/cmd_send_pdamesg(mob/user) - var/list/plist = list() - var/list/namecounts = list() - - if(aiPDA.toff) - to_chat(user, span_alert("Turn on your receiver in order to send messages.")) - return - - for (var/obj/item/pda/pda as anything in get_viewable_pdas()) - if (pda == src) - continue - else if (pda == aiPDA) - continue - - plist[avoid_assoc_duplicate_keys(pda.owner, namecounts)] = pda - - var/choice = tgui_input_list(user, "Please select a PDA", "PDA Messenger", sort_list(plist)) - if (isnull(choice)) - return - - var/selected = plist[choice] - - if(aicamera.stored.len) - var/add_photo = tgui_alert(user,"Do you want to attach a photo?", "PDA Messenger", list("Yes","No")) - if(add_photo == "Yes") - var/datum/picture/Pic = aicamera.selectpicture(user) - aiPDA.picture = Pic - - if(incapacitated()) - return - - aiPDA.create_message(src, selected) - -/mob/living/silicon/proc/cmd_show_message_log(mob/user) - if(incapacitated()) - return - if(!isnull(aiPDA)) - var/HTML = "AI PDA Message Log[aiPDA.tnote]" - user << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0") - else - to_chat(user, span_warning("You do not have a PDA! You should make an issue report about this.")) - -// Pass along the pulse to atoms in contents, largely added so pAIs are vulnerable to EMP -/obj/item/pda/emp_act(severity) - . = ..() - if (!(. & EMP_PROTECT_CONTENTS)) - for(var/atom/A in src) - A.emp_act(severity) - if (!(. & EMP_PROTECT_SELF)) - emped++ - addtimer(CALLBACK(src, .proc/emp_end), 200 * severity) - -/obj/item/pda/proc/emp_end() - emped-- - -/proc/get_viewable_pdas(sort_by_job = FALSE) - . = list() - // Returns a list of PDAs which can be viewed from another PDA/message monitor., - var/sortmode - if(sort_by_job) - sortmode = /proc/cmp_pdajob_asc - else - sortmode = /proc/cmp_pdaname_asc - - for(var/obj/item/pda/P in sort_list(GLOB.PDAs, sortmode)) - if(!P.owner || P.toff || P.hidden) - continue - . += P - -/obj/item/pda/proc/pda_no_detonate() - SIGNAL_HANDLER - return COMPONENT_PDA_NO_DETONATE - -/// Return a list of types you want to pregenerate and use later -/// Do not pass in things that care about their init location, or expect extra input -/// Also as a curtiousy to me, don't pass in any bombs -/obj/item/pda/proc/get_types_to_preload() - var/list/preload = list() - preload += default_cartridge - preload += insert_type - return preload - -/// Callbacks for preloading pdas -/obj/item/pda/proc/display_pda() - GLOB.PDAs += src - -/// See above, we don't want jerry from accounting to try and message nullspace his new bike -/obj/item/pda/proc/cloak_pda() - GLOB.PDAs -= src - -#undef PDA_SCANNER_NONE -#undef PDA_SCANNER_MEDICAL -#undef PDA_SCANNER_FORENSICS -#undef PDA_SCANNER_REAGENT -#undef PDA_SCANNER_GAS -#undef PDA_SPAM_DELAY diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm deleted file mode 100644 index e4db41d2841..00000000000 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ /dev/null @@ -1,258 +0,0 @@ -//Clown PDA is slippery. -/obj/item/pda/clown - name = "clown PDA" - default_cartridge = /obj/item/cartridge/virus/clown - insert_type = /obj/item/toy/crayon/rainbow - icon_state = "pda-clown" - greyscale_config = null - greyscale_config = null - desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings." - ttone = "honk" - -/obj/item/pda/clown/ComponentInitialize() - . = ..() - AddComponent(/datum/component/slippery/clowning, 120, NO_SLIP_WHEN_WALKING, CALLBACK(src, .proc/AfterSlip), slot_whitelist = list(ITEM_SLOT_ID, ITEM_SLOT_BELT)) - AddComponent(/datum/component/wearertargeting/sitcomlaughter, CALLBACK(src, .proc/after_sitcom_laugh)) - -/obj/item/pda/clown/proc/AfterSlip(mob/living/carbon/human/M) - if (istype(M) && (M.real_name != owner)) - var/obj/item/cartridge/virus/clown/cart = cartridge - if(istype(cart) && cart.charges < 5) - cart.charges++ - playsound(src,'sound/machines/ping.ogg',30,TRUE) - -/obj/item/pda/clown/proc/after_sitcom_laugh(mob/victim) - victim.visible_message("[src] lets out a burst of laughter!") - -//Mime PDA sends "silent" messages. -/obj/item/pda/mime - name = "mime PDA" - default_cartridge = /obj/item/cartridge/virus/mime - insert_type = /obj/item/toy/crayon/mime - greyscale_config = /datum/greyscale_config/pda/mime - greyscale_colors = "#e2e2e2#cc4242" - desc = "A portable microcomputer by Thinktronic Systems, LTD. The hardware has been modified for compliance with the vows of silence." - allow_emojis = TRUE - silent = TRUE - ttone = "silence" - -/obj/item/pda/mime/msg_input(mob/living/U = usr, rigged = FALSE) - if(rigged) - return ..() - if(emped || toff) - return - var/emojis = emoji_sanitize(stripped_input(U, "Please enter emojis", name)) - if(!emojis) - return - if(!U.canUseTopic(src, BE_CLOSE)) - return - return emojis - -// Special AI/pAI PDAs that cannot explode. -/obj/item/pda/ai - icon = null - greyscale_config = null - greyscale_colors = null - ttone = "data" - - -/obj/item/pda/ai/attack_self(mob/user) - if ((honkamt > 0) && (prob(60)))//For clown virus. - honkamt-- - playsound(loc, 'sound/items/bikehorn.ogg', 30, TRUE) - return - -/obj/item/pda/ai/pai - ttone = "assist" - -/obj/item/pda/ai/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_PDA_CHECK_DETONATE, .proc/pda_no_detonate) - -/obj/item/pda/medical - name = "medical PDA" - default_cartridge = /obj/item/cartridge/medical - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#e2e2e2#000099#5d99be" - -/obj/item/pda/viro - name = "virology PDA" - default_cartridge = /obj/item/cartridge/medical - greyscale_config = /datum/greyscale_config/pda/stripe_split - greyscale_colors = "#e2e2e2#355FAC#789876" - -/obj/item/pda/engineering - name = "engineering PDA" - default_cartridge = /obj/item/cartridge/engineering - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#C5994C#69DBF3#D9D65B" - -/obj/item/pda/security - name = "security PDA" - default_cartridge = /obj/item/cartridge/security - greyscale_colors = "#cc4242#0000cc" - -/obj/item/pda/detective - name = "detective PDA" - default_cartridge = /obj/item/cartridge/detective - greyscale_colors = "#90714F#990202" - -/obj/item/pda/warden - name = "warden PDA" - default_cartridge = /obj/item/cartridge/security - greyscale_config = /datum/greyscale_config/pda/stripe_split - greyscale_colors = "#cc4242#0000cc#666666" - -/obj/item/pda/janitor - name = "janitor PDA" - greyscale_colors = "#933ea8#235AB2" - ttone = "slip" - -/obj/item/pda/science - name = "scientist PDA" - default_cartridge = /obj/item/cartridge/signal/ordnance - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#e2e2e2#000099#9F5CA5" - ttone = "boom" - - -/obj/item/pda/heads - default_cartridge = /obj/item/cartridge/head - greyscale_config = /datum/greyscale_config/pda/head - greyscale_colors = "#789876#a92323" - -/obj/item/pda/heads/hop - name = "head of personnel PDA" - default_cartridge = /obj/item/cartridge/hop - -/obj/item/pda/heads/hos - name = "head of security PDA" - default_cartridge = /obj/item/cartridge/hos - greyscale_config = /datum/greyscale_config/pda/head - greyscale_colors = "#cc4242#0000cc" - -/obj/item/pda/heads/ce - name = "chief engineer PDA" - default_cartridge = /obj/item/cartridge/ce - greyscale_config = /datum/greyscale_config/pda/stripe_thick/head - greyscale_colors = "#C4A56D#69DBF3#e2e2e2" - -/obj/item/pda/heads/cmo - name = "chief medical officer PDA" - default_cartridge = /obj/item/cartridge/cmo - greyscale_config = /datum/greyscale_config/pda/stripe_thick/head - greyscale_colors = "#e2e2e2#000099#5d99be" - -/obj/item/pda/heads/rd - name = "research director PDA" - default_cartridge = /obj/item/cartridge/rd - insert_type = /obj/item/pen/fountain - greyscale_config = /datum/greyscale_config/pda/stripe_thick/head - greyscale_colors = "#e2e2e2#000099#9F5CA5" - -/obj/item/pda/captain - name = "captain PDA" - default_cartridge = /obj/item/cartridge/captain - insert_type = /obj/item/pen/fountain/captain - greyscale_config = /datum/greyscale_config/pda/captain - greyscale_colors = "#2C7CB2#FF0000#FFFFFF#F5D67B" - -/obj/item/pda/captain/Initialize(mapload) - . = ..() - RegisterSignal(src, COMSIG_PDA_CHECK_DETONATE, .proc/pda_no_detonate) - -/obj/item/pda/cargo - name = "cargo technician PDA" - default_cartridge = /obj/item/cartridge/quartermaster - greyscale_colors = "#D6B328#6506ca" - -/obj/item/pda/quartermaster - name = "quartermaster PDA" - default_cartridge = /obj/item/cartridge/quartermaster - insert_type = /obj/item/pen/survival - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#D6B328#6506ca#927444" - -/obj/item/pda/shaftminer - name = "shaft miner PDA" - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#927444#D6B328#6C3BA1" - -/obj/item/pda/syndicate - default_cartridge = /obj/item/cartridge/virus/syndicate - greyscale_colors = "#891417#80FF80" - name = "military PDA" - owner = "John Doe" - hidden = 1 - -/obj/item/pda/chaplain - name = "chaplain PDA" - greyscale_config = /datum/greyscale_config/pda/chaplain - greyscale_colors = "#333333#d11818" - ttone = "holy" - -/obj/item/pda/lawyer - name = "lawyer PDA" - default_cartridge = /obj/item/cartridge/lawyer - insert_type = /obj/item/pen/fountain - greyscale_colors = "#5B74A5#f7e062" - ttone = "objection" - -/obj/item/pda/botanist - name = "botanist PDA" - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#50E193#E26F41#71A7CA" - -/obj/item/pda/roboticist - name = "roboticist PDA" - greyscale_config = /datum/greyscale_config/pda/stripe_split - greyscale_colors = "#484848#0099cc#d33725" - default_cartridge = /obj/item/cartridge/roboticist - -/obj/item/pda/curator - name = "curator PDA" - greyscale_config = null - greyscale_colors = null - icon_state = "pda-library" - icon_alert = "pda-r-library" - icon_pai = "pai_overlay_library" - icon_inactive_pai = "pai_off_overlay_library" - insert_type = /obj/item/pen/fountain - desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader." - note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" - silent = TRUE //Quiet in the library! - -/obj/item/pda/clear - name = "clear PDA" - icon_state = "pda-clear" - greyscale_config = null - greyscale_colors = null - desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition with a transparent case." - note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!" - -/obj/item/pda/cook - name = "cook PDA" - greyscale_colors = "#e2e2e2#a92323" - -/obj/item/pda/bar - name = "bartender PDA" - greyscale_colors = "#333333#c7c7c7" - insert_type = /obj/item/pen/fountain - -/obj/item/pda/atmos - name = "atmospherics PDA" - default_cartridge = /obj/item/cartridge/atmos - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#ceca2b#00E5DA#727272" - -/obj/item/pda/chemist - name = "chemist PDA" - default_cartridge = /obj/item/cartridge/chemistry - greyscale_config = /datum/greyscale_config/pda/stripe_thick - greyscale_colors = "#e2e2e2#355FAC#ea6400" - -/obj/item/pda/geneticist - name = "geneticist PDA" - default_cartridge = /obj/item/cartridge/medical - greyscale_config = /datum/greyscale_config/pda/stripe_split - greyscale_colors = "#e2e2e2#000099#0097ca" diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm deleted file mode 100644 index 560fd492c96..00000000000 --- a/code/game/objects/items/devices/PDA/cart.dm +++ /dev/null @@ -1,648 +0,0 @@ -/obj/item/cartridge - name = "generic cartridge" - desc = "A data cartridge for portable microcomputers." - icon = 'icons/obj/pda.dmi' - icon_state = "cart" - inhand_icon_state = "electronic" - lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - w_class = WEIGHT_CLASS_TINY - - var/obj/item/integrated_signaler/radio = null - - var/access = 0 //Bit flags for cartridge access - - var/list/bot_access = list() -// Selection: SEC_BOT | ADVANCED_SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT | FIRE_BOT | VIBE_BOT - - var/spam_enabled = 0 //Enables "Send to All" Option - - var/obj/item/pda/host_pda = null - var/menu - var/datum/data/record/active1 = null //General - var/datum/data/record/active2 = null //Medical - var/datum/data/record/active3 = null //Security - var/obj/machinery/computer/monitor/powmonitor = null // Power Monitor - var/list/powermonitors = list() - var/message1 // used for status_displays - var/message2 - var/list/stored_data = list() - var/current_channel - - /// Weakref to the currently controlled bot - var/datum/weakref/active_bot_ref - var/list/botlist = list() - -/obj/item/cartridge/engineering - name = "\improper Power-ON cartridge" - icon_state = "cart-e" - access = CART_ENGINE - bot_access = list( - FLOOR_BOT, - ) - -/obj/item/cartridge/atmos - name = "\improper BreatheDeep cartridge" - icon_state = "cart-a" - access = CART_ATMOS - bot_access = list( - FLOOR_BOT, - FIRE_BOT, - ) - -/obj/item/cartridge/medical - name = "\improper Med-U cartridge" - icon_state = "cart-m" - access = CART_MEDICAL - bot_access = list( - MED_BOT, - ) - -/obj/item/cartridge/chemistry - name = "\improper ChemWhiz cartridge" - icon_state = "cart-chem" - access = CART_REAGENT_SCANNER - bot_access = list( - MED_BOT, - ) - -/obj/item/cartridge/security - name = "\improper R.O.B.U.S.T. cartridge" - icon_state = "cart-s" - access = CART_SECURITY | CART_MANIFEST - bot_access = list( - SEC_BOT, - ADVANCED_SEC_BOT, - ) - -/obj/item/cartridge/detective - name = "\improper D.E.T.E.C.T. cartridge" - icon_state = "cart-s" - access = CART_SECURITY | CART_MEDICAL | CART_MANIFEST - bot_access = list( - SEC_BOT, - ADVANCED_SEC_BOT, - ) - -/obj/item/cartridge/lawyer - name = "\improper P.R.O.V.E. cartridge" - icon_state = "cart-s" - access = CART_SECURITY - spam_enabled = 1 - -/obj/item/cartridge/roboticist - name = "\improper B.O.O.P. Remote Control cartridge" - desc = "Packed with heavy duty quad-bot interlink!" - bot_access = list( - FLOOR_BOT, - CLEAN_BOT, - MED_BOT, - FIRE_BOT, - VIBE_BOT, - ) - -/obj/item/cartridge/signal - name = "generic signaler cartridge" - desc = "A data cartridge with an integrated radio signaler module." - -/obj/item/cartridge/signal/ordnance - name = "\improper Signal Ace 2 cartridge" - desc = "Complete with integrated radio signaler!" - icon_state = "cart-ord" - access = CART_REAGENT_SCANNER | CART_ATMOS - -/obj/item/cartridge/signal/Initialize(mapload) - . = ..() - radio = new(src) - -/obj/item/cartridge/quartermaster - name = "space parts & space vendors cartridge" - desc = "Perfect for the Quartermaster on the go!" - icon_state = "cart-q" - access = CART_QUARTERMASTER - bot_access = list( - MULE_BOT, - ) - -/obj/item/cartridge/head - name = "\improper Easy-Record DELUXE cartridge" - icon_state = "cart-h" - access = CART_MANIFEST | CART_STATUS_DISPLAY - -/obj/item/cartridge/hop - name = "\improper HumanResources9001 cartridge" - icon_state = "cart-h" - access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_SECURITY | CART_QUARTERMASTER - bot_access = list( - MULE_BOT, - CLEAN_BOT, - VIBE_BOT, - ) - -/obj/item/cartridge/hos - name = "\improper R.O.B.U.S.T. DELUXE cartridge" - icon_state = "cart-hos" - access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_SECURITY - bot_access = list( - SEC_BOT, - ADVANCED_SEC_BOT, - ) - - -/obj/item/cartridge/ce - name = "\improper Power-On DELUXE cartridge" - icon_state = "cart-ce" - access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_ENGINE | CART_ATMOS - bot_access = list( - FLOOR_BOT, - FIRE_BOT, - ) - -/obj/item/cartridge/cmo - name = "\improper Med-U DELUXE cartridge" - icon_state = "cart-cmo" - access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_REAGENT_SCANNER | CART_MEDICAL - bot_access = list( - MED_BOT, - ) - -/obj/item/cartridge/rd - name = "\improper Signal Ace DELUXE cartridge" - icon_state = "cart-rd" - access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_REAGENT_SCANNER | CART_ATMOS - bot_access = list( - FLOOR_BOT, - CLEAN_BOT, - MED_BOT, - FIRE_BOT, - VIBE_BOT, - ) - -/obj/item/cartridge/rd/Initialize(mapload) - . = ..() - radio = new(src) - -/obj/item/cartridge/captain - name = "\improper Value-PAK cartridge" - desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Clown and Mime ones) - icon_state = "cart-c" - access = ~(CART_CLOWN | CART_MIME) - spam_enabled = 1 - bot_access = list( - SEC_BOT, - ADVANCED_SEC_BOT, - MULE_BOT, - FLOOR_BOT, - CLEAN_BOT, - MED_BOT, - FIRE_BOT, - VIBE_BOT, - ) - -/obj/item/cartridge/captain/Initialize(mapload) - . = ..() - radio = new(src) - -/obj/item/cartridge/proc/post_status(command, data1, data2) - - var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) - - if(!frequency) - return - - var/datum/signal/status_signal = new(list("command" = command)) - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - if("alert") - status_signal.data["picture_state"] = data1 - - frequency.post_signal(src, status_signal) - -/obj/item/cartridge/proc/generate_menu(mob/user) - if(!host_pda) - return - switch(host_pda.ui_mode) - if(PDA_UI_SIGNALER) - menu = "

    [PDAIMG(signaler)] Remote Signaling System

    " - - menu += {" - Send Signal
    - Frequency: - - - - - [format_frequency(radio.frequency)] - + - +
    -
    - Code: - - - - - [radio.code] - + - +
    - "} - if (PDA_UI_CREW_MANIFEST) - menu = "

    [PDAIMG(notes)] Crew Manifest

    " - menu += "
    [GLOB.data_core.get_manifest_html(monochrome=TRUE)]
    " - - - if (PDA_UI_STATUS_DISPLAY) - menu = "

    [PDAIMG(status)] Station Status Display Interlink

    " - - menu += "\[ Clear \]
    " - menu += "\[ Shuttle ETA \]
    " - menu += "\[ Message \]" - menu += "
    " - menu += "\[ Alert: None |" - menu += " Red Alert |" - menu += " Lockdown |" - menu += " Biohazard \]
    " - - if (PDA_UI_POWER_MONITOR) - menu = "

    [PDAIMG(power)] Power Monitors - Please select one


    " - powmonitor = null - powermonitors = list() - var/powercount = 0 - - - - var/turf/pda_turf = get_turf(src) - for(var/obj/machinery/computer/monitor/pMon in GLOB.machines) - if(pMon.machine_stat & (NOPOWER | BROKEN)) //check to make sure the computer is functional - continue - if(pda_turf.z != pMon.z) //and that we're on the same zlevel as the computer (lore: limited signal strength) - continue - if(pMon.is_secret_monitor) //make sure it isn't a secret one (ie located on a ruin), allowing people to metagame that the location exists - continue - powercount++ - powermonitors += pMon - - - if(!powercount) - menu += span_danger("No connection
    ") - else - - menu += "" - var/count = 0 - for(var/obj/machinery/computer/monitor/pMon in powermonitors) - count++ - menu += "[pMon] - [get_area_name(pMon, TRUE)]
    " - - menu += "
    " - - if (PDA_UI_POWER_MONITOR_SELECTED) - menu = "

    [PDAIMG(power)] Power Monitor


    " - if(!powmonitor || !powmonitor.get_powernet()) - menu += span_danger("No connection
    ") - else - var/list/L = list() - var/datum/powernet/connected_powernet = powmonitor.get_powernet() - for(var/obj/machinery/power/terminal/term in connected_powernet.nodes) - if(istype(term.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/A = term.master - L += A - - menu += "
    Location: [get_area_name(powmonitor, TRUE)]
    Total power: [display_power(connected_powernet.viewavail)]
    Total load: [display_power(connected_powernet.viewload)]
    " - - menu += "" - - if(L.len > 0) - menu += "Area Eqp./Lgt./Env. Load Cell
    " - - var/list/S = list(" Off","AOff"," On", " AOn") - var/list/chg = list("N","C","F") - //Neither copytext nor copytext_char is appropriate here; neither 30 UTF-8 code units nor 30 code points equates to 30 columns of output. - //Some glyphs are very tall or very wide while others are small or even take up no space at all. - //Emojis can take modifiers which are many characters but render as only one glyph. - //A proper solution here (as far as Unicode goes, maybe not ideal as far as markup goes, a table would be better) - //would be to use [A.area.name] - for(var/obj/machinery/power/apc/A in L) - menu += copytext_char(add_trailing(A.area.name, 30, " "), 1, 30) - menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_leading(display_power(A.lastused_total), 6, " ")] [A.cell ? "[add_leading(round(A.cell.percent()), 3, " ")]% [chg[A.charging+1]]" : " N/C"]
    " - - menu += "
    " - - if (PDA_UI_MED_RECORDS) - menu = "

    [PDAIMG(medical)] Medical Record List

    " - if(GLOB.data_core.general) - for(var/datum/data/record/R in sort_record(GLOB.data_core.general)) - menu += "[R.fields["id"]]: [R.fields["name"]]
    " - menu += "
    " - if(PDA_UI_MED_RECORD_SELECTED) - menu = "

    [PDAIMG(medical)] Medical Record

    " - - if(active1 in GLOB.data_core.general) - menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
    " - menu += "Gender: [active1.fields["gender"]]
    " - menu += "Age: [active1.fields["age"]]
    " - menu += "Rank: [active1.fields["rank"]]
    " - menu += "Fingerprint: [active1.fields["fingerprint"]]
    " - menu += "Physical Status: [active1.fields["p_stat"]]
    " - menu += "Mental Status: [active1.fields["m_stat"]]
    " - else - menu += "Record Lost!
    " - - menu += "
    " - - menu += "

    [PDAIMG(medical)] Medical Data

    " - if(active2 in GLOB.data_core.medical) - menu += "Blood Type: [active2.fields["blood_type"]]

    " - - menu += "Minor Disabilities: [active2.fields["mi_dis"]]
    " - menu += "Details: [active2.fields["mi_dis_d"]]

    " - - menu += "Major Disabilities: [active2.fields["ma_dis"]]
    " - menu += "Details: [active2.fields["ma_dis_d"]]

    " - - menu += "Allergies: [active2.fields["alg"]]
    " - menu += "Details: [active2.fields["alg_d"]]

    " - - menu += "Current Diseases: [active2.fields["cdi"]]
    " - menu += "Details: [active2.fields["cdi_d"]]

    " - - menu += "Important Notes: [active2.fields["notes"]]
    " - else - menu += "Record Lost!
    " - - menu += "
    " - if (PDA_UI_SEC_RECORDS) - menu = "

    [PDAIMG(cuffs)] Security Record List

    " - if(GLOB.data_core.general) - for (var/datum/data/record/R in sort_record(GLOB.data_core.general)) - menu += "
    [R.fields["id"]]: [R.fields["name"]]
    " - - menu += "
    " - if(PDA_UI_SEC_RECORD_SELECTED) - menu = "

    [PDAIMG(cuffs)] Security Record

    " - - if(active1 in GLOB.data_core.general) - menu += "Name: [active1.fields["name"]] ID: [active1.fields["id"]]
    " - menu += "Gender: [active1.fields["gender"]]
    " - menu += "Age: [active1.fields["age"]]
    " - menu += "Rank: [active1.fields["rank"]]
    " - menu += "Fingerprint: [active1.fields["fingerprint"]]
    " - menu += "Physical Status: [active1.fields["p_stat"]]
    " - menu += "Mental Status: [active1.fields["m_stat"]]
    " - else - menu += "Record Lost!
    " - - menu += "
    " - - menu += "

    [PDAIMG(cuffs)] Security Data

    " - if(active3 in GLOB.data_core.security) - menu += "Criminal Status: [active3.fields["criminal"]]
    " - - menu += text("
    \nCrimes:") - - menu +={" - - - - - - - "} - for(var/datum/data/crime/c in active3.fields["crim"]) - menu += "" - menu += "" - menu += "" - menu += "" - menu += "" - menu += "
    CrimeDetailsAuthorTime Added
    [c.crimeName][c.crimeDetails][c.author][c.time]
    " - menu += "
    \nImportant Notes:
    " - menu += "[active3.fields["notes"]]" - else - menu += "Record Lost!
    " - - menu += "
    " - - if (PDA_UI_SUPPLY_RECORDS) - menu = "

    [PDAIMG(crate)] Supply Record Interlink

    " - - menu += "
    Supply shuttle
    " - menu += "Location: " - switch(SSshuttle.supply.mode) - if(SHUTTLE_CALL) - menu += "Moving to " - if(!is_station_level(SSshuttle.supply.z)) - menu += "station" - else - menu += "CentCom" - menu += " ([SSshuttle.supply.timeLeft(600)] Mins)" - else - menu += "At " - if(!is_station_level(SSshuttle.supply.z)) - menu += "CentCom" - else - menu += "station" - menu += "
    Current approved orders:
      " - for(var/S in SSshuttle.shopping_list) - var/datum/supply_order/SO = S - menu += "
    1. #[SO.id] - [SO.pack.name] approved by [SO.orderer] [SO.reason ? "([SO.reason])":""]
    2. " - menu += "
    " - - menu += "Current requests:
      " - for(var/S in SSshuttle.request_list) - var/datum/supply_order/SO = S - menu += "
    1. #[SO.id] - [SO.pack.name] requested by [SO.orderer]
    2. " - menu += "
    Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management." - - if (PDA_UI_SILO_LOGS) - menu = list("

    [PDAIMG(crate)] Ore Silo Logs

    ") - if (GLOB.ore_silo_default) - var/list/logs = GLOB.silo_access_logs[REF(GLOB.ore_silo_default)] - var/len = LAZYLEN(logs) - var/i = 0 - for(var/M in logs) - if (++i > 30) - menu += "(... older logs not shown ...)" - break - var/datum/ore_silo_log/entry = M - menu += "[len - i]. [entry.formatted]

    " - if(i == 0) - menu += "Nothing!" - else - menu += "No ore silo detected!" - menu = jointext(menu, "") - - if (PDA_UI_BOTS_ACCESS) - menu = "

    [PDAIMG(medbot)] Bots Interlink

    " - bot_control() - if (PDA_UI_EMOJI_GUIDE) - menu = "

    [PDAIMG(emoji)] Emoji Guidebook

    " - var/static/list/emoji_icon_states - var/static/emoji_table - if(!emoji_table) - var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) - var/list/collate = list("
    ") - for(var/emoji in sort_list(icon_states(icon(EMOJI_SET)))) - var/tag = sheet.icon_tag("emoji-[emoji]") - collate += "" - collate += "
    [emoji][tag]

    " - emoji_table = collate.Join() - - menu += "
    To use an emoji in a pda message, refer to the guide and add \":\" around the emoji. Your PDA supports the following emoji:
    " - menu += emoji_table - - return menu - -/obj/item/cartridge/Topic(href, href_list) - ..() - - if(!usr.canUseTopic(src, !issilicon(usr))) - usr.unset_machine() - usr << browse(null, "window=pda") - return - - switch(href_list["choice"]) - if("Medical Records") - active1 = find_record("id", href_list["target"], GLOB.data_core.general) - if(active1) - active2 = find_record("id", href_list["target"], GLOB.data_core.medical) - host_pda.ui_mode = PDA_UI_MED_RECORD_SELECTED - if(!active2) - active1 = null - - if("Security Records") - active1 = find_record("id", href_list["target"], GLOB.data_core.general) - if(active1) - active3 = find_record("id", href_list["target"], GLOB.data_core.security) - host_pda.ui_mode = PDA_UI_SEC_RECORD_SELECTED - if(!active3) - active1 = null - - if("Send Signal") - INVOKE_ASYNC(radio, /obj/item/integrated_signaler.proc/send_activation) - - if("Signal Frequency") - var/new_frequency = sanitize_frequency(radio.frequency + text2num(href_list["sfreq"])) - radio.set_frequency(new_frequency) - - if("Signal Code") - radio.code += text2num(href_list["scode"]) - radio.code = round(radio.code) - radio.code = min(100, radio.code) - radio.code = max(1, radio.code) - - if("Status") - switch(href_list["statdisp"]) - if("message") - post_status("message", message1, message2) - if("alert") - post_status("alert", href_list["alert"]) - if("setmsg1") - message1 = reject_bad_text(input("Line 1", "Enter Message Text", message1) as text|null, 40) - updateSelfDialog() - if("setmsg2") - message2 = reject_bad_text(input("Line 2", "Enter Message Text", message2) as text|null, 40) - updateSelfDialog() - else - post_status(href_list["statdisp"]) - if("Power Select") - var/pnum = text2num(href_list["target"]) - powmonitor = powermonitors[pnum] - host_pda.ui_mode = PDA_UI_POWER_MONITOR_SELECTED - - if("Supply Orders") - host_pda.ui_mode = PDA_UI_SUPPLY_RECORDS - - //emoji previews - if(href_list["emoji"]) - var/parse = emoji_parse(":[href_list["emoji"]]:") - to_chat(usr, parse) - - var/mob/living/simple_animal/bot/active_bot = active_bot_ref?.resolve() - - //Bot control section! Viciously ripped from radios for being laggy and terrible. - if(href_list["op"]) - switch(href_list["op"]) - - if("control") - active_bot_ref = WEAKREF(locate(href_list["bot"]) in GLOB.bots_list) - if("botlist") - active_bot_ref = null - if("summon") //Args are in the correct order, they are stated here just as an easy reminder. - active_bot.bot_control("summon", usr, host_pda.GetAccess()) - else //Forward all other bot commands to the bot itself! - active_bot.bot_control(href_list["op"], usr) - - if(href_list["mule"]) //MULEbots are special snowflakes, and need different args due to how they work. - var/mob/living/simple_animal/bot/mulebot/mule = active_bot - if (istype(mule)) - mule.bot_control(href_list["mule"], usr, pda=TRUE) - - if(!host_pda) - return - host_pda.attack_self(usr) - - -/obj/item/cartridge/proc/bot_control() - var/mob/living/simple_animal/bot/active_bot = active_bot_ref?.resolve() - if(!active_bot) - menu += "
    [PDAIMG(refresh)]Scan for active bots

    " - var/turf/current_turf = get_turf(src) - var/zlevel = current_turf.z - var/botcount = 0 - for(var/B in GLOB.bots_list) //Git da botz - var/mob/living/simple_animal/bot/Bot = B - if(!(Bot.bot_mode_flags & BOT_MODE_ON) || Bot.z != zlevel || !(Bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED) || !(Bot.bot_type in bot_access)) //Only non-emagged bots on the same Z-level are detected! - continue //Also, the PDA must have access to the bot type. - menu += "[Bot.name] ([Bot.get_mode()])
    " - botcount++ - if(!botcount) //No bots at all? Lame. - menu += "No bots found.
    " - return menu - - menu += "[active_bot]
    Status: (
    [PDAIMG(refresh)]refresh)
    " - menu += "Model: [active_bot.bot_type]
    " - menu += "Location: [get_area(active_bot)]
    " - menu += "Mode: [active_bot.get_mode()]" - if(active_bot.bot_mode_flags & BOT_MODE_PAI_CONTROLLABLE) - menu += "
    pAI: " - if(active_bot.paicard && active_bot.paicard.pai) - menu += "[active_bot.paicard.pai.name]" - if(active_bot.check_access(usr)) - menu += " (eject)" - else - menu += "none" - - //MULEs! - if(active_bot.bot_type == MULE_BOT) - var/mob/living/simple_animal/bot/mulebot/MULE = active_bot - var/atom/Load = MULE.load - menu += "
    Current Load: [ !Load ? "none" : "[Load.name] (unload)" ]
    " - menu += "Destination: [MULE.destination ? MULE.destination : "None"] (set)
    " - menu += "Set ID: [MULE.suffix] Modify
    " - menu += "Power: [MULE.cell ? MULE.cell.percent() : 0]%
    " - menu += "Home: [!MULE.home_destination ? "none" : MULE.home_destination ]
    " - menu += "Delivery Reporting: [MULE.report_delivery ? "(On)": "(Off)"]
    " - menu += "Auto Return Home: [MULE.auto_return ? "(On)": "(Off)"]
    " - menu += "Auto Pickup Crate: [MULE.auto_pickup ? "(On)": "(Off)"]

    " //Hue. - - menu += "\[Stop\] " - menu += "\[Proceed\] " - menu += "\[Return Home\]
    " - - else - menu += "
    \[Stop Patrol\] " //patrolon - menu += "\[Start Patrol\] " //patroloff - menu += "\[Summon Bot\]
    " //summon - menu += "Keep an ID inserted to upload access codes upon summoning." - - menu += "
    [PDAIMG(back)]Return to bot list" - - return menu - -//If the cartridge adds a special line to the top of the messaging app -/obj/item/cartridge/proc/message_header() - return "" - -//If the cartridge adds something to each potetial messaging target -/obj/item/cartridge/proc/message_special(obj/item/pda/target) - return "" - -//This is called for special abilities of cartridges -/obj/item/cartridge/proc/special(mob/living/user, list/params) diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm deleted file mode 100644 index 39d1a7b5223..00000000000 --- a/code/game/objects/items/devices/PDA/radio.dm +++ /dev/null @@ -1,38 +0,0 @@ -// Radio Cartridge, essentially a remote signaler with limited spectrum. -/obj/item/integrated_signaler - name = "\improper PDA radio module" - desc = "An electronic radio system of Nanotrasen origin." - icon = 'icons/obj/module.dmi' - icon_state = "power_mod" - -/obj/item/integrated_signaler - var/frequency = FREQ_SIGNALER - var/code = DEFAULT_SIGNALER_CODE - var/last_transmission - var/datum/radio_frequency/radio_connection - -/obj/item/integrated_signaler/Destroy() - radio_connection = null - return ..() - -/obj/item/integrated_signaler/Initialize(mapload) - . = ..() - if (frequency < MIN_FREE_FREQ || frequency > MAX_FREE_FREQ) - frequency = sanitize_frequency(frequency) - set_frequency(frequency) - -/obj/item/integrated_signaler/proc/set_frequency(new_frequency) - frequency = new_frequency - radio_connection = SSradio.return_frequency(frequency) - -/obj/item/integrated_signaler/proc/send_activation() - if(last_transmission && world.time < (last_transmission + 5)) - return - last_transmission = world.time - - var/time = time2text(world.realtime,"hh:mm:ss") - var/turf/T = get_turf(src) - GLOB.lastsignalers.Add("[time] : [usr.key] used [src] @ location [AREACOORD(T)] : [format_frequency(frequency)]/[code]") - - var/datum/signal/signal = new(list("code" = code)) - radio_connection.post_signal(src, signal, filter = RADIO_SIGNALER) diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm deleted file mode 100644 index fbaba93fad1..00000000000 --- a/code/game/objects/items/devices/PDA/virus_cart.dm +++ /dev/null @@ -1,146 +0,0 @@ -/obj/item/cartridge/virus - name = "Generic Virus PDA cart" - var/charges = 5 - -/obj/item/cartridge/virus/proc/send_virus(obj/item/pda/target, mob/living/U) - return - -/obj/item/cartridge/virus/message_header() - return "[charges] viral files left.
    " - -/obj/item/cartridge/virus/message_special(obj/item/pda/target) - if (!istype(loc, /obj/item/pda)) - return "" //Sanity check, this shouldn't be possible. - return " (*Send Virus*)" - -/obj/item/cartridge/virus/special(mob/living/user, list/params) - var/obj/item/pda/P = locate(params["target"]) in GLOB.PDAs //Leaving it alone in case it may do something useful, I guess. - INVOKE_ASYNC(src, .proc/send_virus, P, user) - -/obj/item/cartridge/virus/clown - name = "\improper Honkworks 5.0 cartridge" - icon_state = "cart-clown" - desc = "A data cartridge for portable microcomputers. It smells vaguely of bananas." - access = CART_CLOWN - -/obj/item/cartridge/virus/clown/send_virus(obj/item/pda/target, mob/living/U) - if(charges <= 0) - to_chat(U, span_notice("Out of charges.")) - return - if(!isnull(target) && !target.toff) - charges-- - to_chat(U, span_notice("Virus Sent!")) - target.honkamt = (rand(15,20)) - else - to_chat(U, span_alert("PDA not found.")) - -/obj/item/cartridge/virus/mime - name = "\improper Gestur-O 1000 cartridge" - icon_state = "cart-mi" - access = CART_MIME - -/obj/item/cartridge/virus/mime/send_virus(obj/item/pda/target, mob/living/U) - if(charges <= 0) - to_chat(U, span_alert("Out of charges.")) - return - if(!isnull(target) && !target.toff) - charges-- - to_chat(U, span_notice("Virus Sent!")) - target.silent = TRUE - target.ttone = "silence" - else - to_chat(U, span_alert("PDA not found.")) - -/obj/item/cartridge/virus/syndicate - name = "\improper Detomatix cartridge" - icon_state = "cart" - charges = 6 - -/obj/item/cartridge/virus/syndicate/send_virus(obj/item/pda/target, mob/living/user) - if(charges <= 0) - to_chat(user, span_notice("Out of charges.")) - return - if(!target || target.toff) - to_chat(user, span_alert("PDA not found.")) - return - - var/difficulty = 0 - if(target.cartridge) - difficulty += bit_count(target.cartridge.access&(CART_MEDICAL | CART_SECURITY | CART_ENGINE | CART_CLOWN | CART_MANIFEST)) - if(target.cartridge.access & CART_MANIFEST) - difficulty++ //if cartridge has manifest access it has extra snowflake difficulty - if(SEND_SIGNAL(target, COMSIG_PDA_CHECK_DETONATE) & COMPONENT_PDA_NO_DETONATE || prob(difficulty * 15)) - user.show_message(span_danger("An error flashes on your [src]."), MSG_VISUAL) - charges-- - return - - var/original_host = host_pda - var/fakename = sanitize_name(tgui_input_text(user, "Enter a name for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE) - if(!fakename || host_pda != original_host || !user.canUseTopic(host_pda, BE_CLOSE)) - return - var/fakejob = sanitize_name(tgui_input_text(user, "Enter a job for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE) - if(!fakejob || host_pda != original_host || !user.canUseTopic(host_pda, BE_CLOSE)) - return - if(charges > 0 && host_pda.send_message(user, list(target), rigged = REF(user), fakename = fakename, fakejob = fakejob)) - charges-- - user.show_message(span_notice("Success!"), MSG_VISUAL) - //Rigs the PDA to explode if they try to outsmart us by using the message function menu. - var/reference = REF(src) - ADD_TRAIT(target, TRAIT_PDA_CAN_EXPLODE, reference) - ADD_TRAIT(target, TRAIT_PDA_MESSAGE_MENU_RIGGED, reference) - addtimer(TRAIT_CALLBACK_REMOVE(target, TRAIT_PDA_MESSAGE_MENU_RIGGED, reference), 10 SECONDS) - -/obj/item/cartridge/virus/frame - name = "\improper F.R.A.M.E. cartridge" - icon_state = "cart" - var/telecrystals = 0 - var/current_progression = 0 - -/obj/item/cartridge/virus/frame/send_virus(obj/item/pda/target, mob/living/U) - if(charges <= 0) - to_chat(U, span_alert("Out of charges.")) - return - if(!isnull(target) && !target.toff) - charges-- - var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" - to_chat(U, span_notice("Virus Sent! The unlock code to the target is: [lock_code]")) - var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink) - if(!hidden_uplink) - var/datum/mind/target_mind - var/list/backup_players = list() - for(var/datum/mind/player as anything in get_crewmember_minds()) - if(player.assigned_role?.title == target.id?.assignment) - backup_players += player - if(player.name == target.owner) - target_mind = player - break - if(!target_mind) - if(!length(backup_players)) - target_mind = U.mind - else - target_mind = pick(backup_players) - hidden_uplink = target.AddComponent(/datum/component/uplink, target_mind, enabled = TRUE, starting_tc = telecrystals, has_progression = TRUE) - hidden_uplink.uplink_handler.has_objectives = TRUE - hidden_uplink.uplink_handler.owner = target_mind - hidden_uplink.uplink_handler.can_take_objectives = FALSE - hidden_uplink.uplink_handler.progression_points = min(SStraitor.current_global_progression, current_progression) - hidden_uplink.uplink_handler.generate_objectives() - SStraitor.register_uplink_handler(hidden_uplink.uplink_handler) - else - hidden_uplink.add_telecrystals(telecrystals) - telecrystals = 0 - hidden_uplink.locked = FALSE - hidden_uplink.active = TRUE - else - to_chat(U, span_alert("PDA not found.")) - -/obj/item/cartridge/virus/frame/attackby(obj/item/I, mob/user, params) - . = ..() - if(istype(I, /obj/item/stack/telecrystal)) - if(!charges) - to_chat(user, span_notice("[src] is out of charges, it's refusing to accept [I].")) - return - var/obj/item/stack/telecrystal/telecrystalStack = I - telecrystals += telecrystalStack.amount - to_chat(user, span_notice("You slot [telecrystalStack] into [src]. The next time it's used, it will also give telecrystals.")) - telecrystalStack.use(telecrystalStack.amount) diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index ded8c0ee892..7e4124859cf 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -99,7 +99,7 @@ return CONTEXTUAL_SCREENTIP_SET // Used by the PDA medical scanner too -/proc/healthscan(mob/user, mob/living/target, mode = SCANNER_VERBOSE, advanced = FALSE) +/proc/healthscan(mob/user, mob/living/target, mode = SCANNER_VERBOSE, advanced = FALSE, tochat = TRUE) if(user.incapacitated()) return @@ -368,7 +368,11 @@ render_list += "Detected cybernetic modifications:\n" render_list += "[cyberimp_detect]\n" // we handled the last
    so we don't need handholding - to_chat(user, jointext(render_list, ""), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + + if(tochat) + to_chat(user, jointext(render_list, ""), trailing_newline = FALSE, type = MESSAGE_TYPE_INFO) + else + return(jointext(render_list, "")) /proc/chemscan(mob/living/user, mob/living/target) if(user.incapacitated()) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index cf5cc415d9c..8e36b39f1cb 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -662,7 +662,7 @@ STR.silent = TRUE /obj/item/storage/backpack/duffelbag/clown/syndie/PopulateContents() - new /obj/item/pda/clown(src) + new /obj/item/modular_computer/tablet/pda/clown(src) new /obj/item/clothing/under/rank/civilian/clown(src) new /obj/item/clothing/shoes/clown_shoes(src) new /obj/item/clothing/mask/gas/clown_hat(src) diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 9b6a922c31e..58f47f26797 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -549,15 +549,15 @@ /obj/item/storage/box/pdas/PopulateContents() for(var/i in 1 to 4) - new /obj/item/pda(src) - new /obj/item/cartridge/head(src) + new /obj/item/modular_computer/tablet/pda(src) + new /obj/item/computer_hardware/hard_drive/role/head(src) - var/newcart = pick( /obj/item/cartridge/engineering, - /obj/item/cartridge/security, - /obj/item/cartridge/medical, - /obj/item/cartridge/signal/ordnance, - /obj/item/cartridge/quartermaster) - new newcart(src) + var/new_disk = pick( /obj/item/computer_hardware/hard_drive/role/engineering, + /obj/item/computer_hardware/hard_drive/role/security, + /obj/item/computer_hardware/hard_drive/role/medical, + /obj/item/computer_hardware/hard_drive/role/signal/ordnance, + /obj/item/computer_hardware/hard_drive/role/quartermaster) + new new_disk(src) /obj/item/storage/box/silver_ids name = "box of spare silver IDs" @@ -591,9 +591,9 @@ illustration = "pda" /obj/item/storage/box/seccarts/PopulateContents() - new /obj/item/cartridge/detective(src) + new /obj/item/computer_hardware/hard_drive/role/detective(src) for(var/i in 1 to 6) - new /obj/item/cartridge/security(src) + new /obj/item/computer_hardware/hard_drive/role/security(src) /obj/item/storage/box/firingpins name = "box of standard firing pins" @@ -1155,7 +1155,7 @@ /obj/item/storage/box/debugtools/PopulateContents() var/static/items_inside = list( /obj/item/flashlight/emp/debug=1,\ - /obj/item/pda=1,\ + /obj/item/modular_computer/tablet/pda=1,\ /obj/item/modular_computer/tablet/preset/advanced=1,\ /obj/item/geiger_counter=1,\ /obj/item/construction/rcd/combat/admin=1,\ diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 37db789e2cf..b83b9603f21 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -128,7 +128,7 @@ /obj/item/storage/backpack/duffelbag/syndie/sabotage new /obj/item/camera_bug(src) new /obj/item/sbeacondrop/powersink(src) - new /obj/item/cartridge/virus/syndicate(src) + new /obj/item/computer_hardware/hard_drive/role/virus/deto(src) new /obj/item/storage/toolbox/syndicate(src) new /obj/item/pizzabox/bomb(src) new /obj/item/storage/box/syndie_kit/emp(src) @@ -475,7 +475,7 @@ new /obj/item/storage/belt/chameleon(src) new /obj/item/radio/headset/chameleon(src) new /obj/item/stamp/chameleon(src) - new /obj/item/pda/chameleon(src) + new /obj/item/modular_computer/tablet/pda/chameleon(src) //5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. //Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) @@ -515,7 +515,7 @@ new /obj/item/radio/headset/headset_cent/empty(src) new /obj/item/clothing/glasses/sunglasses(src) new /obj/item/storage/backpack/satchel(src) - new /obj/item/pda/heads(src) + new /obj/item/modular_computer/tablet/pda/heads(src) new /obj/item/clipboard(src) /obj/item/storage/box/syndie_kit/chameleon/broken/PopulateContents() @@ -531,7 +531,7 @@ new /obj/item/storage/belt/chameleon/broken(src) new /obj/item/radio/headset/chameleon/broken(src) new /obj/item/stamp/chameleon/broken(src) - new /obj/item/pda/chameleon/broken(src) + new /obj/item/modular_computer/tablet/pda/chameleon/broken(src) // No chameleon laser, they can't randomise for //REASONS// /obj/item/storage/box/syndie_kit/bee_grenades diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index fc7e127f09f..49c62124bcd 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -7,7 +7,7 @@ ..() new /obj/item/storage/bag/garment/engineering_chief (src) - new /obj/item/cartridge/ce(src) + new /obj/item/computer_hardware/hard_drive/role/ce(src) new /obj/item/radio/headset/heads/ce(src) new /obj/item/megaphone/command(src) new /obj/item/areaeditor/blueprints(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 2b155668d28..91d70eefe63 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -77,7 +77,7 @@ new /obj/item/clothing/suit/bio_suit/cmo(src) new /obj/item/clothing/head/bio_hood/cmo(src) new /obj/item/storage/bag/garment/chief_medical(src) - new /obj/item/cartridge/cmo(src) + new /obj/item/computer_hardware/hard_drive/role/cmo(src) new /obj/item/radio/headset/heads/cmo(src) new /obj/item/megaphone/command(src) new /obj/item/defibrillator/compact/loaded(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index c0bb728f877..4a21d6785fd 100755 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -9,7 +9,7 @@ new /obj/item/clothing/suit/bio_suit/scientist(src) new /obj/item/clothing/head/bio_hood/scientist(src) new /obj/item/storage/bag/garment/research_director(src) - new /obj/item/cartridge/rd(src) + new /obj/item/computer_hardware/hard_drive/role/rd(src) new /obj/item/radio/headset/heads/rd(src) new /obj/item/megaphone/command(src) new /obj/item/storage/lockbox/medal/sci(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 7ac0d4e2121..ad417714bce 100755 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -12,7 +12,7 @@ new /obj/item/clothing/neck/petcollar(src) new /obj/item/pet_carrier(src) new /obj/item/storage/bag/garment/captain(src) - new /obj/item/cartridge/captain(src) + new /obj/item/computer_hardware/hard_drive/role/captain(src) new /obj/item/storage/box/silver_ids(src) new /obj/item/radio/headset/heads/captain/alt(src) new /obj/item/radio/headset/heads/captain(src) @@ -30,7 +30,7 @@ ..() new /obj/item/storage/bag/garment/hop(src) new /obj/item/storage/lockbox/medal/service(src) - new /obj/item/cartridge/hop(src) + new /obj/item/computer_hardware/hard_drive/role/hop(src) new /obj/item/radio/headset/heads/hop(src) new /obj/item/storage/box/ids(src) new /obj/item/storage/box/ids(src) @@ -52,7 +52,7 @@ /obj/structure/closet/secure_closet/hos/PopulateContents() ..() - new /obj/item/cartridge/hos(src) + new /obj/item/computer_hardware/hard_drive/role/hos(src) new /obj/item/radio/headset/heads/hos(src) new /obj/item/storage/bag/garment/hos(src) new /obj/item/storage/lockbox/medal/sec(src) diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm index 5d5d7da9027..a42797a7aa1 100644 --- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm +++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm @@ -28,7 +28,7 @@ new /obj/item/storage/box/flashbangs(src) new /obj/item/storage/box/teargas(src) new /obj/item/storage/backpack/duffelbag/syndie/med(src) - new /obj/item/pda/syndicate(src) + new /obj/item/modular_computer/tablet/pda/syndicate(src) /obj/structure/closet/syndicate/resources desc = "An old, dusty locker." diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index e86a087d358..cb200f3be8b 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -533,7 +533,7 @@ playsound(src, 'sound/machines/click.ogg', 20, TRUE) toggle_lock() return - if(istype(I, /obj/item/pda)) + if(istype(I, /obj/item/modular_computer)) return TRUE SStgui.update_uis(src) . = ..() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 5aa29a80ad3..9afe0e1d2dd 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -139,10 +139,12 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that id.update_icon() if(worn) - if(istype(worn, /obj/item/pda)) - var/obj/item/pda/PDA = worn - PDA.id = id - id.forceMove(PDA) + if(istype(worn, /obj/item/modular_computer/tablet/pda)) + var/obj/item/modular_computer/tablet/pda/PDA = worn + var/obj/item/computer_hardware/card_slot/card = PDA.all_components[MC_CARD] + + if(card) + card.try_insert(id) else if(istype(worn, /obj/item/storage/wallet)) var/obj/item/storage/wallet/W = worn W.front_id = id diff --git a/code/modules/cargo/markets/market_items/misc.dm b/code/modules/cargo/markets/market_items/misc.dm index b4f68ad7b64..e63377d5ae3 100644 --- a/code/modules/cargo/markets/market_items/misc.dm +++ b/code/modules/cargo/markets/market_items/misc.dm @@ -4,7 +4,7 @@ /datum/market_item/misc/Clear_PDA name = "Clear PDA" desc = "Show off your style with this limited edition clear PDA!." - item = /obj/item/pda/clear + item = /obj/item/modular_computer/tablet/pda/clear price_min = CARGO_CRATE_VALUE * 1.25 price_max = CARGO_CRATE_VALUE *3 diff --git a/code/modules/client/preferences/pda.dm b/code/modules/client/preferences/pda.dm deleted file mode 100644 index fcbf4f1ad4b..00000000000 --- a/code/modules/client/preferences/pda.dm +++ /dev/null @@ -1,17 +0,0 @@ -/// The color of a PDA -/datum/preference/color/pda_color - category = PREFERENCE_CATEGORY_GAME_PREFERENCES - savefile_key = "pda_color" - savefile_identifier = PREFERENCE_PLAYER - -/datum/preference/color/pda_color/create_default_value() - return COLOR_OLIVE - -/// The visual style of a PDA -/datum/preference/choiced/pda_style - category = PREFERENCE_CATEGORY_GAME_PREFERENCES - savefile_key = "pda_style" - savefile_identifier = PREFERENCE_PLAYER - -/datum/preference/choiced/pda_style/init_possible_values() - return GLOB.pda_styles diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index a4224e8bf79..e8d6e570c00 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -350,18 +350,17 @@ agent_card.update_label() agent_card.update_icon() -/datum/action/item_action/chameleon/change/pda/update_item(obj/item/picked_item) +/datum/action/item_action/chameleon/change/tablet/update_item(obj/item/picked_item) ..() - var/obj/item/pda/agent_pda = target + var/obj/item/modular_computer/tablet/pda/agent_pda = target if(istype(agent_pda)) - agent_pda.update_label() agent_pda.update_appearance() -/datum/action/item_action/chameleon/change/pda/apply_job_data(datum/job/job_datum) +/datum/action/item_action/chameleon/change/tablet/apply_job_data(datum/job/job_datum) ..() - var/obj/item/pda/agent_pda = target + var/obj/item/modular_computer/tablet/pda/agent_pda = target if(istype(agent_pda) && istype(job_datum)) - agent_pda.ownjob = job_datum.title + agent_pda.saved_job = job_datum.title /obj/item/clothing/under/chameleon @@ -693,25 +692,25 @@ . = ..() chameleon_action.emp_randomise(INFINITY) -/obj/item/pda/chameleon - name = "PDA" - var/datum/action/item_action/chameleon/change/pda/chameleon_action +/obj/item/modular_computer/tablet/pda/chameleon + name = "tablet" + var/datum/action/item_action/chameleon/change/tablet/chameleon_action -/obj/item/pda/chameleon/Initialize(mapload) +/obj/item/modular_computer/tablet/pda/chameleon/Initialize(mapload) . = ..() chameleon_action = new(src) - chameleon_action.chameleon_type = /obj/item/pda - chameleon_action.chameleon_name = "PDA" - chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/pda/heads, /obj/item/pda/ai, /obj/item/pda/ai/pai), only_root_path = TRUE) + chameleon_action.chameleon_type = /obj/item/modular_computer/tablet/pda + chameleon_action.chameleon_name = "tablet" + chameleon_action.chameleon_blacklist = typecacheof(list(/obj/item/modular_computer/tablet/pda/heads), only_root_path = TRUE) chameleon_action.initialize_disguises() -/obj/item/pda/chameleon/emp_act(severity) +/obj/item/modular_computer/tablet/pda/chameleon/emp_act(severity) . = ..() if(. & EMP_PROTECT_SELF) return chameleon_action.emp_randomise() -/obj/item/pda/chameleon/broken/Initialize(mapload) +/obj/item/modular_computer/tablet/pda/chameleon/broken/Initialize(mapload) . = ..() chameleon_action.emp_randomise(INFINITY) diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index e0019b2106b..92e5d40e9fe 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -197,17 +197,16 @@ gloves = /obj/item/clothing/gloves/color/black shoes = /obj/item/clothing/shoes/sneakers/black l_pocket = /obj/item/pen - r_pocket = /obj/item/pda/heads + r_pocket = /obj/item/modular_computer/tablet/pda/heads l_hand = /obj/item/clipboard /datum/outfit/centcom/centcom_official/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) if(visualsOnly) return - var/obj/item/pda/heads/pda = H.r_store - pda.owner = H.real_name - pda.ownjob = "CentCom Official" - pda.update_label() + var/obj/item/modular_computer/tablet/pda/heads/pda = H.r_store + pda.saved_identification = H.real_name + pda.saved_job = "CentCom Official" var/obj/item/card/id/W = H.wear_id W.registered_name = H.real_name diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index c6f8901e354..1c8d5b98bc9 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -231,7 +231,7 @@ id = /obj/item/card/id/advanced/chameleon/black id_trim = /datum/id_trim/reaper_assassin uniform = /obj/item/clothing/under/suit/black - belt = /obj/item/pda/heads + belt = /obj/item/modular_computer/tablet/pda/heads ears = /obj/item/radio/headset gloves = /obj/item/clothing/gloves/color/black glasses = /obj/item/clothing/glasses/sunglasses @@ -257,10 +257,9 @@ SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/ammo_box/a357, null, TRUE, TRUE) SEND_SIGNAL(sec_briefcase, COMSIG_TRY_STORAGE_INSERT, new /obj/item/grenade/c4/x4, null, TRUE, TRUE) - var/obj/item/pda/heads/pda = H.belt - pda.owner = H.real_name - pda.ownjob = "Reaper" - pda.update_label() + var/obj/item/modular_computer/tablet/pda/heads/pda = H.belt + pda.saved_identification = H.real_name + pda.saved_job = "Reaper" var/obj/item/card/id/W = H.wear_id W.registered_name = H.real_name diff --git a/code/modules/clothing/suits/wintercoats.dm b/code/modules/clothing/suits/wintercoats.dm index 440d3cc307c..62a71fc77f6 100644 --- a/code/modules/clothing/suits/wintercoats.dm +++ b/code/modules/clothing/suits/wintercoats.dm @@ -17,8 +17,7 @@ allowed += list( /obj/item/flashlight, /obj/item/lighter, - /obj/item/modular_computer/tablet, - /obj/item/pda, + /obj/item/modular_computer/tablet/pda, /obj/item/radio, /obj/item/storage/fancy/cigarettes, /obj/item/tank/internals/emergency_oxygen, diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 5b8323dd0a5..36f7e88929b 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -170,6 +170,13 @@ for(var/i in roundstart_experience) experiencer.mind.adjust_experience(i, roundstart_experience[i], TRUE) + var/obj/item/modular_computer/tablet/pda/PDA = spawned.get_item_by_slot(ITEM_SLOT_BELT) + if(istype(PDA)) + var/obj/item/computer_hardware/identifier/id = PDA.all_components[MC_IDENTIFY] + + if(id) + id.UpdateDisplay() + /datum/job/proc/announce_job(mob/living/joining_mob) if(head_announce) @@ -244,7 +251,7 @@ uniform = /obj/item/clothing/under/color/grey id = /obj/item/card/id/advanced ears = /obj/item/radio/headset - belt = /obj/item/pda + belt = /obj/item/modular_computer/tablet/pda back = /obj/item/storage/backpack shoes = /obj/item/clothing/shoes/sneakers/black box = /obj/item/storage/box/survival @@ -312,11 +319,10 @@ B.bank_cards += C H.sec_hud_set_ID() - var/obj/item/pda/PDA = H.get_item_by_slot(pda_slot) + var/obj/item/modular_computer/tablet/pda/PDA = H.get_item_by_slot(pda_slot) if(istype(PDA)) - PDA.owner = H.real_name - PDA.ownjob = J.title - PDA.update_label() + PDA.saved_identification = C.registered_name + PDA.saved_job = C.assignment /datum/outfit/job/get_chameleon_disguise_info() diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm index 894cd1c708d..c0a871b6dd1 100644 --- a/code/modules/jobs/job_types/atmospheric_technician.dm +++ b/code/modules/jobs/job_types/atmospheric_technician.dm @@ -44,12 +44,9 @@ id_trim = /datum/id_trim/job/atmospheric_technician uniform = /obj/item/clothing/under/rank/engineering/atmospheric_technician - backpack_contents = list( - /obj/item/modular_computer/tablet/preset/advanced/atmos = 1, - ) belt = /obj/item/storage/belt/utility/atmostech ears = /obj/item/radio/headset/headset_eng - l_pocket = /obj/item/pda/atmos + l_pocket = /obj/item/modular_computer/tablet/pda/atmos r_pocket = /obj/item/analyzer backpack = /obj/item/storage/backpack/industrial diff --git a/code/modules/jobs/job_types/bartender.dm b/code/modules/jobs/job_types/bartender.dm index 03eef61755e..d546411c0f4 100644 --- a/code/modules/jobs/job_types/bartender.dm +++ b/code/modules/jobs/job_types/bartender.dm @@ -53,7 +53,7 @@ backpack_contents = list( /obj/item/storage/box/beanbag = 1, ) - belt = /obj/item/pda/bar + belt = /obj/item/modular_computer/tablet/pda/bar ears = /obj/item/radio/headset/headset_srv glasses = /obj/item/clothing/glasses/sunglasses/reagent shoes = /obj/item/clothing/shoes/laceup diff --git a/code/modules/jobs/job_types/botanist.dm b/code/modules/jobs/job_types/botanist.dm index 43893211cb6..451db5322a6 100644 --- a/code/modules/jobs/job_types/botanist.dm +++ b/code/modules/jobs/job_types/botanist.dm @@ -42,7 +42,7 @@ uniform = /obj/item/clothing/under/rank/civilian/hydroponics suit = /obj/item/clothing/suit/apron suit_store = /obj/item/plant_analyzer - belt = /obj/item/pda/botanist + belt = /obj/item/modular_computer/tablet/pda/botanist ears = /obj/item/radio/headset/headset_srv gloves = /obj/item/clothing/gloves/botanic_leather diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 6eb57e17c82..907608d2255 100755 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -62,7 +62,7 @@ /obj/item/melee/baton/telescopic = 1, /obj/item/station_charter = 1, ) - belt = /obj/item/pda/captain + belt = /obj/item/modular_computer/tablet/pda/captain ears = /obj/item/radio/headset/heads/captain/alt glasses = /obj/item/clothing/glasses/sunglasses gloves = /obj/item/clothing/gloves/color/captain diff --git a/code/modules/jobs/job_types/cargo_technician.dm b/code/modules/jobs/job_types/cargo_technician.dm index 2b3fbd81313..36d0ea45147 100644 --- a/code/modules/jobs/job_types/cargo_technician.dm +++ b/code/modules/jobs/job_types/cargo_technician.dm @@ -41,10 +41,7 @@ id_trim = /datum/id_trim/job/cargo_technician uniform = /obj/item/clothing/under/rank/cargo/tech - backpack_contents = list( - /obj/item/modular_computer/tablet/preset/cargo = 1, - ) - belt = /obj/item/pda/cargo + belt = /obj/item/modular_computer/tablet/pda/cargo ears = /obj/item/radio/headset/headset_cargo l_hand = /obj/item/export_scanner diff --git a/code/modules/jobs/job_types/chaplain.dm b/code/modules/jobs/job_types/chaplain.dm index ef0f86c7faa..81ad1ecc481 100644 --- a/code/modules/jobs/job_types/chaplain.dm +++ b/code/modules/jobs/job_types/chaplain.dm @@ -120,7 +120,7 @@ /obj/item/camera/spooky = 1, /obj/item/stamp/chap = 1, ) - belt = /obj/item/pda/chaplain + belt = /obj/item/modular_computer/tablet/pda/chaplain ears = /obj/item/radio/headset/headset_srv backpack = /obj/item/storage/backpack/cultpack diff --git a/code/modules/jobs/job_types/chemist.dm b/code/modules/jobs/job_types/chemist.dm index 0670eea63c6..859e1394e12 100644 --- a/code/modules/jobs/job_types/chemist.dm +++ b/code/modules/jobs/job_types/chemist.dm @@ -45,7 +45,7 @@ id_trim = /datum/id_trim/job/chemist uniform = /obj/item/clothing/under/rank/medical/chemist suit = /obj/item/clothing/suit/toggle/labcoat/chemist - belt = /obj/item/pda/chemist + belt = /obj/item/modular_computer/tablet/pda/chemist ears = /obj/item/radio/headset/headset_med glasses = /obj/item/clothing/glasses/science shoes = /obj/item/clothing/shoes/sneakers/white diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm index cdf6117c44d..03df4c57607 100644 --- a/code/modules/jobs/job_types/chief_engineer.dm +++ b/code/modules/jobs/job_types/chief_engineer.dm @@ -61,14 +61,13 @@ uniform = /obj/item/clothing/under/rank/engineering/chief_engineer backpack_contents = list( /obj/item/melee/baton/telescopic = 1, - /obj/item/modular_computer/tablet/preset/advanced/command/engineering = 1, ) belt = /obj/item/storage/belt/utility/chief/full ears = /obj/item/radio/headset/heads/ce gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/hardhat/white shoes = /obj/item/clothing/shoes/sneakers/brown - l_pocket = /obj/item/pda/heads/ce + l_pocket = /obj/item/modular_computer/tablet/pda/heads/ce backpack = /obj/item/storage/backpack/industrial satchel = /obj/item/storage/backpack/satchel/eng diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm index 4da3e2f6abb..b9065156fa3 100644 --- a/code/modules/jobs/job_types/chief_medical_officer.dm +++ b/code/modules/jobs/job_types/chief_medical_officer.dm @@ -60,9 +60,8 @@ suit_store = /obj/item/flashlight/pen/paramedic backpack_contents = list( /obj/item/melee/baton/telescopic = 1, - /obj/item/modular_computer/tablet/preset/advanced/command = 1, ) - belt = /obj/item/pda/heads/cmo + belt = /obj/item/modular_computer/tablet/pda/heads/cmo ears = /obj/item/radio/headset/heads/cmo shoes = /obj/item/clothing/shoes/sneakers/blue l_pocket = /obj/item/pinpointer/crew diff --git a/code/modules/jobs/job_types/clown.dm b/code/modules/jobs/job_types/clown.dm index c4a16a86803..647968defe8 100644 --- a/code/modules/jobs/job_types/clown.dm +++ b/code/modules/jobs/job_types/clown.dm @@ -54,7 +54,7 @@ /obj/item/food/grown/banana = 1, /obj/item/instrument/bikehorn = 1, ) - belt = /obj/item/pda/clown + belt = /obj/item/modular_computer/tablet/pda/clown ears = /obj/item/radio/headset/headset_srv shoes = /obj/item/clothing/shoes/clown_shoes mask = /obj/item/clothing/mask/gas/clown_hat diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm index 8cbeada5cc4..b6d78e54d03 100644 --- a/code/modules/jobs/job_types/cook.dm +++ b/code/modules/jobs/job_types/cook.dm @@ -94,7 +94,7 @@ /obj/item/choice_beacon/ingredient = 1, /obj/item/sharpener = 1, ) - belt = /obj/item/pda/cook + belt = /obj/item/modular_computer/tablet/pda/cook ears = /obj/item/radio/headset/headset_srv head = /obj/item/clothing/head/chefhat mask = /obj/item/clothing/mask/fakemoustache/italian diff --git a/code/modules/jobs/job_types/curator.dm b/code/modules/jobs/job_types/curator.dm index 4b00fab0e5d..1d48388c5bd 100644 --- a/code/modules/jobs/job_types/curator.dm +++ b/code/modules/jobs/job_types/curator.dm @@ -35,11 +35,10 @@ id_trim = /datum/id_trim/job/curator uniform = /obj/item/clothing/under/rank/civilian/curator backpack_contents = list( - /obj/item/modular_computer/tablet/preset/advanced/curator = 1, /obj/item/barcodescanner = 1, /obj/item/choice_beacon/hero = 1, ) - belt = /obj/item/pda/curator + belt = /obj/item/modular_computer/tablet/pda/curator ears = /obj/item/radio/headset/headset_srv shoes = /obj/item/clothing/shoes/laceup l_pocket = /obj/item/laser_pointer diff --git a/code/modules/jobs/job_types/detective.dm b/code/modules/jobs/job_types/detective.dm index 60deeee2a95..05b242abc31 100644 --- a/code/modules/jobs/job_types/detective.dm +++ b/code/modules/jobs/job_types/detective.dm @@ -54,10 +54,9 @@ backpack_contents = list( /obj/item/detective_scanner = 1, /obj/item/melee/baton = 1, - /obj/item/modular_computer/tablet/preset/advanced/security = 1, /obj/item/storage/box/evidence = 1, ) - belt = /obj/item/pda/detective + belt = /obj/item/modular_computer/tablet/pda/detective ears = /obj/item/radio/headset/headset_sec/alt gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/fedora/det_hat diff --git a/code/modules/jobs/job_types/geneticist.dm b/code/modules/jobs/job_types/geneticist.dm index 76e3628bde0..4ceb55e97ec 100644 --- a/code/modules/jobs/job_types/geneticist.dm +++ b/code/modules/jobs/job_types/geneticist.dm @@ -40,7 +40,7 @@ uniform = /obj/item/clothing/under/rank/rnd/geneticist suit = /obj/item/clothing/suit/toggle/labcoat/genetics suit_store = /obj/item/flashlight/pen - belt = /obj/item/pda/geneticist + belt = /obj/item/modular_computer/tablet/pda/geneticist ears = /obj/item/radio/headset/headset_sci shoes = /obj/item/clothing/shoes/sneakers/white l_pocket = /obj/item/sequence_scanner diff --git a/code/modules/jobs/job_types/head_of_personnel.dm b/code/modules/jobs/job_types/head_of_personnel.dm index 8a637738685..3737b252eee 100644 --- a/code/modules/jobs/job_types/head_of_personnel.dm +++ b/code/modules/jobs/job_types/head_of_personnel.dm @@ -57,10 +57,9 @@ uniform = /obj/item/clothing/under/rank/civilian/head_of_personnel backpack_contents = list( /obj/item/melee/baton/telescopic = 1, - /obj/item/modular_computer/tablet/preset/advanced/command = 1, /obj/item/storage/box/ids = 1, ) - belt = /obj/item/pda/heads/hop + belt = /obj/item/modular_computer/tablet/pda/heads/hop ears = /obj/item/radio/headset/heads/hop head = /obj/item/clothing/head/hopcap shoes = /obj/item/clothing/shoes/sneakers/brown diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm index 081bbf6577b..576f7564909 100644 --- a/code/modules/jobs/job_types/head_of_security.dm +++ b/code/modules/jobs/job_types/head_of_security.dm @@ -55,9 +55,8 @@ suit_store = /obj/item/gun/energy/e_gun backpack_contents = list( /obj/item/evidencebag = 1, - /obj/item/modular_computer/tablet/preset/advanced/command = 1, ) - belt = /obj/item/pda/heads/hos + belt = /obj/item/modular_computer/tablet/pda/heads/hos ears = /obj/item/radio/headset/heads/hos/alt glasses = /obj/item/clothing/glasses/hud/security/sunglasses gloves = /obj/item/clothing/gloves/color/black diff --git a/code/modules/jobs/job_types/janitor.dm b/code/modules/jobs/job_types/janitor.dm index 3e71b02852a..7ef32aacbd4 100644 --- a/code/modules/jobs/job_types/janitor.dm +++ b/code/modules/jobs/job_types/janitor.dm @@ -37,10 +37,7 @@ id_trim = /datum/id_trim/job/janitor uniform = /obj/item/clothing/under/rank/civilian/janitor - backpack_contents = list( - /obj/item/modular_computer/tablet/preset/advanced/custodial = 1, - ) - belt = /obj/item/pda/janitor + belt = /obj/item/modular_computer/tablet/pda/janitor ears = /obj/item/radio/headset/headset_srv /datum/outfit/job/janitor/pre_equip(mob/living/carbon/human/H, visualsOnly) diff --git a/code/modules/jobs/job_types/lawyer.dm b/code/modules/jobs/job_types/lawyer.dm index bb58f241dce..11d7d8e6be8 100644 --- a/code/modules/jobs/job_types/lawyer.dm +++ b/code/modules/jobs/job_types/lawyer.dm @@ -36,7 +36,7 @@ id_trim = /datum/id_trim/job/lawyer uniform = /obj/item/clothing/under/rank/civilian/lawyer/bluesuit suit = /obj/item/clothing/suit/toggle/lawyer - belt = /obj/item/pda/lawyer + belt = /obj/item/modular_computer/tablet/pda/lawyer ears = /obj/item/radio/headset/headset_srvsec shoes = /obj/item/clothing/shoes/laceup l_pocket = /obj/item/laser_pointer diff --git a/code/modules/jobs/job_types/medical_doctor.dm b/code/modules/jobs/job_types/medical_doctor.dm index 7646d7b84b5..d1cb6fd6890 100644 --- a/code/modules/jobs/job_types/medical_doctor.dm +++ b/code/modules/jobs/job_types/medical_doctor.dm @@ -47,7 +47,7 @@ uniform = /obj/item/clothing/under/rank/medical/scrubs/blue suit = /obj/item/clothing/suit/toggle/labcoat suit_store = /obj/item/flashlight/pen - belt = /obj/item/pda/medical + belt = /obj/item/modular_computer/tablet/pda/medical ears = /obj/item/radio/headset/headset_med shoes = /obj/item/clothing/shoes/sneakers/white l_hand = /obj/item/storage/medkit/surgery diff --git a/code/modules/jobs/job_types/mime.dm b/code/modules/jobs/job_types/mime.dm index 71956c5e300..d821b617649 100644 --- a/code/modules/jobs/job_types/mime.dm +++ b/code/modules/jobs/job_types/mime.dm @@ -54,7 +54,7 @@ /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing = 1, /obj/item/stamp/mime = 1, ) - belt = /obj/item/pda/mime + belt = /obj/item/modular_computer/tablet/pda/mime ears = /obj/item/radio/headset/headset_srv gloves = /obj/item/clothing/gloves/color/white head = /obj/item/clothing/head/frenchberet diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index 17b722a74e5..d04fa51c242 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -55,7 +55,7 @@ head = /obj/item/clothing/head/soft/paramedic gloves = /obj/item/clothing/gloves/color/latex/nitrile shoes = /obj/item/clothing/shoes/sneakers/blue - l_pocket = /obj/item/pda/medical + l_pocket = /obj/item/modular_computer/tablet/pda/medical backpack = /obj/item/storage/backpack/medic satchel = /obj/item/storage/backpack/satchel/med diff --git a/code/modules/jobs/job_types/psychologist.dm b/code/modules/jobs/job_types/psychologist.dm index b8c51861940..ef5f80f5828 100644 --- a/code/modules/jobs/job_types/psychologist.dm +++ b/code/modules/jobs/job_types/psychologist.dm @@ -48,7 +48,7 @@ /obj/item/storage/pill_bottle/paxpsych, /obj/item/storage/pill_bottle/psicodine, ) - belt = /obj/item/pda/medical + belt = /obj/item/modular_computer/tablet/pda/medical ears = /obj/item/radio/headset/headset_srvmed shoes = /obj/item/clothing/shoes/laceup l_hand = /obj/item/clipboard diff --git a/code/modules/jobs/job_types/quartermaster.dm b/code/modules/jobs/job_types/quartermaster.dm index 01efa9170c4..8c5ec64c47b 100644 --- a/code/modules/jobs/job_types/quartermaster.dm +++ b/code/modules/jobs/job_types/quartermaster.dm @@ -38,10 +38,7 @@ id_trim = /datum/id_trim/job/quartermaster uniform = /obj/item/clothing/under/rank/cargo/qm - backpack_contents = list( - /obj/item/modular_computer/tablet/preset/cargo/quartermaster = 1, - ) - belt = /obj/item/pda/quartermaster + belt = /obj/item/modular_computer/tablet/pda/quartermaster ears = /obj/item/radio/headset/headset_cargo glasses = /obj/item/clothing/glasses/sunglasses shoes = /obj/item/clothing/shoes/sneakers/brown diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm index 9dee88593c9..99cc22fa028 100644 --- a/code/modules/jobs/job_types/research_director.dm +++ b/code/modules/jobs/job_types/research_director.dm @@ -62,7 +62,7 @@ /obj/item/melee/baton/telescopic = 1, /obj/item/modular_computer/tablet/preset/advanced/command = 1, ) - belt = /obj/item/pda/heads/rd + belt = /obj/item/modular_computer/tablet/pda/heads/rd ears = /obj/item/radio/headset/heads/rd shoes = /obj/item/clothing/shoes/sneakers/brown l_pocket = /obj/item/laser_pointer diff --git a/code/modules/jobs/job_types/roboticist.dm b/code/modules/jobs/job_types/roboticist.dm index 290fbd2e665..12fc8ad9a8c 100644 --- a/code/modules/jobs/job_types/roboticist.dm +++ b/code/modules/jobs/job_types/roboticist.dm @@ -50,7 +50,7 @@ ) belt = /obj/item/storage/belt/utility/full ears = /obj/item/radio/headset/headset_sci - l_pocket = /obj/item/pda/roboticist + l_pocket = /obj/item/modular_computer/tablet/pda/roboticist backpack = /obj/item/storage/backpack/science satchel = /obj/item/storage/backpack/satchel/science diff --git a/code/modules/jobs/job_types/scientist.dm b/code/modules/jobs/job_types/scientist.dm index e0c67d36669..23941f90407 100644 --- a/code/modules/jobs/job_types/scientist.dm +++ b/code/modules/jobs/job_types/scientist.dm @@ -44,7 +44,7 @@ backpack_contents = list( /obj/item/modular_computer/tablet/preset/science = 1, ) - belt = /obj/item/pda/science + belt = /obj/item/modular_computer/tablet/pda/science ears = /obj/item/radio/headset/headset_sci shoes = /obj/item/clothing/shoes/sneakers/white diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm index 4ee29dce560..4dc664c0108 100644 --- a/code/modules/jobs/job_types/security_officer.dm +++ b/code/modules/jobs/job_types/security_officer.dm @@ -162,14 +162,14 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) partners += partner.real_name if (partners.len) - for (var/obj/item/pda/pda as anything in GLOB.PDAs) - if (pda.owner in partners) - targets += STRINGIFY_PDA_TARGET(pda.owner, pda.ownjob) + for (var/obj/item/modular_computer/pda as anything in GLOB.TabletMessengers) + if (pda.saved_identification in partners) + targets += pda if (!targets.len) return - var/datum/signal/subspace/messaging/pda/signal = new(announcement_system, list( + var/datum/signal/subspace/messaging/tablet_msg/signal = new(announcement_system, list( "name" = "Security Department Update", "job" = "Automated Announcement System", "message" = "Officer [officer.real_name] has been assigned to your department, [department].", @@ -204,7 +204,7 @@ GLOBAL_LIST_EMPTY(security_officer_distribution) /obj/item/evidencebag = 1, /obj/item/modular_computer/tablet/preset/advanced/security = 1, ) - belt = /obj/item/pda/security + belt = /obj/item/modular_computer/tablet/pda/security ears = /obj/item/radio/headset/headset_sec/alt gloves = /obj/item/clothing/gloves/color/black head = /obj/item/clothing/head/helmet/sec diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm index 3a5342b6dfb..a319be558de 100644 --- a/code/modules/jobs/job_types/shaft_miner.dm +++ b/code/modules/jobs/job_types/shaft_miner.dm @@ -39,7 +39,7 @@ /obj/item/mining_voucher = 1, /obj/item/stack/marker_beacon/ten = 1, ) - belt = /obj/item/pda/shaftminer + belt = /obj/item/modular_computer/tablet/pda/shaftminer ears = /obj/item/radio/headset/headset_cargo/mining gloves = /obj/item/clothing/gloves/color/black shoes = /obj/item/clothing/shoes/workboots/mining diff --git a/code/modules/jobs/job_types/station_engineer.dm b/code/modules/jobs/job_types/station_engineer.dm index 6be9573da74..b806de25a2b 100644 --- a/code/modules/jobs/job_types/station_engineer.dm +++ b/code/modules/jobs/job_types/station_engineer.dm @@ -51,7 +51,7 @@ ears = /obj/item/radio/headset/headset_eng head = /obj/item/clothing/head/hardhat shoes = /obj/item/clothing/shoes/workboots - l_pocket = /obj/item/pda/engineering + l_pocket = /obj/item/modular_computer/tablet/pda/engineering r_pocket = /obj/item/t_scanner backpack = /obj/item/storage/backpack/industrial diff --git a/code/modules/jobs/job_types/virologist.dm b/code/modules/jobs/job_types/virologist.dm index 1b874b20ff3..04d2776cca2 100644 --- a/code/modules/jobs/job_types/virologist.dm +++ b/code/modules/jobs/job_types/virologist.dm @@ -47,7 +47,7 @@ uniform = /obj/item/clothing/under/rank/medical/virologist suit = /obj/item/clothing/suit/toggle/labcoat/virologist suit_store = /obj/item/flashlight/pen - belt = /obj/item/pda/viro + belt = /obj/item/modular_computer/tablet/pda/viro ears = /obj/item/radio/headset/headset_med mask = /obj/item/clothing/mask/surgical shoes = /obj/item/clothing/shoes/sneakers/white diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm index 8ccb1b2d30d..fad1da748bf 100644 --- a/code/modules/jobs/job_types/warden.dm +++ b/code/modules/jobs/job_types/warden.dm @@ -56,7 +56,7 @@ /obj/item/evidencebag = 1, /obj/item/modular_computer/tablet/preset/advanced/security = 1, ) - belt = /obj/item/pda/warden + belt = /obj/item/modular_computer/tablet/pda/warden ears = /obj/item/radio/headset/headset_sec/alt glasses = /obj/item/clothing/glasses/hud/security/sunglasses gloves = /obj/item/clothing/gloves/color/black diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 191294a6085..ec06b4a3330 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -157,7 +157,7 @@ for(var/i in 1 to 5) new /obj/item/toy/snappop/phoenix(src) if(41 to 45) - new /obj/item/pda/clear(src) + new /obj/item/modular_computer/tablet/pda/clear(src) if(46 to 50) new /obj/item/storage/box/syndie_kit/chameleon/broken if(51 to 52) // 2% chance diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 6423979410d..b9248b8e037 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -293,14 +293,14 @@ return var/datum/data/crime/crime = GLOB.data_core.createCrimeEntry(t1, "", allowed_access, station_time_timestamp(), fine) - for (var/obj/item/pda/P in GLOB.PDAs) - if(P.owner == R.fields["name"]) + for (var/obj/item/modular_computer/tablet in GLOB.TabletMessengers) + if(tablet.saved_identification == R.fields["name"]) var/message = "You have been fined [fine] credits for '[t1]'. Fines may be paid at security." - var/datum/signal/subspace/messaging/pda/signal = new(src, list( + var/datum/signal/subspace/messaging/tablet_msg/signal = new(src, list( "name" = "Security Citation", "job" = "Citation Server", "message" = message, - "targets" = list(STRINGIFY_PDA_TARGET(P.owner, P.ownjob)), + "targets" = list(tablet), "automated" = TRUE )) signal.send_to_receivers() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index e318ecfb635..4c6d41bea0b 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -12,9 +12,9 @@ if(id) . = id.assignment else - var/obj/item/pda/pda = wear_id + var/obj/item/modular_computer/pda = wear_id if(istype(pda)) - . = pda.ownjob + . = pda.saved_job else return if_no_id if(!.) @@ -26,9 +26,9 @@ var/obj/item/card/id/id = get_idcard(FALSE) if(id) return id.registered_name - var/obj/item/pda/pda = wear_id + var/obj/item/modular_computer/pda = wear_id if(istype(pda)) - return pda.owner + return pda.saved_identification return if_no_id //repurposed proc. Now it combines get_id_name() and get_face_name() to determine a mob's name variable. Made into a separate proc as it'll be useful elsewhere @@ -60,17 +60,14 @@ //Useful when player is being seen by other mobs /mob/living/carbon/human/proc/get_id_name(if_no_id = "Unknown") var/obj/item/storage/wallet/wallet = wear_id - var/obj/item/pda/pda = wear_id + var/obj/item/modular_computer/tablet/pda/pda = wear_id var/obj/item/card/id/id = wear_id - var/obj/item/modular_computer/tablet/tablet = wear_id if(istype(wallet)) id = wallet.front_id if(istype(id)) . = id.registered_name else if(istype(pda)) - . = pda.owner - else if(istype(tablet)) - var/obj/item/computer_hardware/card_slot/card_slot = tablet.all_components[MC_CARD] + var/obj/item/computer_hardware/card_slot/card_slot = pda.all_components[MC_CARD] if(card_slot?.stored_card) . = card_slot.stored_card.registered_name if(!.) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 4507ad5c5d3..1797549ea98 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -964,7 +964,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(!disable_warning) to_chat(H, span_warning("The [I.name] is too big to attach!")) //should be src? return FALSE - if( istype(I, /obj/item/pda) || istype(I, /obj/item/pen) || is_type_in_list(I, H.wear_suit.allowed) ) + if( istype(I, /obj/item/modular_computer/tablet) || istype(I, /obj/item/pen) || is_type_in_list(I, H.wear_suit.allowed) ) return TRUE return FALSE if(ITEM_SLOT_HANDCUFFED) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 8df343607cb..e94cd69739a 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -107,6 +107,8 @@ var/atom/lastloc interaction_range = null + var/atom/movable/screen/ai/modpc/interfaceButton + /mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai) . = ..() if(!target_ai) //If there is no player/brain inside. @@ -158,10 +160,7 @@ add_verb(src, /mob/living/silicon/ai/proc/show_laws_verb) - aiPDA = new/obj/item/pda/ai(src) - aiPDA.owner = real_name - aiPDA.ownjob = "AI" - aiPDA.name = real_name + " (" + aiPDA.ownjob + ")" + create_modularInterface() aiMulti = new(src) aicamera = new/obj/item/camera/siliconcam/ai_camera(src) @@ -832,16 +831,12 @@ if(oldname != real_name) if(eyeobj) eyeobj.name = "[newname] (AI Eye)" + modularInterface.saved_identification = real_name // Notify Cyborgs for(var/mob/living/silicon/robot/Slave in connected_robots) Slave.show_laws() -/mob/living/silicon/ai/replace_identification_name(oldname,newname) - if(aiPDA) - aiPDA.owner = newname - aiPDA.name = newname + " (" + aiPDA.ownjob + ")" - /datum/action/innate/choose_modules name = "Malfunction Modules" desc = "Choose from a variety of insidious modules to aid you." diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 2af326b024f..5510e5c33ad 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -127,6 +127,8 @@ "universal translator" = 35, ) + var/atom/movable/screen/ai/modpc/interfaceButton + /mob/living/silicon/pai/add_sensors() //pAIs have to buy their HUDs return @@ -171,10 +173,10 @@ aicamera = new /obj/item/camera/siliconcam/ai_camera(src) aicamera.flash_enabled = TRUE - addtimer(CALLBACK(src, .proc/pdaconfig), 5) - . = ..() + create_modularInterface() + emittersemicd = TRUE addtimer(CALLBACK(src, .proc/emittercool), 600) @@ -198,13 +200,6 @@ GLOB.pai_list -= src return ..() -/mob/living/silicon/pai/proc/pdaconfig() - //PDA - aiPDA = new /obj/item/pda/ai(src) - aiPDA.owner = real_name - aiPDA.ownjob = "pAI Messenger" - aiPDA.name = "[real_name] ([aiPDA.ownjob])" - /mob/living/silicon/pai/make_laws() laws = new /datum/ai_laws/pai() return TRUE @@ -255,6 +250,8 @@ /mob/living/silicon/pai/can_interact_with(atom/A) if(A == signaler) // Bypass for signaler return TRUE + if(A == modularInterface) + return TRUE return ..() diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm index 2a4b5f8fbb8..8431e0e967e 100644 --- a/code/modules/mob/living/silicon/pai/pai_shell.dm +++ b/code/modules/mob/living/silicon/pai/pai_shell.dm @@ -21,8 +21,8 @@ REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, PAI_FOLDED) REMOVE_TRAIT(src, TRAIT_HANDS_BLOCKED, PAI_FOLDED) set_density(TRUE) - if(istype(card.loc, /obj/item/pda)) - var/obj/item/pda/P = card.loc + if(istype(card.loc, /obj/item/modular_computer)) + var/obj/item/modular_computer/P = card.loc P.pai = null P.visible_message(span_notice("[src] ejects itself from [P]!")) if(isliving(card.loc)) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 0c4a0fcdc08..63a6ee684ac 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -30,9 +30,6 @@ data["pda"] = list() data["ram"] = ram data["refresh_spam"] = refresh_spam - if(aiPDA) - data["pda"]["power"] = !aiPDA.toff - data["pda"]["silent"] = aiPDA.silent if(master) data["master"]["name"] = master data["master"]["dna"] = master_dna @@ -128,15 +125,6 @@ med.remove_hud_from(src) if("newscaster") newscaster.ui_interact(src) - if("pda") - if(isnull(aiPDA)) - return FALSE - if(params["pda"] == "power") - aiPDA.toff = !aiPDA.toff - if(params["pda"] == "silent") - aiPDA.silent = !aiPDA.silent - if(params["pda"] == "message") - cmd_send_pdamesg(usr) if("photography_module") aicamera.toggle_camera_mode(usr) if("printer_module") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 96d320f5bbd..e0cd26a7607 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -91,17 +91,14 @@ laws = new /datum/ai_laws/syndicate_override() addtimer(CALLBACK(src, .proc/show_playstyle), 5) -/mob/living/silicon/robot/proc/create_modularInterface() - if(!modularInterface) - modularInterface = new /obj/item/modular_computer/tablet/integrated(src) - modularInterface.layer = ABOVE_HUD_PLANE - modularInterface.plane = ABOVE_HUD_PLANE - /mob/living/silicon/robot/model/syndicate/create_modularInterface() if(!modularInterface) modularInterface = new /obj/item/modular_computer/tablet/integrated/syndicate(src) + modularInterface.saved_identification = real_name + modularInterface.saved_job = "Cyborg" return ..() + /** * Sets the tablet theme and icon * @@ -691,6 +688,7 @@ notify_ai(AI_NOTIFICATION_CYBORG_RENAMED, oldname, newname) if(!QDELETED(builtInCamera)) builtInCamera.c_tag = real_name + modularInterface.saved_identification = real_name custom_name = newname @@ -976,29 +974,6 @@ lamp_doom = connected_ai.doomsday_device ? TRUE : FALSE toggle_headlamp(FALSE, TRUE) -/** - * Records an IC event log entry in the cyborg's internal tablet. - * - * Creates an entry in the borglog list of the cyborg's internal tablet, listing the current - * in-game time followed by the message given. These logs can be seen by the cyborg in their - * BorgUI tablet app. By design, logging fails if the cyborg is dead. - * - * Arguments: - * arg1: a string containing the message to log. - */ -/mob/living/silicon/robot/proc/logevent(string = "") - if(!string) - return - if(stat == DEAD) //Dead borgs log no longer - return - if(!modularInterface) - stack_trace("Cyborg [src] ( [type] ) was somehow missing their integrated tablet. Please make a bug report.") - create_modularInterface() - modularInterface.borglog += "[station_time_timestamp()] - [string]" - var/datum/computer_file/program/robotact/program = modularInterface.get_robotact() - if(program) - program.force_full_update() - /mob/living/silicon/robot/get_exp_list(minutes) . = ..() diff --git a/code/modules/mob/living/silicon/robot/robot_defines.dm b/code/modules/mob/living/silicon/robot/robot_defines.dm index 8334ad36c51..e6c9b01744e 100644 --- a/code/modules/mob/living/silicon/robot/robot_defines.dm +++ b/code/modules/mob/living/silicon/robot/robot_defines.dm @@ -68,8 +68,7 @@ var/atom/movable/screen/robot/lamp/lampButton ///The reference to the built-in tablet that borgs carry. - var/obj/item/modular_computer/tablet/integrated/modularInterface - var/atom/movable/screen/robot/modPC/interfaceButton + var/atom/movable/screen/robot/modpc/interfaceButton var/sight_mode = 0 hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index d13a4b92f41..0b0e6c4d688 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -47,7 +47,8 @@ var/hack_software = FALSE //Will be able to use hacking actions interaction_range = 7 //wireless control range - var/obj/item/pda/ai/aiPDA + + var/obj/item/modular_computer/tablet/integrated/modularInterface /mob/living/silicon/Initialize(mapload) . = ..() @@ -71,12 +72,35 @@ QDEL_NULL(radio) QDEL_NULL(aicamera) QDEL_NULL(builtInCamera) - QDEL_NULL(aiPDA) laws?.owner = null //Laws will refuse to die otherwise. QDEL_NULL(laws) GLOB.silicon_mobs -= src return ..() +/mob/living/silicon/proc/create_modularInterface() + if(!modularInterface) + modularInterface = new /obj/item/modular_computer/tablet/integrated(src) + modularInterface.layer = ABOVE_HUD_PLANE + modularInterface.plane = ABOVE_HUD_PLANE + modularInterface.saved_identification = real_name || name + if(istype(src, /mob/living/silicon/robot)) + modularInterface.saved_job = "Cyborg" + modularInterface.install_component(new /obj/item/computer_hardware/hard_drive/small/integrated/borg) + if(istype(src, /mob/living/silicon/ai)) + modularInterface.saved_job = "AI" + modularInterface.install_component(new /obj/item/computer_hardware/hard_drive/small/integrated) + if(istype(src, /mob/living/silicon/pai)) + modularInterface.saved_job = "pAI Messenger" + modularInterface.install_component(new /obj/item/computer_hardware/hard_drive/small/integrated) + +/mob/living/silicon/robot/model/syndicate/create_modularInterface() + if(!modularInterface) + modularInterface = new /obj/item/modular_computer/tablet/integrated/syndicate(src) + modularInterface.saved_identification = real_name + modularInterface.saved_job = "Cyborg" + return ..() + + /mob/living/silicon/med_hud_set_health() return //we use a different hud @@ -403,3 +427,30 @@ /mob/living/silicon/on_standing_up() return // Silicons are always standing by default. + +/** + * Records an IC event log entry in the cyborg's internal tablet. + * + * Creates an entry in the borglog list of the cyborg's internal tablet (if it's a borg), listing the current + * in-game time followed by the message given. These logs can be seen by the cyborg in their + * BorgUI tablet app. By design, logging fails if the cyborg is dead. + * + * (This used to be in robot.dm. It's in here now.) + * + * Arguments: + * arg1: a string containing the message to log. + */ +/mob/living/silicon/proc/logevent(string = "") + if(!string) + return + if(stat == DEAD) //Dead silicons log no longer + return + if(!modularInterface) + stack_trace("Silicon [src] ( [type] ) was somehow missing their integrated tablet. Please make a bug report.") + create_modularInterface() + var/mob/living/silicon/robot/robo = modularInterface.borgo + if(istype(robo)) + modularInterface.borglog += "[station_time_timestamp()] - [string]" + var/datum/computer_file/program/robotact/program = modularInterface.get_robotact() + if(program) + program.force_full_update() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 93e12e45289..8fd2cc53368 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1042,11 +1042,10 @@ break search_id = 0 - else if( search_pda && istype(A, /obj/item/pda) ) - var/obj/item/pda/PDA = A - if(PDA.owner == oldname) - PDA.owner = newname - PDA.update_label() + else if( search_pda && istype(A, /obj/item/modular_computer/tablet/pda) ) + var/obj/item/modular_computer/tablet/pda/PDA = A + if(PDA.saved_identification == oldname) + PDA.saved_identification = newname if(!search_id) break search_pda = 0 diff --git a/code/modules/mob_spawn/corpses/mining_corpses.dm b/code/modules/mob_spawn/corpses/mining_corpses.dm index ecbbc2001f3..1e0e06a7304 100644 --- a/code/modules/mob_spawn/corpses/mining_corpses.dm +++ b/code/modules/mob_spawn/corpses/mining_corpses.dm @@ -124,7 +124,6 @@ uniform = /obj/item/clothing/under/rank/civilian/clown back = /obj/item/storage/backpack/clown backpack_contents = list() - belt = /obj/item/pda/clown ears = /obj/item/radio/headset/headset_srv shoes = /obj/item/clothing/shoes/clown_shoes mask = /obj/item/clothing/mask/gas/clown_hat diff --git a/code/modules/mob_spawn/corpses/nonhuman_corpses.dm b/code/modules/mob_spawn/corpses/nonhuman_corpses.dm index 258b7b98ea6..b39c381f0f9 100644 --- a/code/modules/mob_spawn/corpses/nonhuman_corpses.dm +++ b/code/modules/mob_spawn/corpses/nonhuman_corpses.dm @@ -15,7 +15,6 @@ . = ..() dead_ai.name = src.name dead_ai.real_name = src.name - dead_ai.aiPDA.toff = TRUE //turns the AI's PDA messenger off, stopping it showing up on player PDAs ///dead slimes, with a var for whatever color you want. /obj/effect/mob_spawn/corpse/slime diff --git a/code/modules/mob_spawn/ghost_roles/unused_roles.dm b/code/modules/mob_spawn/ghost_roles/unused_roles.dm index 82a1e4a5bb8..00390d533be 100644 --- a/code/modules/mob_spawn/ghost_roles/unused_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/unused_roles.dm @@ -197,7 +197,7 @@ /obj/effect/mob_spawn/ghost_role/human/doctor/alive/equip(mob/living/carbon/human/doctor) . = ..() // Remove radio and PDA so they wouldn't annoy station crew. - var/list/del_types = list(/obj/item/pda, /obj/item/radio/headset) + var/list/del_types = list(/obj/item/modular_computer/tablet, /obj/item/radio/headset) for(var/del_type in del_types) var/obj/item/unwanted_item = locate(del_type) in doctor qdel(unwanted_item) diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index 7824401311b..6db07990ae9 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -255,9 +255,9 @@ . = ..() if(conceal_presence) // We don't want corpse PDAs to show up in the messenger list. - var/obj/item/pda/messenger = locate(/obj/item/pda) in spawned_human + var/obj/item/modular_computer/tablet/pda/messenger = locate(/obj/item/modular_computer/tablet/pda/) in spawned_human if(messenger) - messenger.toff = TRUE + messenger.invisible = TRUE // Or on crew monitors var/obj/item/clothing/under/sensor_clothes = spawned_human.w_uniform if(istype(sensor_clothes)) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 54f7f265284..e7b30d69a04 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar to GLOB.PDAs (used primarily with ntmessenger.dm) + // This is the base type that does all the hardware stuff. // Other types expand it - tablets use a direct subtypes, and // consoles and laptops use "procssor" item that is held inside machinery piece @@ -11,7 +13,11 @@ max_integrity = 100 armor = list(MELEE = 0, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 100, FIRE = 0, ACID = 0) + var/bypass_state = FALSE // bypassing the set icon state + var/enabled = 0 // Whether the computer is turned on. + var/upgradable = TRUE // whether or not the computer can be upgraded + var/deconstructable = TRUE // whether or not the computer can be deconstructed var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. var/device_theme = "ntos" // Sets the theme for the main menu, hardware config, and file browser apps. Overridden by certain non-NT devices. var/datum/computer_file/program/active_program = null // A currently active program running on the computer. @@ -46,14 +52,26 @@ /// Number of total expansion bays this computer has available. var/max_bays = 0 + var/saved_identification = null // next two values are the currently imprinted id and job values + var/saved_job = null + + var/honkamnt = 0 /// honk honk honk honk honk honkh onk honkhnoohnk + var/list/idle_threads // Idle programs on background. They still receive process calls but can't be interacted with. var/obj/physical = null // Object that represents our computer. It's used for Adjacent() and UI visibility checks. var/has_light = FALSE //If the computer has a flashlight/LED light/what-have-you installed var/comp_light_luminosity = 3 //The brightness of that light var/comp_light_color //The color of that light + var/invisible = FALSE // whether or not the tablet is invisible in messenger and other apps + + var/datum/picture/saved_image // the saved image used for messaging purpose like come on dude + + var/obj/item/paicard/pai = null /obj/item/modular_computer/Initialize(mapload) . = ..() + + var/obj/item/computer_hardware/identifier/id = all_components[MC_IDENTIFY] START_PROCESSING(SSobj, src) if(!physical) physical = src @@ -61,20 +79,28 @@ idle_threads = list() if(looping_sound) soundloop = new(src, enabled) + if(id) + id.UpdateDisplay() update_appearance() + Add_Messenger() /obj/item/modular_computer/Destroy() wipe_program(forced = TRUE) for(var/datum/computer_file/program/idle as anything in idle_threads) idle.kill_program(TRUE) - idle_threads.Cut() + idle_threads?.Cut() STOP_PROCESSING(SSobj, src) for(var/port in all_components) var/obj/item/computer_hardware/component = all_components[port] qdel(component) - all_components.Cut() //Die demon die + all_components?.Cut() //Some components will actually try and interact with this, so let's do it later QDEL_NULL(soundloop) + Remove_Messenger() + + if(istype(pai)) + QDEL_NULL(pai) + physical = null return ..() @@ -86,6 +112,16 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN return ..() +// shameless copy of newscaster photo saving + +/obj/item/modular_computer/proc/save_photo(icon/photo) + var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6) + if(!fexists("[GLOB.log_directory]/photos/[photo_file].png")) + //Clean up repeated frames + var/icon/clean = new /icon() + clean.Insert(photo, "", SOUTH, 1, 0) + fcopy(clean, "[GLOB.log_directory]/photos/[photo_file].png") + return photo_file /** * Plays a ping sound. @@ -103,7 +139,10 @@ if(user.canUseTopic(src, BE_CLOSE)) var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2] var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] - return (card_slot2?.try_eject(user) || card_slot?.try_eject(user)) //Try the secondary one first. + if(card_slot2?.try_eject(user) || card_slot?.try_eject(user)) + return TRUE + if(!istype(src, /obj/item/modular_computer/tablet)) + return FALSE // Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. /obj/item/modular_computer/GetAccess() @@ -169,6 +208,8 @@ if(human_wearer.wear_id == src) human_wearer.sec_hud_set_ID() update_slot_icon() + update_appearance() + return removed_id return ..() @@ -176,10 +217,11 @@ /obj/item/modular_computer/InsertID(obj/item/inserting_item) var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD] var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2] + if(!(card_slot || card_slot2)) return FALSE - var/obj/item/card/inserting_id = inserting_item.RemoveID() + var/obj/item/card/inserting_id = inserting_item.GetID() if(!inserting_id) return FALSE @@ -188,8 +230,8 @@ var/mob/living/carbon/human/human_wearer = loc if(human_wearer.wear_id == src) human_wearer.sec_hud_set_ID() + update_appearance() update_slot_icon() - return TRUE return FALSE @@ -241,19 +283,24 @@ . += get_modular_computer_parts_examine(user) /obj/item/modular_computer/update_icon_state() - icon_state = enabled ? icon_state_powered : icon_state_unpowered + if(!bypass_state) + icon_state = enabled ? icon_state_powered : icon_state_unpowered return ..() /obj/item/modular_computer/update_overlays() . = ..() + var/init_icon = initial(icon) + + if(!init_icon) + return if(!display_overlays) return if(enabled) - . += active_program?.program_icon_state || icon_state_menu + . += active_program ? mutable_appearance(init_icon, active_program.program_icon_state) : mutable_appearance(init_icon, icon_state_menu) if(atom_integrity <= integrity_failure * max_integrity) - . += "bsod" - . += "broken" + . += mutable_appearance(init_icon, "bsod") + . += mutable_appearance(init_icon, "broken") // On-click handling. Turns on the computer if it's off and opens the GUI. @@ -353,6 +400,16 @@ if(istype(holder)) to_chat(holder, "[icon2html(src)] [span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")]") +/obj/item/modular_computer/proc/ring(ringtone) // bring bring + if(HAS_TRAIT(SSstation, STATION_TRAIT_PDA_GLITCHED)) + playsound(src, pick('sound/machines/twobeep_voice1.ogg', 'sound/machines/twobeep_voice2.ogg'), 50, TRUE) + else + playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE) + visible_message("*[ringtone]*") + +/obj/item/modular_computer/proc/send_sound() + playsound(src, 'sound/machines/terminal_success.ogg', 15, TRUE) + // Function used by NanoUI's to obtain data for header. All relevant entries begin with "PC_" /obj/item/modular_computer/proc/get_header_data() var/list/data = list() @@ -489,6 +546,8 @@ return TRUE /obj/item/modular_computer/screwdriver_act(mob/user, obj/item/tool) + if(!deconstructable) + return if(!length(all_components)) balloon_alert(user, "no components installed!") return @@ -520,6 +579,25 @@ if(istype(W, /obj/item/card/id) && InsertID(W)) return + // Insert a PAI. + if(istype(W, /obj/item/paicard) && !pai) + if(!user.transferItemToLoc(W, src)) + return + pai = W + pai.slotted = TRUE + to_chat(user, span_notice("You slot \the [W] into [src].")) + return + + // Scan a photo. + if(istype(W, /obj/item/photo)) + var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD] + var/obj/item/photo/pic = W + if(hdd) + for(var/datum/computer_file/program/messenger/messenger in hdd.stored_files) + saved_image = pic.picture + messenger.ProcessPhoto() + return + // Insert items into the components for(var/h in all_components) var/obj/item/computer_hardware/H = all_components[h] @@ -527,7 +605,7 @@ return // Insert new hardware - if(istype(W, /obj/item/computer_hardware)) + if(istype(W, /obj/item/computer_hardware) && upgradable) if(install_component(W, user)) return @@ -574,3 +652,9 @@ if(physical && physical != src) return physical.Adjacent(neighbor) return ..() + +/obj/item/modular_computer/proc/Add_Messenger() + GLOB.TabletMessengers += src + +/obj/item/modular_computer/proc/Remove_Messenger() + GLOB.TabletMessengers -= src diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index 45f8805a4ca..7319751bc8d 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -4,6 +4,8 @@ // Operates TGUI /obj/item/modular_computer/ui_interact(mob/user, datum/tgui/ui) + if(issilicon(user)) // silicons have some issues regarding real_name + saved_identification = user.real_name if(!enabled) if(ui) ui.close() @@ -37,6 +39,10 @@ to_chat(user, span_danger("\The [src] beeps three times, it's screen displaying a \"DISK ERROR\" warning.")) return // No HDD, No HDD files list or no stored files. Something is very broken. + if(honkamnt > 0) // EXTRA annoying, huh! + honkamnt-- + playsound(src, 'sound/items/bikehorn.ogg', 30, TRUE) + ui = SStgui.try_update_ui(user, src, ui) if (!ui) ui = new(user, src, "NtosMain") @@ -44,28 +50,55 @@ if(ui.open()) ui.send_asset(get_asset_datum(/datum/asset/simple/headers)) +/obj/item/modular_computer/ui_static_data(mob/user) + . = ..() + var/list/data = list() + + data["show_imprint"] = istype(src, /obj/item/modular_computer/tablet/) + + return data + + /obj/item/modular_computer/ui_data(mob/user) var/list/data = get_header_data() data["device_theme"] = device_theme - data["login"] = list() + + data["disk"] = null + var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD] + var/obj/item/computer_hardware/hard_drive/role/ssd = all_components[MC_HDD_JOB] data["cardholder"] = FALSE + if(cardholder) data["cardholder"] = TRUE - var/obj/item/card/id/stored_card = cardholder.GetID() - if(stored_card) - var/stored_name = stored_card.registered_name - var/stored_title = stored_card.assignment - if(!stored_name) - stored_name = "Unknown" - if(!stored_title) - stored_title = "Unknown" - data["login"] = list( - IDName = stored_name, - IDJob = stored_title, - ) + + var/stored_name = saved_identification + var/stored_title = saved_job + if(!stored_name) + stored_name = "Unknown" + if(!stored_title) + stored_title = "Unknown" + data["login"] = list( + IDName = saved_identification, + IDJob = saved_job, + ) + data["proposed_login"] = list( + IDName = cardholder.current_identification, + IDJob = cardholder.current_job, + ) + + if(ssd) + data["disk"] = ssd + data["disk_name"] = ssd.name + + for(var/datum/computer_file/program/prog in ssd.stored_files) + var/running = FALSE + if(prog in idle_threads) + running = TRUE + + data["disk_programs"] += list(list("name" = prog.filename, "desc" = prog.filedesc, "running" = running, "icon" = prog.program_icon, "alert" = prog.alert_pending)) data["removable_media"] = list() if(all_components[MC_SDD]) @@ -89,6 +122,7 @@ data["has_light"] = has_light data["light_on"] = light_on data["comp_light_color"] = comp_light_color + data["pai"] = pai return data @@ -134,10 +168,15 @@ if("PC_runprogram") var/prog = params["name"] + var/is_disk = params["is_disk"] var/datum/computer_file/program/P = null + var/obj/item/computer_hardware/hard_drive/role/ssd = all_components[MC_HDD_JOB] var/mob/user = usr - if(hard_drive) + + if(hard_drive && !is_disk) P = hard_drive.find_file_by_name(prog) + if(ssd && is_disk) + P = ssd.find_file_by_name(prog) if(!P || !istype(P)) // Program not found or it's not executable program. to_chat(user, span_danger("\The [src]'s screen shows \"I/O ERROR - Unable to run program\" warning.")) @@ -198,6 +237,13 @@ if(uninstall_component(portable_drive, usr)) user.put_in_hands(portable_drive) playsound(src, 'sound/machines/card_slide.ogg', 50) + if("job disk") + var/obj/item/computer_hardware/hard_drive/role/ssd = all_components[MC_HDD_JOB] + if(!ssd) + return + if(uninstall_component(ssd, usr)) + user.put_in_hands(ssd) + playsound(src, 'sound/machines/card_slide.ogg', 50) if("intelliCard") var/obj/item/computer_hardware/ai_slot/intelliholder = all_components[MC_AI] if(!intelliholder) @@ -208,14 +254,37 @@ var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD] if(!cardholder) return - cardholder.try_eject(user) + if(cardholder.try_eject(user)) + playsound(src, 'sound/machines/card_slide.ogg', 50) if("secondary RFID card") var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD2] if(!cardholder) return - cardholder.try_eject(user) + if(cardholder.try_eject(user)) + playsound(src, 'sound/machines/card_slide.ogg', 50) + if("PC_Imprint_ID") + var/obj/item/computer_hardware/card_slot/cardholder = all_components[MC_CARD] + var/obj/item/computer_hardware/identifier/id_hardware = all_components[MC_IDENTIFY] + if(!cardholder) + return + saved_identification = cardholder.current_identification + saved_job = cardholder.current_job + if(id_hardware) + id_hardware.UpdateDisplay() + + playsound(src, 'sound/machines/terminal_processing.ogg', 15, TRUE) + if("PC_Pai_Interact") + switch(params["option"]) + if("eject") + usr.put_in_hands(pai) + pai.slotted = FALSE + pai = null + to_chat(usr, span_notice("You remove the pAI from the [name].")) + if("interact") + pai.attack_self(usr) + return UI_UPDATE else return diff --git a/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/code/modules/modular_computers/computers/item/role_tablet_presets.dm new file mode 100644 index 00000000000..9206c53eb08 --- /dev/null +++ b/code/modules/modular_computers/computers/item/role_tablet_presets.dm @@ -0,0 +1,227 @@ +/obj/item/modular_computer/tablet/pda/medical + name = "medical PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/medical + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#e2e2e2#000099#5d99be" + +/obj/item/modular_computer/tablet/pda/viro + name = "virology PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/medical + greyscale_config = /datum/greyscale_config/tablet/stripe_split + greyscale_colors = "#e2e2e2#355FAC#789876" + +/obj/item/modular_computer/tablet/pda/engineering + name = "engineering PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/engineering + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#C5994C#69DBF3#D9D65B" + +/obj/item/modular_computer/tablet/pda/security + name = "security PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/security + greyscale_colors = "#cc4242#0000cc" + +/obj/item/modular_computer/tablet/pda/detective + name = "detective PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/detective + greyscale_colors = "#90714F#990202" + +/obj/item/modular_computer/tablet/pda/warden + name = "warden PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/security + greyscale_config = /datum/greyscale_config/tablet/stripe_split + greyscale_colors = "#cc4242#0000cc#666666" + +/obj/item/modular_computer/tablet/pda/janitor + name = "janitor PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/janitor + greyscale_colors = "#933ea8#235AB2" + +/obj/item/modular_computer/tablet/pda/science + name = "scientist PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/signal/ordnance + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#e2e2e2#000099#9F5CA5" + +/obj/item/modular_computer/tablet/pda/heads + default_disk = /obj/item/computer_hardware/hard_drive/role/head + greyscale_config = /datum/greyscale_config/tablet/head + greyscale_colors = "#789876#a92323" + +/obj/item/modular_computer/tablet/pda/heads/hop + name = "head of personnel PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/hop + +/obj/item/modular_computer/tablet/pda/heads/hos + name = "head of security PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/hos + greyscale_config = /datum/greyscale_config/tablet/head + greyscale_colors = "#cc4242#0000cc" + +/obj/item/modular_computer/tablet/pda/heads/ce + name = "chief engineer PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/ce + greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head + greyscale_colors = "#C4A56D#69DBF3#e2e2e2" + +/obj/item/modular_computer/tablet/pda/heads/cmo + name = "chief medical officer PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/cmo + greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head + greyscale_colors = "#e2e2e2#000099#5d99be" + +/obj/item/modular_computer/tablet/pda/heads/rd + name = "research director PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/rd + greyscale_config = /datum/greyscale_config/tablet/stripe_thick/head + greyscale_colors = "#e2e2e2#000099#9F5CA5" + insert_type = /obj/item/pen/fountain + +/obj/item/modular_computer/tablet/pda/captain + name = "captain PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/captain + greyscale_config = /datum/greyscale_config/tablet/captain + greyscale_colors = "#2C7CB2#FF0000#FFFFFF#F5D67B" + insert_type = /obj/item/pen/fountain + +/obj/item/modular_computer/tablet/pda/captain/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_TABLET_CHECK_DETONATE, .proc/tab_no_detonate) + +/obj/item/modular_computer/tablet/pda/cargo + name = "cargo technician PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/quartermaster + greyscale_colors = "#D6B328#6506ca" + +/obj/item/modular_computer/tablet/pda/quartermaster/Initialize(mapload) + . = ..() + install_component(new /obj/item/computer_hardware/printer/mini) + +/obj/item/modular_computer/tablet/pda/quartermaster + name = "quartermaster PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/quartermaster + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#D6B328#6506ca#927444" + +/obj/item/modular_computer/tablet/pda/quartermaster/Initialize(mapload) + . = ..() + install_component(new /obj/item/computer_hardware/printer/mini) + +/obj/item/modular_computer/tablet/pda/shaftminer + name = "shaft miner PDA" + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#927444#D6B328#6C3BA1" + +/obj/item/modular_computer/tablet/pda/chaplain + name = "chaplain PDA" + greyscale_config = /datum/greyscale_config/tablet/chaplain + greyscale_colors = "#333333#d11818" + +/obj/item/modular_computer/tablet/pda/lawyer + name = "lawyer PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/lawyer + greyscale_colors = "#5B74A5#f7e062" + insert_type = /obj/item/pen/fountain + +/obj/item/modular_computer/tablet/pda/botanist + name = "botanist PDA" + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#50E193#E26F41#71A7CA" + +/obj/item/modular_computer/tablet/pda/roboticist + name = "roboticist PDA" + greyscale_config = /datum/greyscale_config/tablet/stripe_split + greyscale_colors = "#484848#0099cc#d33725" + default_disk = /obj/item/computer_hardware/hard_drive/role/roboticist + +/obj/item/modular_computer/tablet/pda/cook + name = "cook PDA" + greyscale_colors = "#e2e2e2#a92323" + +/obj/item/modular_computer/tablet/pda/bar + name = "bartender PDA" + greyscale_colors = "#333333#c7c7c7" + +/obj/item/modular_computer/tablet/pda/atmos + name = "atmospherics PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/atmos + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#ceca2b#00E5DA#727272" + +/obj/item/modular_computer/tablet/pda/chemist + name = "chemist PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/chemistry + greyscale_config = /datum/greyscale_config/tablet/stripe_thick + greyscale_colors = "#e2e2e2#355FAC#ea6400" + +/obj/item/modular_computer/tablet/pda/geneticist + name = "geneticist PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/medical + greyscale_config = /datum/greyscale_config/tablet/stripe_split + greyscale_colors = "#e2e2e2#000099#0097ca" + +/obj/item/modular_computer/tablet/pda/clown + name = "clown PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/virus/clown + icon_state = "pda-clown" + greyscale_config = null + greyscale_colors = null + insert_type = /obj/item/toy/crayon/rainbow + +/obj/item/modular_computer/tablet/pda/clown/ComponentInitialize() + . = ..() + AddComponent(/datum/component/slippery/clowning, 120, NO_SLIP_WHEN_WALKING, CALLBACK(src, .proc/AfterSlip), slot_whitelist = list(ITEM_SLOT_ID, ITEM_SLOT_BELT)) + AddComponent(/datum/component/wearertargeting/sitcomlaughter, CALLBACK(src, .proc/after_sitcom_laugh)) + +/obj/item/modular_computer/tablet/pda/clown/update_overlays() + . = ..() + . += mutable_appearance(icon, "pda_stripe_clown") // clowns have eyes that go over their screen, so it needs to be compiled last + +/obj/item/modular_computer/tablet/pda/clown/proc/AfterSlip(mob/living/carbon/human/M) + if (istype(M) && (M.real_name != saved_identification)) + var/obj/item/computer_hardware/hard_drive/role/virus/clown/cart = all_components[MC_HDD_JOB] + if(istype(cart) && cart.charges < 5) + cart.charges++ + playsound(src,'sound/machines/ping.ogg',30,TRUE) + +/obj/item/modular_computer/tablet/pda/clown/proc/after_sitcom_laugh(mob/victim) + victim.visible_message("[src] lets out a burst of laughter!") + +/obj/item/modular_computer/tablet/pda/mime + name = "mime PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/virus/mime + greyscale_config = /datum/greyscale_config/tablet/mime + greyscale_colors = "#e2e2e2#cc4242" + insert_type = /obj/item/toy/crayon/mime + +/obj/item/modular_computer/tablet/pda/mime/Initialize(mapload) + . = ..() + var/obj/item/computer_hardware/hard_drive/hdd = all_components[MC_HDD] + + if(hdd) + for(var/datum/computer_file/program/messenger/msg in hdd.stored_files) + msg.mime_mode = TRUE + msg.allow_emojis = TRUE + +/obj/item/modular_computer/tablet/pda/curator + name = "curator PDA" + default_disk = /obj/item/computer_hardware/hard_drive/role/curator + greyscale_config = null + greyscale_colors = null + icon_state = "pda-library" + insert_type = /obj/item/pen/fountain + display_overlays = FALSE + +/obj/item/modular_computer/tablet/pda/syndicate + name = "military PDA" + greyscale_colors = "#891417#80FF80" + saved_identification = "John Doe" + saved_job = "Citizen" + invisible = TRUE + +/obj/item/modular_computer/tablet/pda/clear + name = "clear PDA" + icon_state = "pda-clear" + greyscale_config = null + greyscale_colors = null + diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm index f69f3bbb0ef..0b7994a4fa0 100644 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ b/code/modules/modular_computers/computers/item/tablet.dm @@ -16,16 +16,95 @@ has_light = TRUE //LED flashlight! comp_light_luminosity = 2.3 //Same as the PDA looping_sound = FALSE + var/has_variants = TRUE var/finish_color = null + var/list/contained_item = list(/obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, /obj/item/clothing/mask/cigarette) + var/obj/item/insert_type = /obj/item/pen + var/obj/item/inserted_item + + var/note = "Congratulations on your station upgrading to the new NtOS and Thinktronic based collaboration effort, bringing you the best in electronics and software since 2467!" // the note used by the notekeeping app, stored here for convenience + /obj/item/modular_computer/tablet/update_icon_state() - if(has_variants) + if(has_variants && !bypass_state) if(!finish_color) finish_color = pick("red", "blue", "brown", "green", "black") icon_state = icon_state_powered = icon_state_unpowered = "[base_icon_state]-[finish_color]" return ..() +/obj/item/modular_computer/tablet/interact(mob/user) + . = ..() + if(HAS_TRAIT(src, TRAIT_PDA_MESSAGE_MENU_RIGGED)) + explode(usr, from_message_menu = TRUE) + return + +/obj/item/modular_computer/tablet/attackby(obj/item/W, mob/user) + . = ..() + + if(is_type_in_list(W, contained_item)) + if(inserted_item) + to_chat(user, span_warning("There is already \a [inserted_item] in \the [src]!")) + else + if(!user.transferItemToLoc(W, src)) + return + to_chat(user, span_notice("You insert \the [W] into \the [src].")) + inserted_item = W + playsound(src, 'sound/machines/pda_button1.ogg', 50, TRUE) + +/obj/item/modular_computer/tablet/AltClick(mob/user) + . = ..() + if(.) + return + + remove_pen(user) + +/obj/item/modular_computer/tablet/proc/tab_no_detonate() + SIGNAL_HANDLER + return COMPONENT_TABLET_NO_DETONATE + +/obj/item/modular_computer/tablet/proc/remove_pen(mob/user) + + if(issilicon(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) //TK doesn't work even with this removed but here for readability + return + + if(inserted_item) + to_chat(user, span_notice("You remove [inserted_item] from [src].")) + user.put_in_hands(inserted_item) + inserted_item = null + update_appearance() + playsound(src, 'sound/machines/pda_button2.ogg', 50, TRUE) + else + to_chat(user, span_warning("This tablet does not have a pen in it!")) + +// Tablet 'splosion.. + +/obj/item/modular_computer/tablet/proc/explode(mob/target, mob/bomber, from_message_menu = FALSE) + var/turf/T = get_turf(src) + + if(from_message_menu) + log_bomber(null, null, target, "'s tablet exploded as [target.p_they()] tried to open their tablet message menu because of a recent tablet bomb.") + else + log_bomber(bomber, "successfully tablet-bombed", target, "as [target.p_they()] tried to reply to a rigged tablet message [bomber && !is_special_character(bomber) ? "(SENT BY NON-ANTAG)" : ""]") + + if (ismob(loc)) + var/mob/M = loc + M.show_message(span_userdanger("Your [src] explodes!"), MSG_VISUAL, span_warning("You hear a loud *pop*!"), MSG_AUDIBLE) + else + visible_message(span_danger("[src] explodes!"), span_warning("You hear a loud *pop*!")) + + target.client?.give_award(/datum/award/achievement/misc/clickbait, target) + + if(T) + T.hotspot_expose(700,125) + if(istype(all_components[MC_HDD_JOB], /obj/item/computer_hardware/hard_drive/role/virus/deto)) + explosion(src, devastation_range = -1, heavy_impact_range = 1, light_impact_range = 3, flash_range = 4) + else + explosion(src, devastation_range = -1, heavy_impact_range = -1, light_impact_range = 2, flash_range = 3) + qdel(src) + +// SUBTYPES + /obj/item/modular_computer/tablet/syndicate_contract_uplink name = "contractor tablet" icon = 'icons/obj/contractor_tablet.dmi' @@ -65,8 +144,8 @@ has_light = FALSE //tablet light button actually enables/disables the borg lamp comp_light_luminosity = 0 has_variants = FALSE - ///Ref to the borg we're installed in. Set by the borg during our creation. - var/mob/living/silicon/robot/borgo + ///Ref to the silicon we're installed in. Set by the borg during our creation. + var/mob/living/silicon/borgo ///Ref to the RoboTact app. Important enough to borgs to deserve a ref. var/datum/computer_file/program/robotact/robotact ///IC log that borgs can view in their personal management app @@ -119,22 +198,28 @@ /obj/item/modular_computer/tablet/integrated/ui_data(mob/user) . = ..() .["has_light"] = TRUE - .["light_on"] = borgo?.lamp_enabled - .["comp_light_color"] = borgo?.lamp_color + if(istype(borgo, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/robo = borgo + .["light_on"] = robo.lamp_enabled + .["comp_light_color"] = robo.lamp_color //Makes the flashlight button affect the borg rather than the tablet /obj/item/modular_computer/tablet/integrated/toggle_flashlight() if(!borgo || QDELETED(borgo)) return FALSE - borgo.toggle_headlamp() + if(istype(borgo, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/robo = borgo + robo.toggle_headlamp() return TRUE //Makes the flashlight color setting affect the borg rather than the tablet /obj/item/modular_computer/tablet/integrated/set_flashlight_color(color) if(!borgo || QDELETED(borgo) || !color) return FALSE - borgo.lamp_color = color - borgo.toggle_headlamp(FALSE, TRUE) + if(istype(borgo, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/robo = borgo + robo.lamp_color = color + robo.toggle_headlamp(FALSE, TRUE) return TRUE /obj/item/modular_computer/tablet/integrated/alert_call(datum/computer_file/program/caller, alerttext, sound = 'sound/machines/twobeep_high.ogg') @@ -143,6 +228,8 @@ borgo.playsound_local(src, sound, 50, TRUE) to_chat(borgo, span_notice("The [src] displays a [caller.filedesc] notification: [alerttext]")) +/obj/item/modular_computer/tablet/integrated/ui_state(mob/user) + return GLOB.reverse_contained_state /obj/item/modular_computer/tablet/integrated/syndicate icon_state = "tablet-silicon-syndicate" @@ -153,4 +240,51 @@ /obj/item/modular_computer/tablet/integrated/syndicate/Initialize(mapload) . = ..() - borgo.lamp_color = COLOR_RED //Syndicate likes it red + if(istype(borgo, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/robo = borgo + robo.lamp_color = COLOR_RED //Syndicate likes it red + +// Round start tablets + +/obj/item/modular_computer/tablet/pda + icon_state = "pda" + + greyscale_config = /datum/greyscale_config/tablet + greyscale_colors = "#999875#a92323" + + bypass_state = TRUE + + var/default_disk = 0 + +/obj/item/modular_computer/tablet/pda/update_overlays() + . = ..() + var/init_icon = initial(icon) + var/obj/item/computer_hardware/card_slot/card = all_components[MC_CARD] + if(!init_icon) + return + if(card) + if(card.stored_card) + . += mutable_appearance(init_icon, "id_overlay") + if(light_on) + . += mutable_appearance(init_icon, "light_overlay") + +/obj/item/modular_computer/tablet/pda/attack_ai(mob/user) + to_chat(user, span_notice("It doesn't feel right to snoop around like that...")) + return // we don't want ais or cyborgs using a private role tablet + +/obj/item/modular_computer/tablet/pda/Initialize(mapload) + . = ..() + install_component(new /obj/item/computer_hardware/hard_drive/small) + install_component(new /obj/item/computer_hardware/processor_unit/small) + install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) + install_component(new /obj/item/computer_hardware/network_card) + install_component(new /obj/item/computer_hardware/card_slot) + install_component(new /obj/item/computer_hardware/identifier) + install_component(new /obj/item/computer_hardware/sensorpackage) + + if(default_disk) + var/obj/item/computer_hardware/hard_drive/portable/disk = new default_disk(src) + install_component(disk) + + if(insert_type) + inserted_item = new insert_type(src) diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm index bbde8533364..1bb4124fdf5 100644 --- a/code/modules/modular_computers/computers/item/tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/tablet_presets.dm @@ -107,6 +107,5 @@ /obj/item/modular_computer/tablet/integrated/Initialize(mapload) . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) - install_component(new /obj/item/computer_hardware/hard_drive/small/integrated) install_component(new /obj/item/computer_hardware/recharger/cyborg) install_component(new /obj/item/computer_hardware/network_card/integrated) diff --git a/code/modules/modular_computers/file_system/programs/newscasterapp.dm b/code/modules/modular_computers/file_system/programs/newscasterapp.dm index dd3fcb8d5fe..8b422470fda 100644 --- a/code/modules/modular_computers/file_system/programs/newscasterapp.dm +++ b/code/modules/modular_computers/file_system/programs/newscasterapp.dm @@ -3,7 +3,7 @@ filedesc = "Newscaster" required_access = list(ACCESS_LIBRARY) category = PROGRAM_CATEGORY_CREW - program_icon_state = "computer" + program_icon_state = "bountyboard" extended_desc = "This program allows any user to access the Newscaster network from anywhere." size = 2 requires_ntnet = TRUE diff --git a/code/modules/modular_computers/file_system/programs/notepad.dm b/code/modules/modular_computers/file_system/programs/notepad.dm new file mode 100644 index 00000000000..1d505cc42c1 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/notepad.dm @@ -0,0 +1,29 @@ +/datum/computer_file/program/notepad + filename = "notepad" + filedesc = "Notepad" + category = PROGRAM_CATEGORY_MISC + program_icon_state = "generic" + extended_desc = "Jot down your work-safe thoughts and what not." + size = 2 + tgui_id = "NtosNotepad" + program_icon = "book" + usage_flags = PROGRAM_TABLET + +/datum/computer_file/program/notepad/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + switch(action) + if("UpdateNote") + var/obj/item/modular_computer/tablet/comp = computer + comp.note = params["newnote"] + return UI_UPDATE + +/datum/computer_file/program/notepad/ui_data(mob/user) + var/list/data = get_header_data() + var/obj/item/modular_computer/tablet/comp = computer + + data["note"] = comp.note + + return data diff --git a/code/modules/modular_computers/file_system/programs/ntmessenger.dm b/code/modules/modular_computers/file_system/programs/ntmessenger.dm new file mode 100644 index 00000000000..a2f16f548d4 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/ntmessenger.dm @@ -0,0 +1,366 @@ +/datum/computer_file/program/messenger + filename = "nt_messenger" + filedesc = "Direct Messenger" + category = PROGRAM_CATEGORY_MISC + program_icon_state = "command" + extended_desc = "This program allows old-school communication with other modular devices." + size = 8 + usage_flags = PROGRAM_TABLET + ui_header = "ntnrc_idle.gif" + available_on_ntnet = TRUE + tgui_id = "NtosMessenger" + program_icon = "comment-alt" + alert_able = TRUE + + /// The current ringtone (displayed in the chat when a message is received). + var/ringtone = "beep" + /// Whether or not the ringtone is currently on. + var/ringer_status = TRUE + /// Whether or not we're sending and receiving messages. + var/sending_and_receiving = TRUE + /// The messages currently saved in the app. + var/messages = list() + /// great wisdom from PDA.dm - "no spamming" (prevents people from spamming the same message over and over) + var/last_text + /// even more wisdom from PDA.dm - "no everyone spamming" (prevents people from spamming the same message over and over) + var/last_text_everyone + /// Scanned photo for sending purposes. + var/datum/picture/picture + /// Whether or not we allow emojis to be sent by the user. + var/allow_emojis = FALSE + /// Whether or not we're currently looking at the message list. + var/viewing_messages = FALSE + // Whether or not this device is currently hidden from the message monitor. + var/monitor_hidden = FALSE + // Whether or not we're sorting by job. + var/sort_by_job = TRUE + // Whether or not we're sending (or trying to send) a virus. + var/sending_virus = FALSE + + /// The path for the current loaded image in rsc + var/photo_path + + /// Whether or not this app is loaded on a silicon's tablet. + var/is_silicon = FALSE + /// Whether or not we're in a mime PDA. + var/mime_mode = FALSE + +/datum/computer_file/program/messenger/proc/ScrubMessengerList() + var/list/dictionary = list() + + for(var/obj/item/modular_computer/messenger in GetViewableDevices(sort_by_job)) + if(messenger.saved_identification && messenger.saved_job && !(messenger == computer)) + var/list/data = list() + data["name"] = messenger.saved_identification + data["job"] = messenger.saved_job + data["ref"] = REF(messenger) + + //if(data["ref"] != REF(computer)) // you cannot message yourself (despite all my rage) + dictionary += list(data) + + return dictionary + +/proc/GetViewableDevices(sort_by_job = FALSE) + var/list/dictionary = list() + + var/sortmode + if(sort_by_job) + sortmode = /proc/cmp_pdajob_asc + else + sortmode = /proc/cmp_pdaname_asc + + for(var/obj/item/modular_computer/P in sort_list(GLOB.TabletMessengers, sortmode)) + var/obj/item/computer_hardware/hard_drive/drive = P.all_components[MC_HDD] + if(!drive) + continue + for(var/datum/computer_file/program/messenger/app in drive.stored_files) + if(!P.saved_identification || !P.saved_job || P.invisible || app.monitor_hidden) + continue + dictionary += P + + return dictionary + +/datum/computer_file/program/messenger/proc/StringifyMessengerTarget(obj/item/modular_computer/messenger) + return "[messenger.saved_identification] ([messenger.saved_job])" + +/datum/computer_file/program/messenger/proc/ProcessPhoto() + if(computer.saved_image) + var/icon/img = computer.saved_image.picture_image + var/deter_path = "tmp_msg_photo[rand(0, 99999)].png" + usr << browse_rsc(img, deter_path) // funny random assignment for now, i'll make an actual key later + photo_path = deter_path + +/datum/computer_file/program/messenger/ui_state(mob/user) + if(istype(user, /mob/living/silicon)) + return GLOB.reverse_contained_state + return GLOB.default_state + +/datum/computer_file/program/messenger/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + switch(action) + if("PDA_ringSet") + var/t = tgui_input_text(usr, "Enter a new tablet ID", "Computer ID", "", 20) + var/mob/living/usr_mob = usr + if(in_range(computer, usr_mob) && computer.loc == usr_mob && t) + if(SEND_SIGNAL(computer, COMSIG_TABLET_CHANGE_ID, usr_mob, t) & COMPONENT_STOP_RINGTONE_CHANGE) + return + else + ringtone = t + return(UI_UPDATE) + if("PDA_ringer_status") + ringer_status = !ringer_status + return(UI_UPDATE) + if("PDA_sAndR") + sending_and_receiving = !sending_and_receiving + return(UI_UPDATE) + if("PDA_viewMessages") + viewing_messages = !viewing_messages + return(UI_UPDATE) + if("PDA_clearMessages") + messages = list() + return(UI_UPDATE) + if("PDA_changeSortStyle") + sort_by_job = !sort_by_job + return(UI_UPDATE) + if("PDA_sendEveryone") + if(!sending_and_receiving) + to_chat(usr, span_notice("ERROR: Device has sending disabled.")) + return + + var/list/targets = list() + + for(var/obj/item/modular_computer/mc in GetViewableDevices()) + targets += mc + + if(targets.len > 0) + send_message(usr, targets, TRUE) + + return(UI_UPDATE) + if("PDA_sendMessage") + if(!sending_and_receiving) + to_chat(usr, span_notice("ERROR: Device has sending disabled.")) + return + var/obj/item/modular_computer/target = locate(params["ref"]) + if(!target) + return // we don't want tommy sending his messages to nullspace + if(!(target.saved_identification == params["name"] && target.saved_job == params["job"])) + to_chat(usr, span_notice("ERROR: User no longer exists.")) + return + + var/obj/item/computer_hardware/hard_drive/drive = target.all_components[MC_HDD] + + for(var/datum/computer_file/program/messenger/app in drive.stored_files) + if(!app.sending_and_receiving && !sending_virus) + to_chat(usr, span_notice("ERROR: Device has receiving disabled.")) + return + if(sending_virus) + var/obj/item/computer_hardware/hard_drive/role/virus/disk = computer.all_components[MC_HDD_JOB] + if(istype(disk)) + disk.send_virus(target, usr) + return(UI_UPDATE) + send_message(usr, list(target)) + return(UI_UPDATE) + if("PDA_clearPhoto") + computer.saved_image = null + photo_path = null + return(UI_UPDATE) + if("PDA_toggleVirus") + sending_virus = !sending_virus + return(UI_UPDATE) + + +/datum/computer_file/program/messenger/ui_data(mob/user) + var/list/data = get_header_data() + + var/obj/item/computer_hardware/hard_drive/role/disk = computer.all_components[MC_HDD_JOB] + + data["owner"] = computer.saved_identification + data["messages"] = messages + data["ringer_status"] = ringer_status + data["sending_and_receiving"] = sending_and_receiving + data["messengers"] = ScrubMessengerList() + data["viewing_messages"] = viewing_messages + data["sortByJob"] = sort_by_job + data["isSilicon"] = is_silicon + data["photo"] = photo_path + + if(disk) + data["canSpam"] = disk.CanSpam() + data["virus_attach"] = istype(disk, /obj/item/computer_hardware/hard_drive/role/virus) + data["sending_virus"] = sending_virus + + return data + +//////////////////////// +// MESSAGE HANDLING +//////////////////////// + +// How I Learned To Stop Being A PDA Bloat Chump And Learn To Embrace The Lightweight + +// Gets the input for a message being sent. + +/datum/computer_file/program/messenger/proc/msg_input(mob/living/U = usr, rigged = FALSE) + var/t = null + + if(mime_mode) + t = emoji_sanitize(tgui_input_text(U, "Enter emojis", "NT Messaging")) + else + t = tgui_input_text(U, "Enter a message", "NT Messaging") + + if (!t || !sending_and_receiving) + return + if(!U.canUseTopic(computer, BE_CLOSE)) + return + return sanitize(t) + +/datum/computer_file/program/messenger/proc/send_message(mob/living/user, list/obj/item/modular_computer/targets, everyone = FALSE, rigged = FALSE, fake_name = null, fake_job = null) + var/message = msg_input(user, rigged) + if(!message || !targets.len) + return FALSE + if((last_text && world.time < last_text + 10) || (everyone && last_text_everyone && world.time < last_text_everyone + 2 MINUTES)) + return FALSE + + var/turf/position = get_turf(computer) + for(var/obj/item/jammer/jammer as anything in GLOB.active_jammers) + var/turf/jammer_turf = get_turf(jammer) + if(position?.z == jammer_turf.z && (get_dist(position, jammer_turf) <= jammer.range)) + return FALSE + + var/list/filter_result = CAN_BYPASS_FILTER(user) ? null : is_ic_filtered_for_pdas(message) + if (filter_result) + REPORT_CHAT_FILTER_TO_USER(user, filter_result) + return FALSE + + var/list/soft_filter_result = CAN_BYPASS_FILTER(user) ? null : is_soft_ic_filtered_for_pdas(message) + if (soft_filter_result) + if(tgui_alert(usr,"Your message contains \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". \"[soft_filter_result[CHAT_FILTER_INDEX_REASON]]\", Are you sure you want to send it?", "Soft Blocked Word", list("Yes", "No")) != "Yes") + return FALSE + message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[html_encode(message)]\"") + log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\" they may be using a disallowed term in PDA messages. Message: \"[message]\"") + + // Send the signal + var/list/string_targets = list() + for (var/obj/item/modular_computer/comp in targets) + if (comp.saved_identification && comp.saved_job) // != src is checked by the UI + string_targets += STRINGIFY_PDA_TARGET(comp.saved_identification, comp.saved_job) + + if (!string_targets.len) + return FALSE + + var/datum/signal/subspace/messaging/tablet_msg/signal = new(computer, list( + "name" = fake_name || computer.saved_identification, + "job" = fake_job || computer.saved_job, + "message" = html_decode(message), + "ref" = REF(computer), + "targets" = targets, + "emojis" = allow_emojis, + "rigged" = rigged, + "photo" = photo_path, + "automated" = FALSE, + )) + if(rigged) //Will skip the message server and go straight to the hub so it can't be cheesed by disabling the message server machine + signal.data["rigged_user"] = REF(user) // Used for bomb logging + signal.server_type = /obj/machinery/telecomms/hub + signal.data["reject"] = FALSE // Do not refuse the message + + signal.send_to_receivers() + + // If it didn't reach, note that fact + if (!signal.data["done"]) + to_chat(user, span_notice("ERROR: Server isn't responding.")) + //if(!silent) + //playsound(src, 'sound/machines/terminal_error.ogg', 15, TRUE) + return FALSE + + if(allow_emojis) + message = emoji_parse(message)//already sent- this just shows the sent emoji as one to the sender in the to_chat + signal.data["message"] = emoji_parse(signal.data["message"]) + + // Log it in our logs + var/list/message_data = list() + message_data["name"] = signal.data["name"] + message_data["job"] = signal.data["job"] + message_data["contents"] = html_decode(signal.data["message"]) + message_data["outgoing"] = TRUE + message_data["ref"] = signal.data["ref"] + message_data["photo"] = signal.data["photo"] + + // Show it to ghosts + var/ghost_message = span_name("[message_data["name"]] [rigged ? "Rigged" : ""] PDA Message --> [span_name("[signal.format_target()]")]: [signal.data["message"]]") + for(var/mob/M in GLOB.player_list) + if(isobserver(M) && (M.client?.prefs.chat_toggles & CHAT_GHOSTPDA)) + to_chat(M, "[FOLLOW_LINK(M, user)] [ghost_message]") + + // Log in the talk log + user.log_talk(message, LOG_PDA, tag="[rigged ? "Rigged" : ""] PDA: [initial(message_data["name"])] to [signal.format_target()]") + if(rigged) + log_bomber(user, "sent a rigged PDA message (Name: [message_data["name"]]. Job: [message_data["job"]]) to [english_list(string_targets)] [!is_special_character(user) ? "(SENT BY NON-ANTAG)" : ""]") + to_chat(user, span_info("PDA message sent to [signal.format_target()]: [signal.data["message"]]")) + + if (ringer_status) + computer.send_sound() + + last_text = world.time + if (everyone) + message_data["name"] = "Everyone" + message_data["job"] = "" + last_text_everyone = world.time + + messages += list(message_data) + return TRUE + +/datum/computer_file/program/messenger/proc/receive_message(datum/signal/subspace/messaging/tablet_msg/signal) + var/list/message_data = list() + message_data["name"] = signal.data["name"] + message_data["job"] = signal.data["job"] + message_data["contents"] = html_decode(signal.data["message"]) + message_data["outgoing"] = FALSE + message_data["ref"] = signal.data["ref"] + message_data["automated"] = signal.data["automated"] + message_data["photo"] = signal.data["photo"] + messages += list(message_data) + + var/mob/living/L = null + if(computer.loc && isliving(computer.loc)) + L = computer.loc + //Maybe they are a pAI! + else + L = get(computer, /mob/living/silicon) + + if(L && (L.stat == CONSCIOUS || L.stat == SOFT_CRIT)) + var/reply = "(Reply)" + var/hrefstart + var/hrefend + if (isAI(L)) + hrefstart = "" + hrefend = "" + + if(signal.data["automated"]) + reply = "\[Automated Message\]" + + var/inbound_message = signal.format_message() + if(signal.data["emojis"] == TRUE)//so will not parse emojis as such from pdas that don't send emojis + inbound_message = emoji_parse(inbound_message) + + if(ringer_status) + to_chat(L, "[icon2html(src)] PDA message from [hrefstart][signal.data["name"]] ([signal.data["job"]])[hrefend], [inbound_message] [reply]") + + + if (ringer_status) + computer.ring(ringtone) + +/datum/computer_file/program/messenger/Topic(href, href_list) + ..() + + if(!href_list["close"] && usr.canUseTopic(computer, BE_CLOSE, FALSE, NO_TK)) + switch(href_list["choice"]) + if("Message") + send_message(usr, list(locate(href_list["target"]))) + if("Mess_us_up") + if(!HAS_TRAIT(src, TRAIT_PDA_CAN_EXPLODE)) + var/obj/item/modular_computer/tablet/comp = computer + comp.explode(usr, from_message_menu = TRUE) + return diff --git a/code/modules/modular_computers/file_system/programs/phys_scanner.dm b/code/modules/modular_computers/file_system/programs/phys_scanner.dm new file mode 100644 index 00000000000..804ada70b8e --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/phys_scanner.dm @@ -0,0 +1,78 @@ +/datum/computer_file/program/phys_scanner + filename = "phys_scanner" + filedesc = "Physical Scanner" + category = PROGRAM_CATEGORY_MISC + extended_desc = "This program allows the tablet to scan physical objects and display a data output." + size = 8 + usage_flags = PROGRAM_TABLET + available_on_ntnet = FALSE + tgui_id = "NtosPhysScanner" + program_icon = "barcode" + + var/current_mode = 0 + var/available_modes = 0 + + var/last_record = "" + +/datum/computer_file/program/phys_scanner/proc/ReadModes() + var/reads = list() + + if(available_modes & DISK_CHEM) + reads += "Reagent" + + if(available_modes & DISK_MED) + reads += "Health" + + return reads + +/datum/computer_file/program/phys_scanner/proc/ReadCurrent() + if(current_mode & DISK_CHEM) + return "Reagent" + if(current_mode & DISK_MED) + return "Health" + +/datum/computer_file/program/phys_scanner/tap(atom/A, mob/living/user, params) + . = ..() + + switch(current_mode) + if(DISK_CHEM) + if(!isnull(A.reagents)) + if(A.reagents.reagent_list.len > 0) + var/reagents_length = A.reagents.reagent_list.len + last_record = "[reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found." + for (var/re in A.reagents.reagent_list) + last_record += "\t [re]" + else + last_record = "No active chemical agents found in [A]." + else + last_record = "No significant chemical agents found in [A]." + if(DISK_MED) + var/mob/living/carbon/carbon = A + if(istype(carbon)) + carbon.visible_message(span_notice("[user] analyzes [A]'s vitals.")) + last_record = healthscan(user, carbon, 1, tochat = FALSE) + +/datum/computer_file/program/phys_scanner/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + switch(action) + if("selectMode") + switch(params["newMode"]) + if("Reagent") + current_mode = DISK_CHEM + if("Health") + current_mode = DISK_MED + + return UI_UPDATE + + +/datum/computer_file/program/phys_scanner/ui_data(mob/user) + var/list/data = get_header_data() + + data["set_mode"] = ReadCurrent() + data["last_record"] = last_record + data["available_modes"] = ReadModes() + + return data diff --git a/code/modules/modular_computers/file_system/programs/records.dm b/code/modules/modular_computers/file_system/programs/records.dm new file mode 100644 index 00000000000..d96f89779fe --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/records.dm @@ -0,0 +1,74 @@ +/datum/computer_file/program/records + filename = "ntrecords" + filedesc = "Records" + extended_desc = "Allows the user to view several basic records from the crew." + category = PROGRAM_CATEGORY_MISC + program_icon = "clipboard" + program_icon_state = "crew" + tgui_id = "NtosRecords" + size = 4 + usage_flags = PROGRAM_TABLET | PROGRAM_LAPTOP + available_on_ntnet = FALSE + + var/mode + +/datum/computer_file/program/records/medical + filedesc = "Medical Records" + filename = "medrecords" + program_icon = "book-medical" + extended_desc = "Allows the user to view several basic medical records from the crew." + transfer_access = list(ACCESS_MEDICAL, ACCESS_FLAG_COMMAND) + available_on_ntnet = TRUE + mode = "medical" + +/datum/computer_file/program/records/security + filedesc = "Security Records" + filename = "secrecords" + extended_desc = "Allows the user to view several basic security records from the crew." + transfer_access = list(ACCESS_SECURITY, ACCESS_FLAG_COMMAND) + available_on_ntnet = TRUE + mode = "security" + +/datum/computer_file/program/records/proc/GetRecordsReadable() + var/list/all_records = list() + + switch(mode) + if("security") + for(var/datum/data/record/person in GLOB.data_core.general) + var/datum/data/record/security_person = find_record("id", person.fields["id"], GLOB.data_core.security) + var/list/current_record = list() + + if(security_person) + current_record["wanted"] = security_person.fields["criminal"] + + current_record["id"] = person.fields["id"] + current_record["name"] = person.fields["name"] + current_record["rank"] = person.fields["rank"] + current_record["gender"] = person.fields["gender"] + current_record["age"] = person.fields["age"] + current_record["species"] = person.fields["species"] + current_record["fingerprint"] = person.fields["fingerprint"] + + all_records += list(current_record) + if("medical") + for(var/datum/data/record/person in GLOB.data_core.medical) + var/list/current_record = list() + + current_record["name"] = person.fields["name"] + current_record["bloodtype"] = person.fields["blood_type"] + current_record["mi_dis"] = person.fields["mi_dis"] + current_record["ma_dis"] = person.fields["ma_dis"] + current_record["notes"] = person.fields["notes"] + current_record["cnotes"] = person.fields["notes_d"] + + all_records += list(current_record) + + return all_records + + + +/datum/computer_file/program/records/ui_data(mob/user) + var/list/data = get_header_data() + data["records"] = GetRecordsReadable() + data["mode"] = mode + return data diff --git a/code/modules/modular_computers/file_system/programs/robocontrol.dm b/code/modules/modular_computers/file_system/programs/robocontrol.dm index e7d7e89ae30..b3cdb793a45 100644 --- a/code/modules/modular_computers/file_system/programs/robocontrol.dm +++ b/code/modules/modular_computers/file_system/programs/robocontrol.dm @@ -13,6 +13,8 @@ var/botcount = 0 ///Access granted by the used to summon robots. var/list/current_access = list() + ///Whether or not this is the cartridge program version. + var/cart_mode = FALSE var/list/drone_ping_types = list( "Low", "Medium", @@ -27,20 +29,23 @@ var/list/botlist = list() var/list/mulelist = list() + var/obj/item/computer_hardware/hard_drive/role/job_disk = computer ? computer.all_components[MC_HDD_JOB] : null var/obj/item/computer_hardware/card_slot/card_slot = computer ? computer.all_components[MC_CARD] : null - var/obj/item/card/id/id_card = card_slot?.stored_card data["have_id_slot"] = !!card_slot if(computer) - data["has_id"] = !!id_card - data["id_owner"] = id_card ? id_card.registered_name : "No Card Inserted." - data["access_on_card"] = id_card ? id_card.access : null + var/obj/item/card/id/id_card = card_slot ? card_slot.stored_card : "" + data["id_owner"] = id_card + if(cart_mode && job_disk) + data["id_owner"] = "JOB DISK OVERRIDE" botcount = 0 for(var/mob/living/simple_animal/bot/simple_bot as anything in GLOB.bots_list) if(simple_bot.z != zlevel || !(simple_bot.bot_mode_flags & BOT_MODE_REMOTE_ENABLED)) //Only non-emagged bots on the same Z-level are detected! continue - if(computer && !simple_bot.check_access(user, id_card)) // Only check Bots we can access + if(computer && !simple_bot.check_access(user) && !cart_mode) // Only check Bots we can access) + continue + if(!(simple_bot.bot_type in job_disk.bot_access) && cart_mode) continue var/list/newbot = list( "name" = simple_bot.name, diff --git a/code/modules/modular_computers/file_system/programs/signaler.dm b/code/modules/modular_computers/file_system/programs/signaler.dm index 125b43e4d67..78b2897466f 100644 --- a/code/modules/modular_computers/file_system/programs/signaler.dm +++ b/code/modules/modular_computers/file_system/programs/signaler.dm @@ -19,14 +19,16 @@ . = ..() if (!.) return - if(!computer?.get_modular_computer_part(MC_SIGNALER)) //Giving a clue to users why the program is spitting out zeros. + var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB) + if(!(computer?.get_modular_computer_part(MC_SIGNALER) || istype(disk))) //Giving a clue to users why the program is spitting out zeros. to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\signal_hardware\\startup.bin -- file not found\".")) /datum/computer_file/program/signaler/ui_data(mob/user) var/list/data = get_header_data() var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER) - if(sensor?.check_functionality()) + var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB) + if(sensor?.check_functionality() || istype(disk)) data["frequency"] = signal_frequency data["code"] = signal_code data["minFrequency"] = MIN_FREE_FREQ @@ -38,7 +40,8 @@ if(.) return var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER) - if(!(sensor?.check_functionality())) + var/obj/item/computer_hardware/hard_drive/role/signal/disk = computer?.get_modular_computer_part(MC_HDD_JOB) + if(!(sensor?.check_functionality() || istype(disk))) playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE) return switch(action) @@ -65,18 +68,19 @@ return var/time = time2text(world.realtime,"hh:mm:ss") - var/turf/T = get_turf(src) + var/turf/T = get_turf(computer) var/logging_data if(usr) - logging_data = "[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(signal_frequency)]/[signal_code]" + message_admins("usr is true") + logging_data = "[time] : [usr.key] used [computer] @ location ([T.x],[T.y],[T.z]) : [format_frequency(signal_frequency)]/[signal_code]" GLOB.lastsignalers.Add(logging_data) var/datum/signal/signal = new(list("code" = signal_code), logging_data = logging_data) - radio_connection.post_signal(src, signal) + radio_connection.post_signal(computer, signal) /datum/computer_file/program/signaler/proc/set_frequency(new_frequency) - SSradio.remove_object(src, signal_frequency) + SSradio.remove_object(computer, signal_frequency) signal_frequency = new_frequency - radio_connection = SSradio.add_object(src, signal_frequency, RADIO_SIGNALER) + radio_connection = SSradio.add_object(computer, signal_frequency, RADIO_SIGNALER) return diff --git a/code/modules/modular_computers/file_system/programs/statusdisplay.dm b/code/modules/modular_computers/file_system/programs/statusdisplay.dm new file mode 100644 index 00000000000..30f7c297f18 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/statusdisplay.dm @@ -0,0 +1,55 @@ +/datum/computer_file/program/status + filename = "statusdisplay" + filedesc = "Status Display" + program_icon = "signal" + program_icon_state = "generic" + requires_ntnet = TRUE + size = 4 + + extended_desc = "An app used to change the message on the station status displays." + tgui_id = "NtosStatus" + + usage_flags = PROGRAM_ALL + available_on_ntnet = FALSE + + var/upper_text + var/lower_text + +/datum/computer_file/program/status/proc/SendSignal() + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) + + if(!frequency) + return + + var/datum/signal/status_signal = new(list("command" = "message")) + + status_signal.data["msg1"] = reject_bad_text(upper_text || "", MAX_STATUS_LINE_LENGTH) + status_signal.data["msg2"] = reject_bad_text(lower_text || "", MAX_STATUS_LINE_LENGTH) + + frequency.post_signal(computer, status_signal) + +/datum/computer_file/program/status/proc/SetText(position, text) + switch(position) + if("upper") + upper_text = text + if("lower") + lower_text = text + +/datum/computer_file/program/status/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + switch(action) + if("stat_send") + SendSignal() + if("stat_update") + SetText(params["position"], params["text"]) // i hate the player i hate the player + +/datum/computer_file/program/status/ui_data(mob/user) + var/list/data = get_header_data() + + data["upper"] = upper_text + data["lower"] = lower_text + + return data diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index f2cf4285b64..2e527435c8e 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -7,6 +7,8 @@ device_type = MC_CARD var/obj/item/card/id/stored_card + var/current_identification = null + var/current_job = null ///What happens when the ID card is removed (or deleted) from the module, through try_eject() or not. /obj/item/computer_hardware/card_slot/Exited(atom/movable/gone, direction) @@ -76,6 +78,10 @@ stored_card = I to_chat(user, span_notice("You insert \the [I] into \the [expansion_hw ? "secondary":"primary"] [src].")) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + holder.update_appearance() + + current_identification = stored_card.registered_name + current_job = stored_card.assignment var/holder_loc = holder.loc if(ishuman(holder_loc)) @@ -99,6 +105,11 @@ to_chat(user, span_notice("You remove the card from \the [src].")) playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + holder.update_appearance() + + stored_card = null + current_identification = null + current_job = null return TRUE diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index d499fca4443..2431b41f876 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -9,6 +9,7 @@ var/max_capacity = 128 var/used_capacity = 0 var/list/stored_files = list() // List of stored files on this drive. DO NOT MODIFY DIRECTLY! + var/default_installs = TRUE // install the default progs /obj/item/computer_hardware/hard_drive/on_remove(obj/item/modular_computer/remove_from, mob/user) remove_from.shutdown_computer() @@ -130,7 +131,9 @@ /obj/item/computer_hardware/hard_drive/Initialize(mapload) . = ..() - install_default_programs() + + if(default_installs) + install_default_programs() /obj/item/computer_hardware/hard_drive/advanced @@ -167,12 +170,25 @@ w_class = WEIGHT_CLASS_TINY custom_price = PAYCHECK_MEDIUM * 2 +/obj/item/computer_hardware/hard_drive/small/install_default_programs() + . = ..() + + store_file(new /datum/computer_file/program/messenger(src)) + store_file(new /datum/computer_file/program/notepad(src)) + // For borg integrated tablets. No downloader. /obj/item/computer_hardware/hard_drive/small/integrated/install_default_programs() + var/datum/computer_file/program/messenger/messenger = new(src) + messenger.is_silicon = TRUE + store_file(messenger) + +/obj/item/computer_hardware/hard_drive/small/integrated/borg/install_default_programs() store_file(new /datum/computer_file/program/computerconfig(src)) // Computer configuration utility, allows hardware control and displays more info than status bar store_file(new /datum/computer_file/program/filemanager(src)) // File manager, allows text editor functions and basic file manipulation. store_file(new /datum/computer_file/program/robotact(src)) - + var/datum/computer_file/program/messenger/messenger = new(src) + messenger.is_silicon = TRUE + store_file(messenger) // Syndicate variant - very slight better /obj/item/computer_hardware/hard_drive/small/syndicate diff --git a/code/modules/modular_computers/hardware/identifier.dm b/code/modules/modular_computers/hardware/identifier.dm new file mode 100644 index 00000000000..c64b62cdf4a --- /dev/null +++ b/code/modules/modular_computers/hardware/identifier.dm @@ -0,0 +1,13 @@ +/obj/item/computer_hardware/identifier + name = "identifier" + desc = "Used to automatically update the names of modular devices." + power_usage = 0 + w_class = WEIGHT_CLASS_TINY + device_type = MC_IDENTIFY + expansion_hw = FALSE + +/obj/item/computer_hardware/identifier/proc/UpdateDisplay() + var/name = holder.saved_identification + var/job = holder.saved_job + + holder.name = "[name] ([job])" diff --git a/code/modules/modular_computers/hardware/job_disk.dm b/code/modules/modular_computers/hardware/job_disk.dm new file mode 100644 index 00000000000..0593ea29ee0 --- /dev/null +++ b/code/modules/modular_computers/hardware/job_disk.dm @@ -0,0 +1,253 @@ +/obj/item/computer_hardware/hard_drive/role + name = "job data disk" + desc = "A disk meant to give a worker the needed programs to work." + power_usage = 0 + icon_state = "datadisk6" + w_class = WEIGHT_CLASS_TINY + critical = FALSE + max_capacity = 500 + device_type = MC_HDD_JOB + default_installs = FALSE + + var/disk_flags = 0 // bit flag for the programs + var/can_spam = FALSE + var/list/bot_access = list() + +/obj/item/computer_hardware/hard_drive/role/on_remove(obj/item/modular_computer/remove_from, mob/user) + return + +/obj/item/computer_hardware/hard_drive/role/Initialize(mapload) + . = ..() + var/list/progs_to_store = list() + + if(disk_flags & DISK_POWER) + progs_to_store += new /datum/computer_file/program/power_monitor(src) + progs_to_store += new /datum/computer_file/program/supermatter_monitor(src) + + if(disk_flags & DISK_ATMOS) + progs_to_store += new /datum/computer_file/program/atmosscan(src) + + if(disk_flags & DISK_MANIFEST) + progs_to_store += new /datum/computer_file/program/crew_manifest(src) + + if(disk_flags & DISK_SEC) + progs_to_store += new /datum/computer_file/program/records/security(src) + + if(disk_flags & DISK_JANI) + progs_to_store += new /datum/computer_file/program/radar/custodial_locator(src) + + if((disk_flags & DISK_CHEM) || (disk_flags & DISK_MED)) + var/datum/computer_file/program/phys_scanner/scanner = new(src) + + if(disk_flags & DISK_CHEM) + scanner.available_modes += DISK_CHEM + + if(disk_flags & DISK_MED) + progs_to_store += new /datum/computer_file/program/records/medical(src) + scanner.available_modes += DISK_MED + + progs_to_store += scanner + + if(disk_flags & DISK_ROBOS) + var/datum/computer_file/program/robocontrol/robo = new(src) + robo.cart_mode = TRUE + progs_to_store += robo + + if(disk_flags & DISK_CARGO) + progs_to_store += new /datum/computer_file/program/shipping(src) + + if(disk_flags & DISK_SIGNAL) + progs_to_store += new /datum/computer_file/program/signaler(src) + + if(disk_flags & DISK_NEWS) + progs_to_store += new /datum/computer_file/program/newscaster(src) + + if(disk_flags & DISK_BUDGET) + progs_to_store += new /datum/computer_file/program/budgetorders(src) + + if(disk_flags & DISK_STATUS) + progs_to_store += new /datum/computer_file/program/status(src) + + for (var/datum/computer_file/program/prog in progs_to_store) + prog.usage_flags = PROGRAM_ALL + prog.required_access = list() + prog.transfer_access = list() + store_file(prog) + + + +/obj/item/computer_hardware/hard_drive/role/proc/CanSpam() + return can_spam + +// Disk Definitions + +/obj/item/computer_hardware/hard_drive/role/engineering + name = "Power-ON disk" + desc = "Engineers ignoring station power-draw since 2400." + icon_state = "datadisk2" + disk_flags = DISK_POWER + +/obj/item/computer_hardware/hard_drive/role/atmos + name = "\improper BreatheDeep disk" + icon_state = "datadisk2" + disk_flags = DISK_ATMOS | DISK_ROBOS + bot_access = list( + FLOOR_BOT, + FIRE_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/medical + name = "\improper Med-U disk" + icon_state = "datadisk7" + disk_flags = DISK_MED | DISK_ROBOS + bot_access = list( + MED_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/chemistry + name = "\improper ChemWhiz disk" + icon_state = "datadisk7" + disk_flags = DISK_CHEM + +/obj/item/computer_hardware/hard_drive/role/security + name = "\improper R.O.B.U.S.T. disk" + icon_state = "datadisk9" + disk_flags = DISK_SEC | DISK_MANIFEST | DISK_ROBOS + bot_access = list( + SEC_BOT, + ADVANCED_SEC_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/detective + name = "\improper D.E.T.E.C.T. disk" + icon_state = "datadisk9" + disk_flags = DISK_MED | DISK_SEC | DISK_MANIFEST | DISK_ROBOS + bot_access = list( + SEC_BOT, + ADVANCED_SEC_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/janitor + name = "\improper CustodiPRO disk" + icon_state = "datadisk5" + desc = "The ultimate in clean-room design." + disk_flags = DISK_JANI | DISK_ROBOS + bot_access = list( + CLEAN_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/lawyer + name = "\improper P.R.O.V.E. disk" + icon_state = "datadisk9" + disk_flags = DISK_SEC + can_spam = TRUE + +/obj/item/computer_hardware/hard_drive/role/curator + name = "\improper Lib-Tweet disk" + icon_state = "datadisk2" + disk_flags = DISK_NEWS + +/obj/item/computer_hardware/hard_drive/role/roboticist + name = "\improper B.O.O.P. Remote Control disk" + icon_state = "datadisk5" + desc = "Packed with heavy duty quad-bot interlink!" + disk_flags = DISK_ROBOS + bot_access = list( + FLOOR_BOT, + CLEAN_BOT, + MED_BOT, + FIRE_BOT, + VIBE_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/signal + name = "generic signaler disk" + icon_state = "datadisk5" + desc = "A data disk with an integrated radio signaler module." + disk_flags = DISK_SIGNAL + +/obj/item/computer_hardware/hard_drive/role/signal/ordnance + name = "\improper Signal Ace 2 disk" + icon_state = "datadisk5" + desc = "Complete with integrated radio signaler!" + disk_flags = DISK_ATMOS | DISK_SIGNAL | DISK_CHEM + +/obj/item/computer_hardware/hard_drive/role/quartermaster + name = "space parts & space vendors disk" + icon_state = "datadisk0" + desc = "Perfect for the Quartermaster on the go!" + disk_flags = DISK_CARGO | DISK_ROBOS | DISK_BUDGET + bot_access = list( + MULE_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/head + name = "\improper Easy-Record DELUXE disk" + icon_state = "datadisk7" + disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_BUDGET + +/obj/item/computer_hardware/hard_drive/role/hop + name = "\improper HumanResources9001 disk" + icon_state = "datadisk7" + disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_JANI | DISK_SEC | DISK_NEWS | DISK_CARGO | DISK_ROBOS | DISK_BUDGET + bot_access = list( + MULE_BOT, + CLEAN_BOT, + VIBE_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/hos + name = "\improper R.O.B.U.S.T. DELUXE disk" + icon_state = "datadisk7" + disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_SEC | DISK_ROBOS | DISK_BUDGET + bot_access = list( + SEC_BOT, + ADVANCED_SEC_BOT, + ) + + +/obj/item/computer_hardware/hard_drive/role/ce + name = "\improper Power-On DELUXE disk" + icon_state = "datadisk7" + disk_flags = DISK_POWER | DISK_ATMOS | DISK_MANIFEST | DISK_STATUS | DISK_ROBOS | DISK_BUDGET + bot_access = list( + FLOOR_BOT, + FIRE_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/cmo + name = "\improper Med-U DELUXE disk" + icon_state = "datadisk7" + disk_flags = DISK_MANIFEST | DISK_STATUS | DISK_CHEM | DISK_ROBOS | DISK_BUDGET + bot_access = list( + MED_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/rd + name = "\improper Signal Ace DELUXE disk" + icon_state = "rndmajordisk" + disk_flags = DISK_ATMOS | DISK_MANIFEST | DISK_STATUS | DISK_CHEM | DISK_ROBOS | DISK_BUDGET | DISK_SIGNAL + bot_access = list( + FLOOR_BOT, + CLEAN_BOT, + MED_BOT, + FIRE_BOT, + VIBE_BOT, + ) + +/obj/item/computer_hardware/hard_drive/role/captain + name = "\improper Value-PAK disk" + icon_state = "datadisk8" + desc = "Now with 350% more value!" //Give the Captain...EVERYTHING! (Except Mime, Clown, and Syndie) + disk_flags = ~0 + can_spam = TRUE + bot_access = list( + SEC_BOT, + ADVANCED_SEC_BOT, + MULE_BOT, + FLOOR_BOT, + CLEAN_BOT, + MED_BOT, + FIRE_BOT, + VIBE_BOT, + ) diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index b0662785e95..f9a8e46a882 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -88,10 +88,12 @@ if(!modularInterface.borgo) return FALSE //No borg found - if(modularInterface.borgo.lockcharge) - return FALSE //lockdown restricts borg networking + var/mob/living/silicon/robot/robo = modularInterface.borgo + if(istype(robo)) + if(robo.lockcharge) + return FALSE //lockdown restricts borg networking - if(!modularInterface.borgo.cell || modularInterface.borgo.cell.charge == 0) - return FALSE //borg cell dying restricts borg networking + if(!robo.cell || robo.cell.charge == 0) + return FALSE //borg cell dying restricts borg networking return ..() diff --git a/code/modules/modular_computers/hardware/virus_disk.dm b/code/modules/modular_computers/hardware/virus_disk.dm new file mode 100644 index 00000000000..6a5c923b60d --- /dev/null +++ b/code/modules/modular_computers/hardware/virus_disk.dm @@ -0,0 +1,140 @@ +/obj/item/computer_hardware/hard_drive/role/virus + name = "\improper generic virus disk" + icon_state = "virusdisk" + var/charges = 5 + +/obj/item/computer_hardware/hard_drive/role/virus/proc/send_virus(obj/item/modular_computer/tablet/target, mob/living/user) + return + +/obj/item/computer_hardware/hard_drive/role/virus/clown + name = "\improper H.O.N.K. disk" + +/obj/item/computer_hardware/hard_drive/role/virus/clown/send_virus(obj/item/modular_computer/tablet/target, mob/living/user) + if(charges <= 0) + to_chat(user, span_notice("ERROR: Out of charges.")) + return + + if(target) + user.show_message(span_notice("Success!")) + charges-- + target.honkamnt = rand(15, 25) + else + to_chat(user, span_notice("ERROR: Could not find device.")) + +/obj/item/computer_hardware/hard_drive/role/virus/mime + name = "\improper sound of silence disk" + +/obj/item/computer_hardware/hard_drive/role/virus/mime/send_virus(obj/item/modular_computer/tablet/target, mob/living/user) + if(charges <= 0) + to_chat(user, span_notice("ERROR: Out of charges.")) + return + + if(target) + user.show_message(span_notice("Success!")) + charges-- + + var/obj/item/computer_hardware/hard_drive/drive = target.all_components[MC_HDD] + + for(var/datum/computer_file/program/messenger/app in drive.stored_files) + app.ringer_status = FALSE + app.ringtone = "" + else + to_chat(user, span_notice("ERROR: Could not find device.")) + +/obj/item/computer_hardware/hard_drive/role/virus/deto + name = "\improper D.E.T.O.M.A.T.I.X. disk" + charges = 6 + +/obj/item/computer_hardware/hard_drive/role/virus/deto/send_virus(obj/item/modular_computer/tablet/target, mob/living/user) + if(charges <= 0) + to_chat(user, span_notice("ERROR: Out of charges.")) + return + + var/difficulty = 0 + var/obj/item/computer_hardware/hard_drive/role/disk = target.all_components[MC_HDD_JOB] + + if(disk) + difficulty += bit_count(disk.disk_flags & (DISK_MED | DISK_SEC | DISK_POWER | DISK_MANIFEST)) + if(disk.disk_flags & DISK_MANIFEST) + difficulty++ //if cartridge has manifest access it has extra snowflake difficulty + if(SEND_SIGNAL(target, COMSIG_TABLET_CHECK_DETONATE) & COMPONENT_TABLET_NO_DETONATE || prob(difficulty * 15)) + user.show_message(span_danger("ERROR: Target could not be bombed."), MSG_VISUAL) + charges-- + return + + var/original_host = holder + var/fakename = sanitize_name(tgui_input_text(user, "Enter a name for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE) + if(!fakename || holder != original_host || !user.canUseTopic(holder, BE_CLOSE)) + return + var/fakejob = sanitize_name(tgui_input_text(user, "Enter a job for the rigged message.", "Forge Message", max_length = MAX_NAME_LEN), allow_numbers = TRUE) + if(!fakejob || holder != original_host || !user.canUseTopic(holder, BE_CLOSE)) + return + + var/obj/item/computer_hardware/hard_drive/drive = holder.all_components[MC_HDD] + + for(var/datum/computer_file/program/messenger/app in drive.stored_files) + if(charges > 0 && app.send_message(user, list(target), rigged = REF(user), fake_name = fakename, fake_job = fakejob)) + charges-- + user.show_message(span_notice("Success!")) + var/reference = REF(src) + ADD_TRAIT(target, TRAIT_PDA_CAN_EXPLODE, reference) + ADD_TRAIT(target, TRAIT_PDA_MESSAGE_MENU_RIGGED, reference) + addtimer(TRAIT_CALLBACK_REMOVE(target, TRAIT_PDA_MESSAGE_MENU_RIGGED, reference), 10 SECONDS) + +/obj/item/computer_hardware/hard_drive/role/virus/frame + name = "\improper F.R.A.M.E. disk" + + var/telecrystals = 0 + var/current_progression = 0 + +/obj/item/computer_hardware/hard_drive/role/virus/frame/send_virus(obj/item/modular_computer/tablet/target, mob/living/user) + if(charges <= 0) + to_chat(user, span_notice("ERROR: Out of charges.")) + return + + if(target) + charges-- + var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" + to_chat(user, span_notice("Success! The unlock code to the target is: [lock_code]")) + var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink) + if(!hidden_uplink) + var/datum/mind/target_mind + var/list/backup_players = list() + for(var/datum/mind/player as anything in get_crewmember_minds()) + if(player.assigned_role?.title == target.saved_job) + backup_players += player + if(player.name == target.saved_identification) + target_mind = player + break + if(!target_mind) + if(!length(backup_players)) + target_mind = user.mind + else + target_mind = pick(backup_players) + hidden_uplink = target.AddComponent(/datum/component/uplink, target_mind, enabled = TRUE, starting_tc = telecrystals, has_progression = TRUE) + hidden_uplink.uplink_handler.has_objectives = TRUE + hidden_uplink.uplink_handler.owner = target_mind + hidden_uplink.uplink_handler.can_take_objectives = FALSE + hidden_uplink.uplink_handler.progression_points = min(SStraitor.current_global_progression, current_progression) + hidden_uplink.uplink_handler.generate_objectives() + SStraitor.register_uplink_handler(hidden_uplink.uplink_handler) + else + hidden_uplink.add_telecrystals(telecrystals) + telecrystals = 0 + hidden_uplink.locked = FALSE + hidden_uplink.active = TRUE + else + to_chat(user, span_notice("ERROR: Could not find device.")) + +/obj/item/computer_hardware/hard_drive/role/virus/frame/attackby(obj/item/I, mob/user, params) + . = ..() + if(istype(I, /obj/item/stack/telecrystal)) + if(!charges) + to_chat(user, span_notice("[src] is out of charges, it's refusing to accept [I].")) + return + var/obj/item/stack/telecrystal/telecrystalStack = I + telecrystals += telecrystalStack.amount + to_chat(user, span_notice("You slot [telecrystalStack] into [src]. The next time it's used, it will also give telecrystals.")) + telecrystalStack.use(telecrystalStack.amount) + + diff --git a/code/modules/tgui/states/reverse_contained.dm b/code/modules/tgui/states/reverse_contained.dm new file mode 100644 index 00000000000..a6d1034a789 --- /dev/null +++ b/code/modules/tgui/states/reverse_contained.dm @@ -0,0 +1,18 @@ +/*! + * Not copyrighted, but magatsuchi made it. + * + */ + +/** + * tgui state: reverse_contained_state + * + * + * Checks if src_object is inside of user. + */ + +GLOBAL_DATUM_INIT(reverse_contained_state, /datum/ui_state/reverse_contained_state, new) + +/datum/ui_state/reverse_contained_state/can_use_topic(atom/src_object, mob/user) + if(!user.contains(src_object)) + return UI_CLOSE + return user.shared_ui_interaction(src_object) diff --git a/code/modules/uplink/uplink_items/device_tools.dm b/code/modules/uplink/uplink_items/device_tools.dm index a6177b89f81..39b05e29945 100644 --- a/code/modules/uplink/uplink_items/device_tools.dm +++ b/code/modules/uplink/uplink_items/device_tools.dm @@ -99,18 +99,18 @@ illegal_tech = FALSE /datum/uplink_item/device_tools/frame - name = "F.R.A.M.E. PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ - when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ + name = "F.R.A.M.E. disk" + desc = "When inserted into a tablet, this cartridge gives you five messenger viruses which \ + when used cause the targeted tablet to become a new uplink with zero TCs, and immediately become unlocked. \ You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ telecrystals normally." - item = /obj/item/cartridge/virus/frame + item = /obj/item/computer_hardware/hard_drive/role/virus/frame cost = 4 restricted = TRUE /datum/uplink_item/device_tools/frame/spawn_item(spawn_path, mob/user, datum/uplink_handler/uplink_handler, atom/movable/source) . = ..() - var/obj/item/cartridge/virus/frame/target = . + var/obj/item/computer_hardware/hard_drive/role/virus/frame/target = . if(!target) return target.current_progression = uplink_handler.progression_points diff --git a/code/modules/uplink/uplink_items/explosive.dm b/code/modules/uplink/uplink_items/explosive.dm index 1a44ba94d5b..6eed450dce0 100644 --- a/code/modules/uplink/uplink_items/explosive.dm +++ b/code/modules/uplink/uplink_items/explosive.dm @@ -45,12 +45,12 @@ cant_discount = TRUE /datum/uplink_item/explosives/detomatix - name = "Detomatix PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ - detonate PDAs of crewmembers who have their message feature enabled. \ + name = "Detomatix disk" + desc = "When inserted into a tablet, this cartridge gives you four opportunities to \ + detonate tablets of crewmembers who have their message feature enabled. \ The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer." progression_minimum = 30 MINUTES - item = /obj/item/cartridge/virus/syndicate + item = /obj/item/computer_hardware/hard_drive/role/virus/deto cost = 6 restricted = TRUE diff --git a/code/modules/vending/assist.dm b/code/modules/vending/assist.dm index 38ea84ee7db..018577e5837 100644 --- a/code/modules/vending/assist.dm +++ b/code/modules/vending/assist.dm @@ -9,7 +9,7 @@ /obj/item/assembly/igniter = 3, /obj/item/assembly/signaler = 4, /obj/item/wirecutters = 1, - /obj/item/cartridge/signal = 4, + /obj/item/computer_hardware/hard_drive/role/signal = 4, /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 3, /obj/item/stock_parts/micro_laser = 3, diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index 0780210f680..701bfd5eaaf 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -7,13 +7,14 @@ icon_deny = "cart-deny" panel_type = "panel6" products = list( - /obj/item/cartridge/medical = 10, - /obj/item/cartridge/engineering = 10, - /obj/item/cartridge/security = 10, - /obj/item/cartridge/signal/ordnance = 10, - /obj/item/pda/heads = 10, - /obj/item/cartridge/captain = 3, - /obj/item/cartridge/quartermaster = 10 + /obj/item/computer_hardware/hard_drive/role/medical = 10, + /obj/item/computer_hardware/hard_drive/role/engineering = 10, + /obj/item/computer_hardware/hard_drive/role/security = 10, + /obj/item/computer_hardware/hard_drive/role/janitor = 10, + /obj/item/computer_hardware/hard_drive/role/signal/ordnance = 10, + /obj/item/modular_computer/tablet/pda/heads = 10, + /obj/item/computer_hardware/hard_drive/role/captain = 3, + /obj/item/computer_hardware/hard_drive/role/quartermaster = 10 ) refill_canister = /obj/item/vending_refill/cart default_price = PAYCHECK_COMMAND diff --git a/icons/obj/modular_tablet.dmi b/icons/obj/modular_tablet.dmi index 60d47a72402..14a1005c075 100644 Binary files a/icons/obj/modular_tablet.dmi and b/icons/obj/modular_tablet.dmi differ diff --git a/icons/obj/module.dmi b/icons/obj/module.dmi index d70a56695ef..a9096a91b3b 100644 Binary files a/icons/obj/module.dmi and b/icons/obj/module.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 5ca43535bdf..6c1c288d5c1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1534,11 +1534,6 @@ #include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\traitordevices.dm" #include "code\game\objects\items\devices\transfer_valve.dm" -#include "code\game\objects\items\devices\PDA\cart.dm" -#include "code\game\objects\items\devices\PDA\PDA.dm" -#include "code\game\objects\items\devices\PDA\PDA_types.dm" -#include "code\game\objects\items\devices\PDA\radio.dm" -#include "code\game\objects\items\devices\PDA\virus_cart.dm" #include "code\game\objects\items\devices\radio\electropack.dm" #include "code\game\objects\items\devices\radio\encryptionkey.dm" #include "code\game\objects\items\devices\radio\headset.dm" @@ -2464,7 +2459,6 @@ #include "code\modules\client\preferences\names.dm" #include "code\modules\client\preferences\ooc.dm" #include "code\modules\client\preferences\parallax.dm" -#include "code\modules\client\preferences\pda.dm" #include "code\modules\client\preferences\persistent_scars.dm" #include "code\modules\client\preferences\phobia.dm" #include "code\modules\client\preferences\pixel_size.dm" @@ -3530,6 +3524,7 @@ #include "code\modules\modular_computers\computers\item\laptop.dm" #include "code\modules\modular_computers\computers\item\laptop_presets.dm" #include "code\modules\modular_computers\computers\item\processor.dm" +#include "code\modules\modular_computers\computers\item\role_tablet_presets.dm" #include "code\modules\modular_computers\computers\item\tablet.dm" #include "code\modules\modular_computers\computers\item\tablet_presets.dm" #include "code\modules\modular_computers\computers\machinery\console_presets.dm" @@ -3553,18 +3548,23 @@ #include "code\modules\modular_computers\file_system\programs\file_browser.dm" #include "code\modules\modular_computers\file_system\programs\jobmanagement.dm" #include "code\modules\modular_computers\file_system\programs\newscasterapp.dm" +#include "code\modules\modular_computers\file_system\programs\notepad.dm" #include "code\modules\modular_computers\file_system\programs\ntdownloader.dm" +#include "code\modules\modular_computers\file_system\programs\ntmessenger.dm" #include "code\modules\modular_computers\file_system\programs\ntmonitor.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm" +#include "code\modules\modular_computers\file_system\programs\phys_scanner.dm" #include "code\modules\modular_computers\file_system\programs\portrait_printer.dm" #include "code\modules\modular_computers\file_system\programs\powermonitor.dm" #include "code\modules\modular_computers\file_system\programs\radar.dm" +#include "code\modules\modular_computers\file_system\programs\records.dm" #include "code\modules\modular_computers\file_system\programs\robocontrol.dm" #include "code\modules\modular_computers\file_system\programs\robotact.dm" #include "code\modules\modular_computers\file_system\programs\secureye.dm" #include "code\modules\modular_computers\file_system\programs\signaler.dm" #include "code\modules\modular_computers\file_system\programs\skill_tracker.dm" #include "code\modules\modular_computers\file_system\programs\sm_monitor.dm" +#include "code\modules\modular_computers\file_system\programs\statusdisplay.dm" #include "code\modules\modular_computers\file_system\programs\techweb.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\dos.dm" #include "code\modules\modular_computers\file_system\programs\antagonist\revelation.dm" @@ -3574,11 +3574,14 @@ #include "code\modules\modular_computers\hardware\card_slot.dm" #include "code\modules\modular_computers\hardware\CPU.dm" #include "code\modules\modular_computers\hardware\hard_drive.dm" +#include "code\modules\modular_computers\hardware\identifier.dm" +#include "code\modules\modular_computers\hardware\job_disk.dm" #include "code\modules\modular_computers\hardware\network_card.dm" #include "code\modules\modular_computers\hardware\portable_disk.dm" #include "code\modules\modular_computers\hardware\printer.dm" #include "code\modules\modular_computers\hardware\recharger.dm" #include "code\modules\modular_computers\hardware\sensor_package.dm" +#include "code\modules\modular_computers\hardware\virus_disk.dm" #include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm" #include "code\modules\movespeed\_movespeed_modifier.dm" #include "code\modules\movespeed\modifiers\components.dm" @@ -4166,6 +4169,7 @@ #include "code\modules\tgui\states\observer.dm" #include "code\modules\tgui\states\paicard.dm" #include "code\modules\tgui\states\physical.dm" +#include "code\modules\tgui\states\reverse_contained.dm" #include "code\modules\tgui\states\self.dm" #include "code\modules\tgui\states\zlevel.dm" #include "code\modules\tgui_panel\audio.dm" diff --git a/tgui/packages/tgui/interfaces/NtosMain.js b/tgui/packages/tgui/interfaces/NtosMain.js index 95e2676cd00..8374dd6ee4f 100644 --- a/tgui/packages/tgui/interfaces/NtosMain.js +++ b/tgui/packages/tgui/interfaces/NtosMain.js @@ -6,6 +6,7 @@ export const NtosMain = (props, context) => { const { act, data } = useBackend(context); const { device_theme, + show_imprint, programs = [], has_light, light_on, @@ -13,6 +14,11 @@ export const NtosMain = (props, context) => { removable_media = [], cardholder, login = [], + proposed_login = [], + disk, + disk_name, + disk_programs = [], + pai, } = data; return ( { )} - {!!cardholder && ( + {!!(cardholder && show_imprint) && (
    act('PC_Eject_Disk', { name: "ID" })} - /> + <> +
    @@ -80,6 +97,38 @@ export const NtosMain = (props, context) => { )} + {!!pai && ( +
    + + + +
    +
    + )}
    {programs.map(program => ( @@ -92,6 +141,7 @@ export const NtosMain = (props, context) => { content={program.desc} onClick={() => act('PC_runprogram', { name: program.name, + is_disk: false, })} /> @@ -110,6 +160,50 @@ export const NtosMain = (props, context) => { ))}
    + {!!disk && ( +
    act('PC_Eject_Disk', { name: "job disk" })} /> + )}> + + {disk_programs.map(program => ( + + +
    +
    + )}
    ); diff --git a/tgui/packages/tgui/interfaces/NtosMessenger.js b/tgui/packages/tgui/interfaces/NtosMessenger.js new file mode 100644 index 00000000000..ddc20055861 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosMessenger.js @@ -0,0 +1,220 @@ +import { useBackend } from '../backend'; +import { Box, Button, Dimmer, Icon, Section, Stack } from '../components'; +import { NtosWindow } from '../layouts'; + +const NoIDDimmer = (props, context) => { + const { act, data } = useBackend(context); + const { owner } = data; + return ( + + + + + + + + + + + + + Please imprint an ID to continue. + + + + + + ); +}; + +export const NtosMessenger = (props, context) => { + const { act, data } = useBackend(context); + const { + owner, + messages = [], + ringer_status, + sending_and_receiving, + messengers = [], + viewing_messages, + sortByJob, + canSpam, + isSilicon, + photo, + virus_attach, + sending_virus, + } = data; + if (viewing_messages) { + return ( + + + +
    +
    + {messages.map(message => ( + +
    + + {message.outgoing ? ( + "(OUTGOING)" + ) : ( + "(INCOMING)" + )} + + {message.outgoing ? ( + + {message.name + " (" + message.job + ")"} + + ) : ( +
    +
    + + {message.contents} + + {!!message.photo && ( + + )} +
    +
    + ))} +
    +
    +
    + ); + } + return ( + + + +
    + + + SpaceMessenger V6.4.7 + + + Bringing you spy-proof communications since 2467. + +
    +
    + +
    + +
    +
    + {!!photo && ( + +
    + + Current Photo +
    +
    + +
    +
    + )} + +
    + + Detected Messengers +
    +
    + +
    + + {messengers.map(messenger => ( + + ))} + + {!!canSpam && ( +
    +
    + {(!owner && !isSilicon) && ( + + )} +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosNotepad.js b/tgui/packages/tgui/interfaces/NtosNotepad.js new file mode 100644 index 00000000000..ad8e40c0a09 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosNotepad.js @@ -0,0 +1,36 @@ +import { NtosWindow } from '../layouts'; +import { useBackend } from '../backend'; +import { Stack, Input, Section } from '../components'; + +export const NtosNotepad = (props, context) => { + const { act, data } = useBackend(context); + const { + note, + } = data; + return ( + + + + + +
    + {note} +
    +
    +
    + +
    + act('UpdateNote', { + newnote: value, + })} + /> +
    +
    +
    +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosPhysScanner.js b/tgui/packages/tgui/interfaces/NtosPhysScanner.js new file mode 100644 index 00000000000..3384d4dce9b --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosPhysScanner.js @@ -0,0 +1,48 @@ +import { useBackend } from '../backend'; +import { NtosWindow } from '../layouts'; +import { Section, Box, Dropdown } from '../components'; +import { sanitizeText } from '../sanitize'; + +export const NtosPhysScanner = (props, context) => { + const { act, data } = useBackend(context); + const { + set_mode, + last_record, + available_modes = [], + } = data; + const textHtml = { + __html: sanitizeText(last_record), + }; + return ( + + +
    + Tap something (right-click) with your tablet + to use the physical scanner. +
    +
    + SELECTED MODE

    + act('selectMode', { + newMode: value, + })} + /> +
    +
    + + LAST SAVED RESULT +
    +
    +
    + +
    +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosRecords.js b/tgui/packages/tgui/interfaces/NtosRecords.js new file mode 100644 index 00000000000..09f1e36e5e1 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosRecords.js @@ -0,0 +1,86 @@ +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Icon, Input, Section } from '../components'; +import { NtosWindow } from '../layouts'; + +export const NtosRecords = (props, context) => { + const { act, data } = useBackend(context); + const [searchTerm, setSearchTerm] = useLocalState(context, "search", ""); + const { + mode, + records, + } = data; + + const isMatchingSearchTerms = createSearch(searchTerm); + + return ( + + +
    + NANOTRASEN PERSONNEL RECORDS (CLASSIFIED) +
    +
    + setSearchTerm(value)} + /> +
    + {mode === "security" && records.map(record => ( + + ))} + {mode === "medical" && records.map(record => ( + + ))} +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosRoboControl.js b/tgui/packages/tgui/interfaces/NtosRoboControl.js index ba4c3b836f7..8ea590978ca 100644 --- a/tgui/packages/tgui/interfaces/NtosRoboControl.js +++ b/tgui/packages/tgui/interfaces/NtosRoboControl.js @@ -24,15 +24,11 @@ export const NtosRoboControl = (props, context) => {
    - + {id_owner} - {!!has_id && ( -
    diff --git a/tgui/packages/tgui/interfaces/NtosStatus.js b/tgui/packages/tgui/interfaces/NtosStatus.js new file mode 100644 index 00000000000..64ad2e81e30 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosStatus.js @@ -0,0 +1,45 @@ +import { useBackend } from '../backend'; +import { NtosWindow } from '../layouts'; +import { Input, Section, Button } from '../components'; + +export const NtosStatus = (props, context) => { + const { act, data } = useBackend(context); + const { + upper, + lower, + } = data; + + return ( + + +
    + act('stat_update', { + position: "upper", + text: value, + })} + /> +
    + act('stat_update', { + position: "lower", + text: value, + })} + /> +
    +
    +
    +
    + ); +}; diff --git a/tools/UpdatePaths/pdas_to_tabs.txt b/tools/UpdatePaths/pdas_to_tabs.txt new file mode 100644 index 00000000000..1248b8fbcc9 --- /dev/null +++ b/tools/UpdatePaths/pdas_to_tabs.txt @@ -0,0 +1,56 @@ +#comment This replaces PDA and cart paths with the new modular tablet role paths. + +/obj/item/cartridge : /obj/item/computer_hardware/hard_drive/role +/obj/item/cartridge/engineering : /obj/item/computer_hardware/hard_drive/role/engineering +/obj/item/cartridge/atmos : /obj/item/computer_hardware/hard_drive/role/atmos +/obj/item/cartridge/medical : /obj/item/computer_hardware/hard_drive/role/medical +/obj/item/cartridge/chemistry : /obj/item/computer_hardware/hard_drive/role/chemistry +/obj/item/cartridge/security : /obj/item/computer_hardware/hard_drive/role/security +/obj/item/cartridge/detective : /obj/item/computer_hardware/hard_drive/role/detective +/obj/item/cartridge/lawyer : /obj/item/computer_hardware/hard_drive/role/lawyer +/obj/item/cartridge/curator : /obj/item/computer_hardware/hard_drive/role/curator +/obj/item/cartridge/roboticist : /obj/item/computer_hardware/hard_drive/role/roboticist +/obj/item/cartridge/signal : /obj/item/computer_hardware/hard_drive/role/signal +/obj/item/cartridge/signal/ordnance : /obj/item/computer_hardware/hard_drive/role/signal/ordnance +/obj/item/cartridge/quartermaster : /obj/item/computer_hardware/hard_drive/role/quartermaster +/obj/item/cartridge/head : /obj/item/computer_hardware/hard_drive/role/head +/obj/item/cartridge/hop : /obj/item/computer_hardware/hard_drive/role/hop +/obj/item/cartridge/hos : /obj/item/computer_hardware/hard_drive/role/hos +/obj/item/cartridge/ce : /obj/item/computer_hardware/hard_drive/role/ce +/obj/item/cartridge/cmo : /obj/item/computer_hardware/hard_drive/role/cmo +/obj/item/cartridge/rd : /obj/item/computer_hardware/hard_drive/role/rd +/obj/item/cartridge/captain : /obj/item/computer_hardware/hard_drive/role/captain + +/obj/item/pda : /obj/item/modular_computer/tablet/pda +/obj/item/pda/medical : /obj/item/modular_computer/tablet/pda/medical +/obj/item/pda/viro : /obj/item/modular_computer/tablet/pda/viro +/obj/item/pda/engineering : /obj/item/modular_computer/tablet/pda/engineering +/obj/item/pda/security : /obj/item/modular_computer/tablet/pda/security +/obj/item/pda/detective : /obj/item/modular_computer/tablet/pda/detective +/obj/item/pda/warden : /obj/item/modular_computer/tablet/pda/warden +/obj/item/pda/janitor : /obj/item/modular_computer/tablet/pda/janitor +/obj/item/pda/science : /obj/item/modular_computer/tablet/pda/science +/obj/item/pda/heads : /obj/item/modular_computer/tablet/pda/heads +/obj/item/pda/hop : /obj/item/modular_computer/tablet/pda/hop +/obj/item/pda/hos : /obj/item/modular_computer/tablet/pda/hos +/obj/item/pda/ce : /obj/item/modular_computer/tablet/pda/ce +/obj/item/pda/cmo : /obj/item/modular_computer/tablet/pda/cmo +/obj/item/pda/rd : /obj/item/modular_computer/tablet/pda/rd +/obj/item/pda/captain : /obj/item/modular_computer/tablet/pda/captain +/obj/item/pda/cargo : /obj/item/modular_computer/tablet/pda/cargo +/obj/item/pda/quartermaster : /obj/item/modular_computer/tablet/pda/quartermaster +/obj/item/pda/shaftminer : /obj/item/modular_computer/tablet/pda/shaftminer +/obj/item/pda/chaplain : /obj/item/modular_computer/tablet/pda/chaplain +/obj/item/pda/lawyer : /obj/item/modular_computer/tablet/pda/lawyer +/obj/item/pda/botanist : /obj/item/modular_computer/tablet/pda/botanist +/obj/item/pda/roboticist : /obj/item/modular_computer/tablet/pda/roboticist +/obj/item/pda/cook : /obj/item/modular_computer/tablet/pda/cook +/obj/item/pda/bar : /obj/item/modular_computer/tablet/pda/bar +/obj/item/pda/atmos : /obj/item/modular_computer/tablet/pda/atmos +/obj/item/pda/chemist : /obj/item/modular_computer/tablet/pda/chemist +/obj/item/pda/geneticist : /obj/item/modular_computer/tablet/pda/geneticist +/obj/item/pda/clown : /obj/item/modular_computer/tablet/pda/clown +/obj/item/pda/mime : /obj/item/modular_computer/tablet/pda/mime +/obj/item/pda/curator : /obj/item/modular_computer/tablet/pda/curator +/obj/item/pda/syndicate : /obj/item/modular_computer/tablet/pda/syndicate +/obj/item/pda/clear : /obj/item/modular_computer/tablet/pda/clear