diff --git a/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm b/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm index 057b0cbdbe8f..fafbd48050f4 100644 --- a/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm +++ b/_maps/RandomRuins/JungleRuins/jungle_interceptor.dmm @@ -3395,7 +3395,7 @@ /turf/open/floor/plating/rust, /area/ruin/jungle/interceptor/starlauncherone) "CU" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/records/sec, /obj/structure/cable/orange{ icon_state = "2-8" }, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_abandonedlisteningpost.dmm b/_maps/RandomRuins/LavaRuins/lavaland_abandonedlisteningpost.dmm index 444f4ec52509..fb7822c1a57f 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_abandonedlisteningpost.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_abandonedlisteningpost.dmm @@ -1029,7 +1029,7 @@ /area/ruin/unpowered/listening_post/commons) "rb" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop, +/obj/machinery/computer/records/sec/laptop, /obj/effect/turf_decal/siding/thinplating/dark{ dir = 4 }, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm index 2c84843cf776..0959a665bf13 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_wrecked_factory.dmm @@ -2920,7 +2920,7 @@ /area/overmap_encounter/planetoid/lava/explored) "By" = ( /obj/structure/table/wood, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4; pixel_x = -5; pixel_y = 5 @@ -4953,7 +4953,7 @@ /turf/open/floor/plating/grass/lava/orange, /area/overmap_encounter/planetoid/lava/explored) "Xp" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/records/sec, /turf/open/floor/carpet/nanoweave/red, /area/ruin/lavaland/factory/adminstrative) "Xv" = ( diff --git a/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm b/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm index b837eff979f7..6a5960bde27b 100644 --- a/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm +++ b/_maps/RandomRuins/RockRuins/rockplanet_budgetcuts.dmm @@ -64,7 +64,7 @@ /area/overmap_encounter/planetoid/rockplanet/explored) "bc" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 4; pixel_x = -7; pixel_y = 6 @@ -1329,7 +1329,7 @@ /obj/machinery/status_display/evac{ pixel_y = 32 }, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ pixel_x = 5; pixel_y = 4 }, @@ -2395,11 +2395,11 @@ /area/ruin/rockplanet/nanotrasen) "Po" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ pixel_x = -5; pixel_y = 3 }, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ pixel_x = 16; pixel_y = 3 }, diff --git a/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm b/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm index a86efe2e9744..284ffa7f47ac 100644 --- a/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm +++ b/_maps/RandomRuins/RockRuins/rockplanet_harmfactory.dmm @@ -111,7 +111,7 @@ /area/ruin/powered) "cy" = ( /obj/structure/table/wood/reinforced, -/obj/machinery/computer/secure_data/laptop, +/obj/machinery/computer/records/sec/laptop, /turf/open/floor/plating/rust, /area/ruin/powered) "cQ" = ( @@ -121,7 +121,7 @@ /area/ruin/powered) "dr" = ( /obj/structure/table/wood/reinforced, -/obj/machinery/computer/med_data/laptop, +/obj/machinery/computer/records/med/laptop, /obj/effect/decal/cleanable/dirt/dust, /obj/item/newspaper{ pixel_x = 8; @@ -271,7 +271,7 @@ /turf/open/floor/plating/rust, /area/ruin/powered) "gx" = ( -/obj/structure/filingcabinet/employment, +/obj/structure/filingcabinet/record/gen, /obj/structure/safe/floor, /obj/item/keycard/harmfactory/office, /turf/open/floor/plating/rust, diff --git a/_maps/RandomRuins/RockRuins/rockplanet_nomadcrash.dmm b/_maps/RandomRuins/RockRuins/rockplanet_nomadcrash.dmm index ff58248ffc4e..4d75b0dd1ec5 100644 --- a/_maps/RandomRuins/RockRuins/rockplanet_nomadcrash.dmm +++ b/_maps/RandomRuins/RockRuins/rockplanet_nomadcrash.dmm @@ -1495,7 +1495,7 @@ dir = 4 }, /obj/structure/table, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_x = 2; pixel_y = 6 diff --git a/_maps/RandomRuins/RockRuins/rockplanet_shippingdock.dmm b/_maps/RandomRuins/RockRuins/rockplanet_shippingdock.dmm index 342b1422b80f..663fc8752c65 100644 --- a/_maps/RandomRuins/RockRuins/rockplanet_shippingdock.dmm +++ b/_maps/RandomRuins/RockRuins/rockplanet_shippingdock.dmm @@ -896,7 +896,7 @@ /area/ruin/rockplanet/shippingdocksecure) "il" = ( /obj/structure/table, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_x = 1 }, diff --git a/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm b/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm index 3d05cfb13d35..15e9c3c21bc0 100644 --- a/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm +++ b/_maps/RandomRuins/SpaceRuins/power_puzzle.dmm @@ -3178,7 +3178,7 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt/dust, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 1; pixel_y = 5 }, diff --git a/_maps/RandomRuins/SpaceRuins/spacemall.dmm b/_maps/RandomRuins/SpaceRuins/spacemall.dmm index eb48bcae1626..c96d92cc893c 100644 --- a/_maps/RandomRuins/SpaceRuins/spacemall.dmm +++ b/_maps/RandomRuins/SpaceRuins/spacemall.dmm @@ -1360,7 +1360,7 @@ /turf/open/floor/plasteel, /area/ruin/space/has_grav/spacemall) "fa" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 1 }, /obj/effect/turf_decal/corner/opaque/red/mono, @@ -8454,7 +8454,7 @@ /turf/open/floor/wood, /area/ruin/space/has_grav/spacemall/maint) "FC" = ( -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 1 }, /obj/structure/table/reinforced, diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 13e075e9884d..46390bd00b3c 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -3781,7 +3781,7 @@ /turf/open/floor/mineral/titanium/blue, /area/centcom/evac) "aLj" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 4 }, /turf/open/floor/mineral/plastitanium/red, @@ -6479,7 +6479,7 @@ /turf/open/floor/plasteel, /area/centcom/control) "bIA" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/records/sec, /obj/effect/turf_decal/industrial/warning, /turf/open/floor/plasteel, /area/centcom/control) @@ -7010,7 +7010,7 @@ /turf/open/floor/plasteel, /area/centcom/control) "cRF" = ( -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 4 }, /obj/effect/turf_decal/corner/transparent/neutral{ @@ -7040,7 +7040,7 @@ /obj/structure/sign/poster/contraband/syndicate_recruitment{ pixel_x = -32 }, -/obj/machinery/computer/secure_data/syndie{ +/obj/machinery/computer/records/sec/syndie{ dir = 4 }, /turf/open/floor/mineral/plastitanium, @@ -7217,7 +7217,7 @@ /turf/open/floor/plasteel, /area/tdome/tdomeobserve) "dsk" = ( -/obj/structure/filingcabinet/security, +/obj/structure/filingcabinet/record/security, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, @@ -7341,7 +7341,7 @@ /turf/open/floor/plasteel, /area/centcom) "dGq" = ( -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 8 }, /obj/effect/turf_decal/corner/opaque/blue{ @@ -8170,7 +8170,7 @@ /turf/open/floor/plasteel/dark, /area/centcom/ferry) "fdr" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, @@ -8901,7 +8901,7 @@ /turf/open/floor/plasteel, /area/centcom/supply) "gLL" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 8 }, /obj/machinery/button/door/indestructible{ @@ -9779,7 +9779,7 @@ /turf/open/floor/mineral/plastitanium, /area/centcom) "izl" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 1 }, /obj/machinery/light/directional/south, @@ -9972,7 +9972,7 @@ /obj/machinery/newscaster/directional/north{ pixel_y = -30 }, -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 1 }, /obj/effect/turf_decal/corner/transparent/neutral{ @@ -10065,7 +10065,7 @@ /turf/open/floor/plasteel, /area/centcom/supplypod/loading/ert) "jly" = ( -/obj/machinery/computer/med_data/syndie{ +/obj/machinery/computer/records/med/syndie{ dir = 1 }, /turf/open/floor/mineral/plastitanium/red, @@ -10172,7 +10172,7 @@ /turf/open/floor/plasteel/dark, /area/tdome/tdomeobserve) "jvG" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 1 }, /obj/effect/turf_decal/industrial/warning{ @@ -10958,7 +10958,7 @@ /turf/open/floor/plasteel, /area/centcom/control) "lhE" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 4 }, /obj/effect/turf_decal/corner/transparent/neutral{ @@ -11612,7 +11612,7 @@ /area/ctf) "moE" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4; pixel_y = 6; pixel_x = -4 @@ -12436,7 +12436,7 @@ /obj/effect/turf_decal/corner/opaque/brown{ dir = 8 }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/records/sec, /obj/machinery/light/directional/north, /turf/open/floor/plasteel, /area/centcom) @@ -12663,7 +12663,7 @@ /area/centcom/ferry) "owZ" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/med_data/laptop, +/obj/machinery/computer/records/med/laptop, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, @@ -13681,7 +13681,7 @@ /turf/open/floor/plasteel, /area/centcom/supply) "qxD" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/machinery/light/directional/north, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 @@ -14574,7 +14574,7 @@ /turf/open/floor/plasteel/dark, /area/tdome/tdomeobserve) "sho" = ( -/obj/structure/filingcabinet/security, +/obj/structure/filingcabinet/record/security, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, @@ -15156,7 +15156,7 @@ /turf/open/floor/plasteel/dark, /area/ctf) "tyD" = ( -/obj/structure/filingcabinet/security, +/obj/structure/filingcabinet/record/security, /obj/effect/turf_decal/industrial/warning{ dir = 9 }, @@ -15195,7 +15195,7 @@ /turf/open/floor/plasteel/patterned/grid, /area/centcom) "tAB" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, @@ -16008,7 +16008,7 @@ /turf/open/floor/plasteel/dark, /area/ctf) "vyk" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 1 }, /obj/effect/turf_decal/corner/transparent/neutral{ @@ -16033,7 +16033,7 @@ /turf/open/floor/plasteel, /area/centcom/control) "vAM" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 8 }, /obj/effect/turf_decal/corner/transparent/neutral{ @@ -16438,7 +16438,7 @@ /turf/open/floor/plasteel, /area/centcom/control) "wER" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, @@ -16724,7 +16724,7 @@ /turf/open/floor/plasteel, /area/centcom/evac) "xEN" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/effect/turf_decal/industrial/warning{ dir = 5 }, @@ -16802,7 +16802,7 @@ /area/centcom/supply) "xSR" = ( /obj/structure/table/wood, -/obj/machinery/computer/med_data/laptop, +/obj/machinery/computer/records/med/laptop, /obj/effect/turf_decal/corner/transparent/neutral{ dir = 1 }, diff --git a/_maps/outpost/hangar/nt_ice_40x40.dmm b/_maps/outpost/hangar/nt_ice_40x40.dmm index 69d81767fd7f..13a233acfcb7 100644 --- a/_maps/outpost/hangar/nt_ice_40x40.dmm +++ b/_maps/outpost/hangar/nt_ice_40x40.dmm @@ -1555,7 +1555,7 @@ }, /area/hangar) "Ps" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ icon_state = "computer-left"; dir = 4; pixel_x = -7 diff --git a/_maps/outpost/hangar/nt_ice_56x40.dmm b/_maps/outpost/hangar/nt_ice_56x40.dmm index b89f435a4a8c..615c8f8fcb64 100644 --- a/_maps/outpost/hangar/nt_ice_56x40.dmm +++ b/_maps/outpost/hangar/nt_ice_56x40.dmm @@ -1462,7 +1462,7 @@ }, /area/hangar) "Mt" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ icon_state = "computer-left"; dir = 4; pixel_x = -7 diff --git a/_maps/outpost/nanotrasen_asteroid.dmm b/_maps/outpost/nanotrasen_asteroid.dmm index 08f1322e7c60..164e7f8a2df2 100644 --- a/_maps/outpost/nanotrasen_asteroid.dmm +++ b/_maps/outpost/nanotrasen_asteroid.dmm @@ -282,10 +282,10 @@ /area/outpost/hallway/central) "bn" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ pixel_x = -3 }, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ pixel_x = 14 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{ @@ -931,7 +931,7 @@ /area/outpost/crew/garden) "dD" = ( /obj/structure/table/glass, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ pixel_x = 4; pixel_y = 4 }, @@ -2890,7 +2890,7 @@ /turf/open/floor/plasteel/rockvault, /area/outpost/operations) "kN" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 8 }, /obj/structure/railing{ @@ -4323,7 +4323,7 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/computer/med_data, +/obj/machinery/computer/records/med, /turf/open/floor/plasteel/dark, /area/outpost/crew/cryo) "qb" = ( @@ -4931,7 +4931,7 @@ /turf/open/floor/plasteel/dark, /area/outpost/cargo) "rO" = ( -/obj/structure/filingcabinet/security{ +/obj/structure/filingcabinet/record/security{ pixel_x = 11 }, /obj/machinery/newscaster/directional/east, @@ -7522,7 +7522,7 @@ /turf/open/floor/plating/rust, /area/outpost/maintenance/aft) "As" = ( -/obj/machinery/computer/med_data, +/obj/machinery/computer/records/med, /obj/effect/turf_decal/trimline/opaque/green/filled/line, /obj/effect/turf_decal/techfloor{ dir = 1 @@ -8129,7 +8129,7 @@ /area/outpost/operations) "CA" = ( /obj/structure/table/wood, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 8 }, /turf/open/floor/plasteel, @@ -8364,7 +8364,7 @@ /turf/open/floor/plating, /area/outpost/maintenance/aft) "Du" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 8 }, /obj/effect/turf_decal/techfloor{ @@ -8484,7 +8484,7 @@ /area/outpost/hallway/central) "DV" = ( /obj/structure/table/wood, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 4; pixel_x = -1; pixel_y = 3 @@ -9822,7 +9822,7 @@ /area/outpost/hallway/central) "Iy" = ( /obj/structure/window/reinforced/spawner/west, -/obj/machinery/computer/med_data, +/obj/machinery/computer/records/med, /turf/open/floor/plasteel/dark, /area/outpost/crew/cryo) "Iz" = ( @@ -10986,7 +10986,7 @@ /turf/open/floor/plasteel/patterned/grid, /area/outpost/hallway/fore) "MC" = ( -/obj/structure/filingcabinet/employment{ +/obj/structure/filingcabinet/record/gen{ pixel_x = -11 }, /turf/open/floor/plasteel/dark, @@ -14142,7 +14142,7 @@ /turf/open/floor/grass, /area/outpost/crew/garden) "XI" = ( -/obj/machinery/computer/secure_data, +/obj/machinery/computer/records/sec, /obj/effect/turf_decal/trimline/opaque/red/filled/line, /obj/effect/turf_decal/techfloor{ dir = 1 diff --git a/_maps/outpost/nanotrasen_ice.dmm b/_maps/outpost/nanotrasen_ice.dmm index 70fb809c4c95..5101716991f1 100644 --- a/_maps/outpost/nanotrasen_ice.dmm +++ b/_maps/outpost/nanotrasen_ice.dmm @@ -2021,7 +2021,7 @@ /area/outpost/exterior) "nU" = ( /obj/effect/decal/cleanable/dirt/dust, -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ icon_state = "computer-left" }, /turf/open/floor/plasteel/telecomms_floor, @@ -5740,7 +5740,7 @@ /turf/closed/indestructible/reinforced, /area/outpost/exterior) "Nl" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ icon_state = "computer-left" }, /turf/open/floor/plasteel/telecomms_floor, diff --git a/_maps/shuttles/independent/independent_beluga.dmm b/_maps/shuttles/independent/independent_beluga.dmm index c8ef49a3b35e..6aac1547358a 100644 --- a/_maps/shuttles/independent/independent_beluga.dmm +++ b/_maps/shuttles/independent/independent_beluga.dmm @@ -467,7 +467,7 @@ /obj/effect/turf_decal/borderfloorblack{ dir = 8 }, -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 4 }, /obj/structure/railing{ @@ -1132,7 +1132,7 @@ /obj/structure/table/reinforced{ color = "#c1b6a5" }, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_x = 5; pixel_y = 2 @@ -4586,7 +4586,7 @@ /area/ship/engineering) "SW" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4; pixel_x = -7; pixel_y = 5 diff --git a/_maps/shuttles/independent/independent_box.dmm b/_maps/shuttles/independent/independent_box.dmm index 31891a371d8c..1a05296ec8b6 100644 --- a/_maps/shuttles/independent/independent_box.dmm +++ b/_maps/shuttles/independent/independent_box.dmm @@ -2494,7 +2494,7 @@ /area/ship/engineering) "LG" = ( /obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ density = 0; pixel_x = 3 }, @@ -2638,7 +2638,7 @@ /turf/open/floor/plating, /area/ship/crew) "RR" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/item/radio/intercom/directional/west, /turf/open/floor/plasteel/dark, /area/ship/crew) diff --git a/_maps/shuttles/independent/independent_lagoon.dmm b/_maps/shuttles/independent/independent_lagoon.dmm index 248ee9240efd..7f899020d513 100644 --- a/_maps/shuttles/independent/independent_lagoon.dmm +++ b/_maps/shuttles/independent/independent_lagoon.dmm @@ -724,7 +724,7 @@ /area/ship/crew/library) "eR" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_x = 3; pixel_y = 5 @@ -1671,7 +1671,7 @@ /area/ship/crew/chapel) "kX" = ( /obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 1 }, /obj/machinery/light/directional/south, diff --git a/_maps/shuttles/independent/independent_rigger.dmm b/_maps/shuttles/independent/independent_rigger.dmm index 15265d30016b..ad70de20744c 100644 --- a/_maps/shuttles/independent/independent_rigger.dmm +++ b/_maps/shuttles/independent/independent_rigger.dmm @@ -378,7 +378,7 @@ /obj/machinery/light/small/directional/south, /obj/effect/turf_decal/borderfloor, /obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 1 }, /obj/effect/turf_decal/corner/opaque/green{ @@ -1390,7 +1390,7 @@ /turf/open/floor/plating, /area/ship/engineering/engine) "rH" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/borderfloor{ dir = 6 @@ -2538,7 +2538,7 @@ "EB" = ( /obj/item/radio/intercom/directional/south, /obj/structure/table/wood, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 1 }, /obj/item/lighter/greyscale{ @@ -4036,7 +4036,7 @@ /turf/open/floor/plating, /area/ship/engineering/atmospherics) "Vq" = ( -/obj/structure/filingcabinet/security, +/obj/structure/filingcabinet/record/security, /obj/machinery/newscaster/security_unit/directional/south, /turf/open/floor/plasteel/grimy, /area/ship/security) diff --git a/_maps/shuttles/independent/independent_schmiedeberg.dmm b/_maps/shuttles/independent/independent_schmiedeberg.dmm index ce7b407a4731..2dc1768d2575 100644 --- a/_maps/shuttles/independent/independent_schmiedeberg.dmm +++ b/_maps/shuttles/independent/independent_schmiedeberg.dmm @@ -1811,7 +1811,7 @@ /area/ship/security) "zW" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 8 }, /obj/machinery/door/window/brigdoor{ diff --git a/_maps/shuttles/independent/independent_shetland.dmm b/_maps/shuttles/independent/independent_shetland.dmm index 0481bd2506fa..32a4fab17b31 100644 --- a/_maps/shuttles/independent/independent_shetland.dmm +++ b/_maps/shuttles/independent/independent_shetland.dmm @@ -1662,7 +1662,7 @@ /area/ship/hallway/central) "oG" = ( /obj/structure/table, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ density = 0 }, /obj/effect/turf_decal/corner/opaque/black{ @@ -1800,7 +1800,7 @@ /area/ship/crew/cryo) "pR" = ( /obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 8 }, /obj/effect/turf_decal/corner/opaque/bottlegreen/full, diff --git a/_maps/shuttles/independent/independent_tranquility.dmm b/_maps/shuttles/independent/independent_tranquility.dmm index 641a74a202ef..3bdfbebf931d 100644 --- a/_maps/shuttles/independent/independent_tranquility.dmm +++ b/_maps/shuttles/independent/independent_tranquility.dmm @@ -645,7 +645,7 @@ /area/ship/external) "fk" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/med_data/laptop, +/obj/machinery/computer/records/med/laptop, /obj/effect/turf_decal/techfloor{ dir = 5 }, @@ -2016,7 +2016,7 @@ /area/ship/external) "qe" = ( /obj/structure/table, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8 }, /obj/effect/turf_decal/borderfloorblack/cee{ @@ -4266,7 +4266,7 @@ /area/ship/crew/crewfive) "Io" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4 }, /obj/effect/turf_decal/techfloor{ diff --git a/_maps/shuttles/inteq/inteq_colossus.dmm b/_maps/shuttles/inteq/inteq_colossus.dmm index 920d16cfc1c7..46bf2c56f6dd 100644 --- a/_maps/shuttles/inteq/inteq_colossus.dmm +++ b/_maps/shuttles/inteq/inteq_colossus.dmm @@ -706,7 +706,7 @@ /area/ship/hallway/fore) "hv" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4 }, /obj/effect/turf_decal/corner/opaque/yellow{ @@ -1758,7 +1758,7 @@ /area/ship/cargo) "tx" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4 }, /turf/open/floor/plasteel/dark, diff --git a/_maps/shuttles/inteq/inteq_talos.dmm b/_maps/shuttles/inteq/inteq_talos.dmm index 1babd6a9b001..af8a6ed60afe 100644 --- a/_maps/shuttles/inteq/inteq_talos.dmm +++ b/_maps/shuttles/inteq/inteq_talos.dmm @@ -3987,7 +3987,7 @@ /area/ship/storage) "yx" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop, +/obj/machinery/computer/records/sec/laptop, /turf/open/floor/plasteel/dark, /area/ship/security) "yz" = ( diff --git a/_maps/shuttles/inteq/inteq_valor.dmm b/_maps/shuttles/inteq/inteq_valor.dmm index c405c803521a..cec2b29c1059 100644 --- a/_maps/shuttles/inteq/inteq_valor.dmm +++ b/_maps/shuttles/inteq/inteq_valor.dmm @@ -1323,7 +1323,7 @@ pixel_x = 13; pixel_y = 5 }, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 1; pixel_y = 4 }, @@ -2646,7 +2646,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 1; pixel_y = 8 }, @@ -4531,7 +4531,7 @@ pixel_x = 32 }, /obj/structure/table/glass, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 8; pixel_x = 3; pixel_y = 7 diff --git a/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm b/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm index 96bd414525c0..2fc8a3c51bf3 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_heron.dmm @@ -53,7 +53,7 @@ layer = 4.1 }, /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 1; pixel_y = 4; pixel_x = 2 @@ -1206,7 +1206,7 @@ /obj/effect/turf_decal/borderfloorblack{ dir = 1 }, -/obj/machinery/computer/secure_data, +/obj/machinery/computer/records/sec, /turf/open/floor/plasteel/tech/grid, /area/ship/bridge) "eX" = ( @@ -2012,7 +2012,7 @@ /obj/effect/turf_decal/techfloor{ dir = 4 }, -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 8 }, /turf/open/floor/plasteel/tech, @@ -6824,7 +6824,7 @@ /turf/open/floor/plating, /area/ship/engineering/electrical) "zf" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 4 }, /obj/structure/extinguisher_cabinet/directional/north, @@ -8740,7 +8740,7 @@ /obj/structure/table/reinforced{ color = "#c1b6a5" }, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ pixel_y = 8; pixel_x = -2 }, @@ -12759,7 +12759,7 @@ /area/ship/crew/office) "VK" = ( /obj/structure/table, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4; pixel_x = -8; pixel_y = 5 @@ -13117,7 +13117,7 @@ /obj/effect/turf_decal/techfloor{ dir = 4 }, -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 8 }, /obj/item/radio/intercom/directional/south, diff --git a/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm b/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm index 928fc6bd90ee..afef69d50092 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm @@ -1139,7 +1139,7 @@ /turf/open/floor/plasteel, /area/ship/security/prison) "gF" = ( -/obj/structure/filingcabinet/security, +/obj/structure/filingcabinet/record/security, /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/siding/red, /turf/open/floor/plasteel/dark, diff --git a/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm b/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm index 564cf0733f9f..ef53d495e72a 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_osprey.dmm @@ -5717,7 +5717,7 @@ /turf/open/floor/plasteel, /area/ship/hallway/central) "Lc" = ( -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 4 }, /turf/open/floor/plasteel/white, diff --git a/_maps/shuttles/nanotrasen/nanotrasen_skipper.dmm b/_maps/shuttles/nanotrasen/nanotrasen_skipper.dmm index 802756c19d04..98db26ec60e2 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_skipper.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_skipper.dmm @@ -453,7 +453,7 @@ /turf/open/floor/plasteel/tech, /area/ship/engineering/atmospherics) "dW" = ( -/obj/structure/filingcabinet/employment, +/obj/structure/filingcabinet/record/gen, /turf/open/floor/carpet/nanoweave/blue, /area/ship/crew/office) "dX" = ( @@ -3030,7 +3030,7 @@ /turf/open/floor/plating, /area/ship/crew/toilet) "xA" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 4 }, /obj/machinery/light/small/directional/west, diff --git a/_maps/shuttles/pgf/pgf_crying_sun.dmm b/_maps/shuttles/pgf/pgf_crying_sun.dmm index c0584df1e945..7ce458b64d08 100644 --- a/_maps/shuttles/pgf/pgf_crying_sun.dmm +++ b/_maps/shuttles/pgf/pgf_crying_sun.dmm @@ -4473,7 +4473,7 @@ /area/ship/hallway/central) "Jd" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop, +/obj/machinery/computer/records/sec/laptop, /obj/effect/turf_decal/spline/fancy/opaque/lime{ dir = 5 }, diff --git a/_maps/shuttles/solgov/solgov_chronicle.dmm b/_maps/shuttles/solgov/solgov_chronicle.dmm index 19730904ab41..9f8bb1a84d50 100644 --- a/_maps/shuttles/solgov/solgov_chronicle.dmm +++ b/_maps/shuttles/solgov/solgov_chronicle.dmm @@ -1136,7 +1136,7 @@ /area/ship/crew/crewtwo) "kl" = ( /obj/structure/table/wood/fancy/purple, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_x = 4; pixel_y = 5 diff --git a/_maps/shuttles/solgov/solgov_inkwell.dmm b/_maps/shuttles/solgov/solgov_inkwell.dmm index d89314c2f769..34c668600a31 100644 --- a/_maps/shuttles/solgov/solgov_inkwell.dmm +++ b/_maps/shuttles/solgov/solgov_inkwell.dmm @@ -4526,7 +4526,7 @@ /area/ship/crew/canteen/kitchen) "CN" = ( /obj/structure/table/wood/fancy/blue, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4 }, /turf/open/floor/wood/walnut, @@ -5641,7 +5641,7 @@ /turf/open/floor/plasteel/white, /area/ship/cargo/office) "Kg" = ( -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 4 }, /obj/structure/table/wood/fancy/purple, diff --git a/_maps/shuttles/solgov/solgov_paracelsus.dmm b/_maps/shuttles/solgov/solgov_paracelsus.dmm index b235794d6cd4..b8bac029b178 100644 --- a/_maps/shuttles/solgov/solgov_paracelsus.dmm +++ b/_maps/shuttles/solgov/solgov_paracelsus.dmm @@ -789,7 +789,7 @@ "if" = ( /obj/structure/table/wood, /obj/machinery/light/directional/west, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 4; pixel_x = -4; pixel_y = 7 @@ -5388,7 +5388,7 @@ pixel_x = 8; pixel_y = -8 }, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 8; pixel_x = 4; pixel_y = 7 diff --git a/_maps/shuttles/subshuttles/inteq_anvil.dmm b/_maps/shuttles/subshuttles/inteq_anvil.dmm index 4a4c4073ced1..334b41dab881 100644 --- a/_maps/shuttles/subshuttles/inteq_anvil.dmm +++ b/_maps/shuttles/subshuttles/inteq_anvil.dmm @@ -1,6 +1,6 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( -/obj/machinery/computer/secure_data{ +/obj/machinery/computer/records/sec{ dir = 8 }, /obj/effect/turf_decal/techfloor{ diff --git a/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm b/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm index d218dc5581b1..5d616a1376cc 100644 --- a/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm +++ b/_maps/shuttles/syndicate/syndicate_gorlex_komodo.dmm @@ -616,7 +616,7 @@ /obj/structure/table/reinforced, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 4 }, /obj/effect/turf_decal/spline/fancy/opaque/black{ @@ -807,7 +807,7 @@ /turf/open/floor/plasteel/tech, /area/ship/maintenance/starboard) "ip" = ( -/obj/machinery/computer/med_data/syndie, +/obj/machinery/computer/records/med/syndie, /obj/effect/turf_decal/techfloor{ dir = 1 }, @@ -908,7 +908,7 @@ /turf/open/floor/plasteel/tech/techmaint, /area/ship/engineering) "jn" = ( -/obj/machinery/computer/secure_data/syndie{ +/obj/machinery/computer/records/sec/syndie{ dir = 1 }, /obj/effect/turf_decal/techfloor, diff --git a/_maps/shuttles/syndicate/syndicate_litieguai.dmm b/_maps/shuttles/syndicate/syndicate_litieguai.dmm index 2b12f177f57e..46143a322557 100644 --- a/_maps/shuttles/syndicate/syndicate_litieguai.dmm +++ b/_maps/shuttles/syndicate/syndicate_litieguai.dmm @@ -1198,7 +1198,7 @@ /turf/open/floor/engine, /area/ship/cargo) "yQ" = ( -/obj/machinery/computer/med_data{ +/obj/machinery/computer/records/med{ dir = 8 }, /turf/open/floor/plasteel/dark, @@ -2199,7 +2199,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 4 }, /obj/machinery/door/firedoor/border_only{ @@ -2652,7 +2652,7 @@ /turf/open/floor/plasteel/tech, /area/ship/medical) "TZ" = ( -/obj/structure/filingcabinet/medical, +/obj/structure/filingcabinet/record/medical, /obj/machinery/airalarm/directional/east, /obj/machinery/light/directional/north, /turf/open/floor/carpet/cyan, diff --git a/_maps/shuttles/syndicate/syndicate_panacea.dmm b/_maps/shuttles/syndicate/syndicate_panacea.dmm index 24334160f64b..03defd494174 100644 --- a/_maps/shuttles/syndicate/syndicate_panacea.dmm +++ b/_maps/shuttles/syndicate/syndicate_panacea.dmm @@ -1292,7 +1292,7 @@ /area/ship/crew/dorm/dormtwo) "hs" = ( /obj/structure/table/wood/reinforced, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 1; pixel_y = 4 }, @@ -2936,7 +2936,7 @@ /area/ship/crew/dorm) "qk" = ( /obj/structure/table/wood/reinforced, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 1; pixel_y = 4 }, @@ -5855,7 +5855,7 @@ /area/ship/engineering) "Ix" = ( /obj/structure/table, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_y = 5; pixel_x = 4 @@ -8310,7 +8310,7 @@ }, /area/ship/crew/dorm/dormfour) "Xw" = ( -/obj/machinery/computer/med_data/syndie{ +/obj/machinery/computer/records/med/syndie{ dir = 8 }, /turf/open/floor/suns/hatch{ diff --git a/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm b/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm index bca4d457916a..f0e5a755a498 100644 --- a/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm +++ b/_maps/shuttles/syndicate/syndicate_twinkleshine.dmm @@ -589,7 +589,7 @@ /area/ship/cargo) "dq" = ( /obj/structure/table/reinforced, -/obj/machinery/computer/secure_data/laptop{ +/obj/machinery/computer/records/sec/laptop{ dir = 8; pixel_y = 6; pixel_x = 1 @@ -1000,7 +1000,7 @@ /area/ship/engineering/engine) "gq" = ( /obj/structure/table, -/obj/machinery/computer/med_data/laptop{ +/obj/machinery/computer/records/med/laptop{ dir = 8; pixel_y = 6 }, diff --git a/code/__DEFINES/datacore.dm b/code/__DEFINES/datacore.dm new file mode 100644 index 000000000000..fa224c91bda8 --- /dev/null +++ b/code/__DEFINES/datacore.dm @@ -0,0 +1,85 @@ +#define DATACORE_ID "id" +#define DATACORE_RANK "rank" +#define DATACORE_INITIAL_RANK "initial_rank" +#define DATACORE_NAME "name" +#define DATACORE_AGE "age" +#define DATACORE_GENDER "gender" +#define DATACORE_SPECIES "species" + +#define DATACORE_APPEARANCE "character_appearance" +#define DATACORE_NOTES "notes" + +#define DATACORE_PHYSICAL_HEALTH "p_stat" +#define DATACORE_MENTAL_HEALTH "m_stat" + +#define DATACORE_BLOOD_TYPE "blood_type" +#define DATACORE_BLOOD_DNA "b_dna" +#define DATACORE_DISEASES "cdi" +#define DATACORE_DISEASES_DETAILS "cdi_d" +#define DATACORE_DISABILITIES "ma_dis" +#define DATACORE_DISABILITIES_DETAILS "ma_dis_d" +#define DATACORE_NOTES_MEDICAL "medical_note" + +#define DATACORE_FINGERPRINT "fingerprint" +#define DATACORE_CRIMES "crim" +#define DATACORE_CRIMINAL_STATUS "criminal" +#define DATACORE_NOTES_SECURITY "security_note" + +//Not very used +#define DATACORE_IMAGE "image" +#define DATACORE_DNA_IDENTITY "identity" +#define DATACORE_DNA_FEATURES "features" +#define DATACORE_MINDREF "mind" + +/// Keys for SSdatacore.library +#define DATACORE_RECORDS_OUTPOST "outpost" +//#define DATACORE_RECORDS_SECURITY "security" +//#define DATACORE_RECORDS_MEDICAL "medical" +//#define DATACORE_RECORDS_LOCKED "locked" + + +/// Physical statuses +#define PHYSICAL_ACTIVE "Active" +#define PHYSICAL_DEBILITATED "Debilitated" +#define PHYSICAL_UNCONSCIOUS "Unconscious" +#define PHYSICAL_DECEASED "Deceased" + +/// List of available physical statuses +#define PHYSICAL_STATUSES list(\ + PHYSICAL_ACTIVE, \ + PHYSICAL_DEBILITATED, \ + PHYSICAL_UNCONSCIOUS, \ + PHYSICAL_DECEASED, \ +) + +/// Mental statuses +#define MENTAL_STABLE "Stable" +#define MENTAL_WATCH "Watch" +#define MENTAL_UNSTABLE "Unstable" +#define MENTAL_INSANE "Insane" + +/// List of available mental statuses +#define MENTAL_STATUSES list(\ + MENTAL_STABLE, \ + MENTAL_WATCH, \ + MENTAL_UNSTABLE, \ + MENTAL_INSANE, \ +) + +/// Wanted statuses +#define WANTED_ARREST "Arrest" +#define WANTED_DISCHARGED "Discharged" +#define WANTED_NONE "None" +#define WANTED_PAROLE "Parole" +#define WANTED_PRISONER "Incarcerated" +#define WANTED_SUSPECT "Suspected" + +/// List of available wanted statuses +#define WANTED_STATUSES list(\ + WANTED_NONE, \ + WANTED_SUSPECT, \ + WANTED_ARREST, \ + WANTED_PRISONER, \ + WANTED_PAROLE, \ + WANTED_DISCHARGED, \ +) diff --git a/code/__DEFINES/dcs/signals/signals.dm b/code/__DEFINES/dcs/signals/signals.dm index 38f7d8692853..5fcd3e4b9137 100644 --- a/code/__DEFINES/dcs/signals/signals.dm +++ b/code/__DEFINES/dcs/signals/signals.dm @@ -730,6 +730,12 @@ ///called in /obj/item/gun/process_chamber (src) #define COMSIG_GUN_CHAMBER_PROCESSED "gun_chamber_processed" + +///Global signal sent when the Datacore's initial manifest is complete +#define COMSIG_GLOB_DATACORE_READY "datacore_ready" +///Global signal sent when the datacore is added to via manifest_inject() (datum/data/record/general, datum/data/record/medical, datum/data/record/security, datum/data/record/locked) +#define COMSIG_GLOB_MANIFEST_INJECT "manifest_inject" + ///called when an elzu should unroot #define COMSIG_DIGOUT "dig_out" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 3c815ef1fc37..1d77af86f9fd 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -329,7 +329,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE //Dummy mob reserve slots #define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview" #define DUMMY_HUMAN_SLOT_ADMIN "admintools" -#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation" #define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 54874bc9e16b..868eae83cf34 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -120,6 +120,7 @@ #define INIT_ORDER_EVENTS 70 #define INIT_ORDER_JOBS 65 #define INIT_ORDER_QUIRKS 60 +#define INIT_ORDER_DATACORE 57 // Must come before SSticker so datacore reading things can access it #define INIT_ORDER_TICKER 55 #define INIT_ORDER_FACTION 53 #define INIT_ORDER_MAPPING 50 diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 435b83e29797..0586f458cf06 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -460,14 +460,6 @@ i++ return i -/// Returns datum/data/record -/proc/find_record(field, value, list/L) - for(var/datum/data/record/R in L) - if(R.fields[field] == value) - return R - return FALSE - - //Move a single element from position fromIndex within a list, to position toIndex //All elements in the range [1,toIndex) before the move will be before the pivot afterwards //All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 38e540e996b9..11f1bd430a81 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -712,206 +712,180 @@ world /// appearance system (overlays/underlays, etc.) is not available. /// /// Only the first argument is required. -/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = TRUE) - //Define... defines. +/proc/getFlatIcon(image/appearance, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) + // Loop through the underlays, then overlays, sorting them into the layers list + #define PROCESS_OVERLAYS_OR_UNDERLAYS(flat, process, base_layer) \ + for (var/i in 1 to process.len) { \ + var/image/current = process[i]; \ + if (!current) { \ + continue; \ + } \ + if (current.plane != FLOAT_PLANE && current.plane != appearance.plane) { \ + continue; \ + } \ + var/current_layer = current.layer; \ + if (current_layer < 0) { \ + if (current_layer <= -1000) { \ + return flat; \ + } \ + current_layer = base_layer + appearance.layer + current_layer / 1000; \ + } \ + for (var/index_to_compare_to in 1 to layers.len) { \ + var/compare_to = layers[index_to_compare_to]; \ + if (current_layer < layers[compare_to]) { \ + layers.Insert(index_to_compare_to, current); \ + break; \ + } \ + } \ + layers[current] = current_layer; \ + } + var/static/icon/flat_template = icon('icons/blanks/32x32.dmi', "nothing") - #define BLANK icon(flat_template) - #define SET_SELF(SETVAR) do { \ - var/icon/SELF_ICON=icon(icon(curicon, curstate, base_icon_dir),"",SOUTH,no_anim?1:null); \ - if(A.alpha<255) { \ - SELF_ICON.Blend(rgb(255,255,255,A.alpha),ICON_MULTIPLY);\ - } \ - if(A.color) { \ - if(islist(A.color)){ \ - SELF_ICON.MapColors(arglist(A.color))} \ - else{ \ - SELF_ICON.Blend(A.color,ICON_MULTIPLY)} \ - } \ - ##SETVAR=SELF_ICON;\ - } while (0) - #define INDEX_X_LOW 1 - #define INDEX_X_HIGH 2 - #define INDEX_Y_LOW 3 - #define INDEX_Y_HIGH 4 - - #define flatX1 flat_size[INDEX_X_LOW] - #define flatX2 flat_size[INDEX_X_HIGH] - #define flatY1 flat_size[INDEX_Y_LOW] - #define flatY2 flat_size[INDEX_Y_HIGH] - #define addX1 add_size[INDEX_X_LOW] - #define addX2 add_size[INDEX_X_HIGH] - #define addY1 add_size[INDEX_Y_LOW] - #define addY2 add_size[INDEX_Y_HIGH] - - if(!A || A.alpha <= 0) - return BLANK - - var/noIcon = FALSE + if(!appearance || appearance.alpha <= 0) + return icon(flat_template) + if(start) if(!defdir) - defdir = A.dir + defdir = appearance.dir if(!deficon) - deficon = A.icon + deficon = appearance.icon if(!defstate) - defstate = A.icon_state + defstate = appearance.icon_state if(!defblend) - defblend = A.blend_mode + defblend = appearance.blend_mode + + var/curicon = appearance.icon || deficon + var/curstate = appearance.icon_state || defstate + var/curdir = (!appearance.dir || appearance.dir == SOUTH) ? defdir : appearance.dir - var/curicon = A.icon || deficon - var/curstate = A.icon_state || defstate + var/render_icon = curicon - if(!((noIcon = (!curicon)))) + if (render_icon) var/curstates = icon_states(curicon) if(!(curstate in curstates)) - if("" in curstates) + if ("" in curstates) curstate = "" else - noIcon = TRUE // Do not render this object. + render_icon = FALSE - var/curdir - var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have - - //These should use the parent's direction (most likely) - if(!A.dir || A.dir == SOUTH) - curdir = defdir - else - curdir = A.dir + var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have //Try to remove/optimize this section ASAP, CPU hog. //Determines if there's directionals. - if(!noIcon && curdir != SOUTH) - var/exist = FALSE - var/static/list/checkdirs = list(NORTH, EAST, WEST) - for(var/i in checkdirs) //Not using GLOB for a reason. - if(length(icon_states(icon(curicon, curstate, i)))) - exist = TRUE - break - if(!exist) + if(render_icon && curdir != SOUTH) + if ( + !length(icon_states(icon(curicon, curstate, NORTH))) \ + && !length(icon_states(icon(curicon, curstate, EAST))) \ + && !length(icon_states(icon(curicon, curstate, WEST))) \ + ) base_icon_dir = SOUTH - // if(!base_icon_dir) base_icon_dir = curdir - ASSERT(!BLEND_DEFAULT) //I might just be stupid but lets make sure this define is 0. + var/curblend = appearance.blend_mode || defblend - var/curblend = A.blend_mode || defblend - - if(A.overlays.len || A.underlays.len) - var/icon/flat = BLANK + if(appearance.overlays.len || appearance.underlays.len) + var/icon/flat = icon(flat_template) // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed var/list/layers = list() var/image/copy // Add the atom's icon itself, without pixel_x/y offsets. - if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) - copy.color = A.color - copy.alpha = A.alpha + if(render_icon) + copy = image(icon=curicon, icon_state=curstate, layer=appearance.layer, dir=base_icon_dir) + copy.color = appearance.color + copy.alpha = appearance.alpha copy.blend_mode = curblend - layers[copy] = A.layer - - // Loop through the underlays, then overlays, sorting them into the layers list - for(var/process_set in 0 to 1) - var/list/process = process_set? A.overlays : A.underlays - for(var/i in 1 to process.len) - var/image/current = process[i] - if(!current) - continue - if(current.plane != FLOAT_PLANE && current.plane != A.plane) - continue - var/current_layer = current.layer - if(current_layer < 0) - if(current_layer <= -1000) - return flat - current_layer = process_set + A.layer + current_layer / 1000 - - for(var/p in 1 to layers.len) - var/image/cmp = layers[p] - if(current_layer < layers[cmp]) - layers.Insert(p, current) - break - layers[current] = current_layer - - //sortTim(layers, /proc/cmp_image_layer_asc) + layers[copy] = appearance.layer + + PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.underlays, 0) + PROCESS_OVERLAYS_OR_UNDERLAYS(flat, appearance.overlays, 1) var/icon/add // Icon of overlay being added - // Current dimensions of flattened icon - var/list/flat_size = list(1, flat.Width(), 1, flat.Height()) - // Dimensions of overlay being added - var/list/add_size[4] + var/flatX1 = 1 + var/flatX2 = flat.Width() + var/flatY1 = 1 + var/flatY2 = flat.Height() - for(var/V in layers) - var/image/I = V - if(I.alpha == 0) + var/addX1 = 0 + var/addX2 = 0 + var/addY1 = 0 + var/addY2 = 0 + + for(var/image/layer_image as anything in layers) + if(layer_image.alpha == 0) continue - if(I == copy) // 'I' is an /image based on the object being flattened. + if(layer_image == copy) // 'layer_image' is an /image based on the object being flattened. curblend = BLEND_OVERLAY - add = icon(I.icon, I.icon_state, base_icon_dir) + add = icon(layer_image.icon, layer_image.icon_state, base_icon_dir) else // 'I' is an appearance object. - add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) + add = getFlatIcon(image(layer_image), curdir, curicon, curstate, curblend, FALSE, no_anim) if(!add) continue + // Find the new dimensions of the flat icon to fit the added overlay - add_size = list( - min(flatX1, I.pixel_x+1), - max(flatX2, I.pixel_x+add.Width()), - min(flatY1, I.pixel_y+1), - max(flatY2, I.pixel_y+add.Height()) + addX1 = min(flatX1, layer_image.pixel_x + 1) + addX2 = max(flatX2, layer_image.pixel_x + add.Width()) + addY1 = min(flatY1, layer_image.pixel_y + 1) + addY2 = max(flatY2, layer_image.pixel_y + add.Height()) + + if ( + addX1 != flatX1 \ + && addX2 != flatX2 \ + && addY1 != flatY1 \ + && addY2 != flatY2 \ ) - - if(flat_size ~! add_size) // Resize the flattened icon so the new icon fits flat.Crop( - addX1 - flatX1 + 1, - addY1 - flatY1 + 1, - addX2 - flatX1 + 1, - addY2 - flatY1 + 1 + addX1 - flatX1 + 1, + addY1 - flatY1 + 1, + addX2 - flatX1 + 1, + addY2 - flatY1 + 1 ) - flat_size = add_size.Copy() + + flatX1 = addX1 + flatX2 = addY1 + flatY1 = addX2 + flatY2 = addY2 // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) + flat.Blend(add, blendMode2iconMode(curblend), layer_image.pixel_x + 2 - flatX1, layer_image.pixel_y + 2 - flatY1) - if(A.color) - if(islist(A.color)) - flat.MapColors(arglist(A.color)) + if(appearance.color) + if(islist(appearance.color)) + flat.MapColors(arglist(appearance.color)) else - flat.Blend(A.color, ICON_MULTIPLY) + flat.Blend(appearance.color, ICON_MULTIPLY) - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + if(appearance.alpha < 255) + flat.Blend(rgb(255, 255, 255, appearance.alpha), ICON_MULTIPLY) if(no_anim) //Clean up repeated frames var/icon/cleaned = new /icon() cleaned.Insert(flat, "", SOUTH, 1, 0) - . = cleaned + return cleaned else - . = icon(flat, "", SOUTH) - else //There's no overlays. - if(!noIcon) - SET_SELF(.) - - //Clear defines - #undef flatX1 - #undef flatX2 - #undef flatY1 - #undef flatY2 - #undef addX1 - #undef addX2 - #undef addY1 - #undef addY2 - - #undef INDEX_X_LOW - #undef INDEX_X_HIGH - #undef INDEX_Y_LOW - #undef INDEX_Y_HIGH - - #undef BLANK - #undef SET_SELF + return icon(flat, "", SOUTH) + else if (render_icon) // There's no overlays. + var/icon/final_icon = icon(icon(curicon, curstate, base_icon_dir), "", SOUTH, no_anim ? TRUE : null) + + if (appearance.alpha < 255) + final_icon.Blend(rgb(255,255,255, appearance.alpha), ICON_MULTIPLY) + + if (appearance.color) + if (islist(appearance.color)) + final_icon.MapColors(arglist(appearance.color)) + else + final_icon.Blend(appearance.color, ICON_MULTIPLY) + + return final_icon + + #undef PROCESS_OVERLAYS_OR_UNDERLAYS + /proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index d78667dbfb4b..de002044a836 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -176,8 +176,8 @@ GLOBAL_DATUM(syndicate_code_response_regex, /regex) var/locations = strings(LOCATIONS_FILE, "locations") var/list/names = list() - for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. - names += t.fields["name"] + for(var/datum/data/record/t in SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))//Picks from crew manifest. + names += t.fields[DATACORE_NAME] var/maxwords = words//Extra var to check for duplicates. diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index d6c720380f46..6b4e519f2444 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -6,8 +6,6 @@ GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the hos // However it'd be ok to use for accessing attack logs and such too, which are even laggier. GLOBAL_VAR_INIT(fileaccess_timer, 0) -GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) - GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second) diff --git a/code/controllers/subsystem/datacore.dm b/code/controllers/subsystem/datacore.dm new file mode 100644 index 000000000000..14d75ec3e211 --- /dev/null +++ b/code/controllers/subsystem/datacore.dm @@ -0,0 +1,273 @@ + +///Dummy mob reserve slot for manifest +#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation" + +SUBSYSTEM_DEF(datacore) + name = "Data Core" + flags = SS_NO_FIRE + init_order = INIT_ORDER_DATACORE + + /// A list of data libraries keyed by DATACORE_RECORDS_* + var/list/datum/data_library/library = list( + DATACORE_RECORDS_OUTPOST, + ) + + /// Set to TRUE when the initial roundstart manifest is complete + var/finished_setup = FALSE + + var/list/datum/callback/datacore_ready_callbacks = list() + +/datum/controller/subsystem/datacore/Initialize(start_timeofday) + for(var/id in library) + library[id] = new /datum/data_library + return ..() + +/datum/controller/subsystem/datacore/Recover() + library = SSdatacore.library + finished_setup = SSdatacore.finished_setup + +/datum/controller/subsystem/datacore/proc/create_library(library_key) + var/datum/data_library/new_library = new /datum/data_library + library[library_key] = new_library + return new_library + +/// Returns a data record or null. +/datum/controller/subsystem/datacore/proc/get_record_by_name(name, record_type = DATACORE_RECORDS_OUTPOST) + RETURN_TYPE(/datum/data/record) + + return library[record_type].get_record_by_name(name) + +/// Returns a data library's records list +/datum/controller/subsystem/datacore/proc/get_records(record_type = DATACORE_RECORDS_OUTPOST) + RETURN_TYPE(/list) + return library[record_type].records + +/datum/controller/subsystem/datacore/proc/find_record(field, needle, haystack = DATACORE_RECORDS_OUTPOST) + RETURN_TYPE(/datum/data/record) + for(var/datum/data/record/record_to_check in get_records(haystack)) + if(record_to_check.fields[field] == needle) + return record_to_check + +/// Empties out a library +/datum/controller/subsystem/datacore/proc/wipe_records(record_type) + var/datum/data_library/to_wipe = library[record_type] + if(!to_wipe) + return + + QDEL_LIST(to_wipe.records) + +/// Removes a person from history. Except locked. That's permanent history. +/datum/controller/subsystem/datacore/proc/demanifest(name) + //for(var/id in library - DATACORE_RECORDS_LOCKED) + for(var/id in library) + var/datum/data/record/R = get_record_by_name(name, id) + qdel(R) + +/datum/controller/subsystem/datacore/proc/inject_record(datum/data/record/R, record_type) + if(isnull(record_type)) + CRASH("inject_record() called with no record type") + + library[record_type].inject_record(R) + +/// Create the roundstart manifest using the newplayer list. +/datum/controller/subsystem/datacore/proc/generate_manifest() + for(var/mob/dead/new_player/N as anything in GLOB.new_player_list) + if(N.new_character) + log_manifest(N.ckey, N.new_character.mind, N.new_character) + + if(ishuman(N.new_character)) + inject_library(N.new_character, N.client, DATACORE_RECORDS_OUTPOST) + + CHECK_TICK + + finished_setup = TRUE + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_DATACORE_READY, src) + invoke_datacore_callbacks() + +/// Add a callback to execute when the datacore has loaded +/datum/controller/subsystem/datacore/proc/OnReady(datum/callback/CB) + if(finished_setup) + CB.InvokeAsync() + else + datacore_ready_callbacks += CB + +/datum/controller/subsystem/datacore/proc/invoke_datacore_callbacks() + for(var/datum/callback/CB as anything in datacore_ready_callbacks) + CB.InvokeAsync() + + datacore_ready_callbacks.Cut() + +/datum/controller/subsystem/datacore/proc/manifest_modify(name, assignment) + var/datum/data/record/foundrecord = library[DATACORE_RECORDS_OUTPOST].get_record_by_name(name) + if(foundrecord) + foundrecord.fields[DATACORE_RANK] = assignment + +/datum/controller/subsystem/datacore/proc/get_manifest(record_type = DATACORE_RECORDS_OUTPOST) + var/list/manifest_out = list() + var/list/departments = list( + "Command" = GLOB.command_positions, + "Security" = GLOB.security_positions, + "Engineering" = GLOB.engineering_positions, + "Medical" = GLOB.medical_positions, + "Science" = GLOB.science_positions, + "Supply" = GLOB.supply_positions, + "Service" = GLOB.service_positions, + "Silicon" = GLOB.nonhuman_positions + ) + for(var/datum/data/record/record as anything in SSdatacore.get_records(record_type)) + var/name = record.fields[DATACORE_NAME] + var/rank = record.fields[DATACORE_RANK] // user-visible job + var/has_department = FALSE + for(var/department in departments) + var/list/jobs = departments[department] + if((rank in jobs)) + if(!manifest_out[department]) + manifest_out[department] = list() + // Append to beginning of list if captain or department head + if (rank == "Captain" || (department != "Command" && (rank in GLOB.command_positions))) + manifest_out[department] = list(list( + "name" = name, + "rank" = rank + )) + manifest_out[department] + else + manifest_out[department] += list(list( + "name" = name, + "rank" = rank + )) + has_department = TRUE + if(!has_department) + if(!manifest_out["Misc"]) + manifest_out["Misc"] = list() + manifest_out["Misc"] += list(list( + "name" = name, + "rank" = rank + )) + + return manifest_out + +//For ship records +/datum/controller/subsystem/datacore/proc/inject_library(mob/living/carbon/human/H, client/C, datum/data_library/custom_library) + var/static/list/show_directions = list(SOUTH, WEST) + if(!(H.mind && (H.mind.assigned_role != H.mind.special_role))) + return + + var/assignment + if(H.mind.assigned_role) + assignment = H.mind.assigned_role + else if(H.job) + assignment = H.job + else + assignment = "Unassigned" + + var/static/record_id_num = 1001 + var/id = num2hex(record_id_num++,6) + if(!C) + C = H.client + + var/person_gender = "Other" + if(H.gender == "male") + person_gender = "Male" + if(H.gender == "female") + person_gender = "Female" + + var/mutable_appearance/character_appearance = new(H.appearance) + + //General Record + var/datum/data/record/G = new() + G.fields[DATACORE_ID] = id + G.fields[DATACORE_RANK] = assignment + G.fields[DATACORE_INITIAL_RANK] = assignment + G.fields[DATACORE_NAME] = H.real_name + G.fields[DATACORE_AGE] = H.age + G.fields[DATACORE_GENDER] = person_gender + G.fields[DATACORE_SPECIES] = H.dna.species.name + + G.fields[DATACORE_APPEARANCE] = character_appearance + G.fields[DATACORE_NOTES] = "No notes." + + G.fields[DATACORE_PHYSICAL_HEALTH] = PHYSICAL_ACTIVE + G.fields[DATACORE_MENTAL_HEALTH] = MENTAL_STABLE + + G.fields[DATACORE_BLOOD_TYPE] = H.dna.blood_type.name + G.fields[DATACORE_BLOOD_DNA] = H.dna.unique_enzymes + G.fields[DATACORE_DISABILITIES] = "None" + G.fields[DATACORE_DISABILITIES_DETAILS] = "No minor disabilities have been declared." + G.fields[DATACORE_DISEASES] = "None" + G.fields[DATACORE_DISEASES_DETAILS] = "No diseases have been diagnosed at the moment." + G.fields[DATACORE_NOTES_MEDICAL] = list() + + G.fields[DATACORE_FINGERPRINT] = md5(H.dna.uni_identity) + G.fields[DATACORE_CRIMINAL_STATUS] = "None" + G.fields[DATACORE_CRIMES] = list() + G.fields[DATACORE_NOTES_SECURITY] = "No security notes." + + if(istype(custom_library, /datum/data_library)) + custom_library.inject_record(G) + else + library[custom_library].inject_record(G) + +/datum/controller/subsystem/datacore/proc/create_record(library_target, name) + var/datum/data/record/new_record = new /datum/data/record + new_record.fields[DATACORE_NAME] = name + library[library_target].inject_record(new_record) + return new_record + +/** + * Supporing proc for getting general records + * and using them as pAI ui data. This gets + * medical information - or what I would deem + * medical information - and sends it as a list. + * + * @return - list(general_records_out) + */ +/datum/controller/subsystem/datacore/proc/get_general_records(record_key = DATACORE_RECORDS_OUTPOST) + if(!get_records(record_key)) + return list() + + /// The array of records + var/list/general_records_out = list() + for(var/datum/data/record/gen_record as anything in get_records(record_key)) + /// The object containing the crew info + var/list/crew_record = list() + crew_record["ref"] = REF(gen_record) + crew_record[DATACORE_NAME] = gen_record.fields[DATACORE_NAME] + crew_record[DATACORE_PHYSICAL_HEALTH] = gen_record.fields[DATACORE_PHYSICAL_HEALTH] + crew_record[DATACORE_MENTAL_HEALTH] = gen_record.fields[DATACORE_MENTAL_HEALTH] + general_records_out += list(crew_record) + return general_records_out + +/** + * Supporing proc for getting secrurity records + * and using them as pAI ui data. Sends it as a + * list. + * + * @return - list(security_records_out) + */ +/datum/controller/subsystem/datacore/proc/get_security_records(record_key = DATACORE_RECORDS_OUTPOST) + if(!get_records(record_key)) + return list() + + /// The array of records + var/list/security_records_out = list() + for(var/datum/data/record/sec_record as anything in get_records(record_key)) + /// The object containing the crew info + var/list/crew_record = list() + crew_record["ref"] = REF(sec_record) + crew_record["name"] = sec_record.fields[DATACORE_NAME] + crew_record["status"] = sec_record.fields[DATACORE_CRIMINAL_STATUS] // wanted status + crew_record["crimes"] = length(sec_record.fields[DATACORE_CRIMES]) + security_records_out += list(crew_record) + return security_records_out + +/// Creates a new crime entry and hands it back. +/datum/controller/subsystem/datacore/proc/new_crime_entry(cname = "", cdetails = "", author = "", time = "", fine = 0) + var/datum/data/crime/c = new /datum/data/crime + c.crimeName = cname + c.crimeDetails = cdetails + c.author = author + c.time = time + c.fine = fine + c.paid = 0 + return c + +#undef DUMMY_HUMAN_SLOT_MANIFEST diff --git a/code/controllers/subsystem/overmap.dm b/code/controllers/subsystem/overmap.dm index 113bfefa7a52..5f70d23c400e 100644 --- a/code/controllers/subsystem/overmap.dm +++ b/code/controllers/subsystem/overmap.dm @@ -463,33 +463,6 @@ SUBSYSTEM_DEF(overmap) return manifest_out -/datum/controller/subsystem/overmap/proc/get_manifest_html(monochrome = FALSE) - var/list/manifest = get_manifest() - var/dat = {" - - - - "} - for(var/department in manifest) - var/list/entries = manifest[department] - dat += "" - var/even = FALSE - for(var/entry in entries) - var/list/entry_list = entry - dat += "" - even = !even - - dat += "
NameRank
[department]
[entry_list["name"]][entry_list["rank"]]
" - dat = replacetext(dat, "\n", "") - dat = replacetext(dat, "\t", "") - return dat - /datum/controller/subsystem/overmap/Recover() overmap_objects = SSovermap.overmap_objects controlled_ships = SSovermap.controlled_ships diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm deleted file mode 100644 index 0103be96ce03..000000000000 --- a/code/datums/datacore.dm +++ /dev/null @@ -1,291 +0,0 @@ -//TODO: someone please get rid of this shit -/datum/datacore - var/list/medical = list() - var/medicalPrintCount = 0 - var/list/general = list() - var/list/security = list() - var/securityPrintCount = 0 - var/securityCrimeCounter = 0 - ///This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/list/locked = list() - -/datum/data - var/name = "data" - -/datum/data/record - name = "record" - var/list/fields = list() - -/datum/data/record/Destroy() - if(src in GLOB.data_core.medical) - GLOB.data_core.medical -= src - if(src in GLOB.data_core.security) - GLOB.data_core.security -= src - if(src in GLOB.data_core.general) - GLOB.data_core.general -= src - if(src in GLOB.data_core.locked) - GLOB.data_core.locked -= src - . = ..() - -/datum/data/crime - name = "crime" - var/crimeName = "" - var/crimeDetails = "" - var/author = "" - var/time = "" - var/fine = 0 - var/paid = 0 - var/dataId = 0 - -/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "", fine = 0) - var/datum/data/crime/c = new /datum/data/crime - c.crimeName = cname - c.crimeDetails = cdetails - c.author = author - c.time = time - c.fine = fine - c.paid = 0 - c.dataId = ++securityCrimeCounter - return c - -/** - * Adds crime to security record. - * - * Is used to add single crime to someone's security record. - * Arguments: - * * id - record id. - * * datum/data/crime/crime - premade array containing every variable, usually created by createCrimeEntry. - */ -/datum/datacore/proc/addCrime(id = "", datum/data/crime/crime) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["crim"] - crimes |= crime - return - -/** - * Deletes crime from security record. - * - * Is used to delete single crime to someone's security record. - * Arguments: - * * id - record id. - * * cDataId - id of already existing crime. - */ -/datum/datacore/proc/removeCrime(id, cDataId) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["crim"] - for(var/datum/data/crime/crime in crimes) - if(crime.dataId == text2num(cDataId)) - crimes -= crime - return - -/** - * Adds details to a crime. - * - * Is used to add or replace details to already existing crime. - * Arguments: - * * id - record id. - * * cDataId - id of already existing crime. - * * details - data you want to add. - */ -/datum/datacore/proc/addCrimeDetails(id, cDataId, details) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["crim"] - for(var/datum/data/crime/crime in crimes) - if(crime.dataId == text2num(cDataId)) - crime.crimeDetails = details - return - -/datum/datacore/proc/manifest() - for(var/i in GLOB.new_player_list) - var/mob/dead/new_player/N = i - if(N.new_character) - log_manifest(N.ckey,N.new_character.mind,N.new_character) - if(ishuman(N.new_character)) - manifest_inject(N.new_character, N.client) - CHECK_TICK - -/datum/datacore/proc/manifest_modify(name, assignment) - var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general) - if(foundrecord) - foundrecord.fields["rank"] = assignment - -/datum/datacore/proc/get_manifest() - var/list/manifest_out = list() - var/list/departments = list( - "Command" = GLOB.command_positions, - "Security" = GLOB.security_positions, - "Engineering" = GLOB.engineering_positions, - "Medical" = GLOB.medical_positions, - "Science" = GLOB.science_positions, - "Supply" = GLOB.supply_positions, - "Service" = GLOB.service_positions, - "Silicon" = GLOB.nonhuman_positions - ) - for(var/datum/data/record/t in GLOB.data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/has_department = FALSE - for(var/department in departments) - var/list/jobs = departments[department] - if((rank in jobs)) - if(!manifest_out[department]) - manifest_out[department] = list() - // Append to beginning of list if captain or department head - if (rank == "Captain" || (department != "Command" && (rank in GLOB.command_positions))) - manifest_out[department] = list(list( - "name" = name, - "rank" = rank - )) + manifest_out[department] - else - manifest_out[department] += list(list( - "name" = name, - "rank" = rank - )) - has_department = TRUE - if(!has_department) - if(!manifest_out["Misc"]) - manifest_out["Misc"] = list() - manifest_out["Misc"] += list(list( - "name" = name, - "rank" = rank - )) - return manifest_out - -/datum/datacore/proc/get_manifest_html(monochrome = FALSE) - var/list/manifest = get_manifest() - var/dat = {" - - - - "} - for(var/department in manifest) - var/list/entries = manifest[department] - dat += "" - //JUST - var/even = FALSE - for(var/entry in entries) - var/list/entry_list = entry - dat += "" - even = !even - - dat += "
NameRank
[department]
[entry_list["name"]][entry_list["rank"]]
" - dat = replacetext(dat, "\n", "") - dat = replacetext(dat, "\t", "") - return dat - - -/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C) - set waitfor = FALSE - var/static/list/show_directions = list(SOUTH, WEST) - if(H.mind && (H.mind.assigned_role != H.mind.special_role)) - var/assignment - if(H.mind.assigned_role) - assignment = H.mind.assigned_role - else if(H.job) - assignment = H.job - else - assignment = "Unassigned" - - var/static/record_id_num = 1001 - var/id = num2hex(record_id_num++,6) - if(!C) - C = H.client - var/image = get_id_photo(H, C, show_directions) - var/datum/picture/pf = new - var/datum/picture/ps = new - pf.picture_name = "[H]" - ps.picture_name = "[H]" - pf.picture_desc = "This is [H]." - ps.picture_desc = "This is [H]." - pf.picture_image = icon(image, dir = SOUTH) - ps.picture_image = icon(image, dir = WEST) - var/obj/item/photo/photo_front = new(null, pf) - var/obj/item/photo/photo_side = new(null, ps) - - //These records should ~really~ be merged or something - //General Record - var/datum/data/record/G = new() - G.fields["id"] = id - G.fields["name"] = H.real_name - G.fields["rank"] = assignment - G.fields["age"] = H.age - G.fields["species"] = H.dna.species.name - G.fields["fingerprint"] = md5(H.dna.uni_identity) - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - G.fields["gender"] = H.gender - if(H.gender == "male") - G.fields["gender"] = "Male" - else if(H.gender == "female") - G.fields["gender"] = "Female" - else - G.fields["gender"] = "Other" - G.fields["photo_front"] = photo_front - G.fields["photo_side"] = photo_side - general += G - - //Medical Record - var/datum/data/record/M = new() - M.fields["id"] = id - M.fields["name"] = H.real_name - M.fields["blood_type"] = H.dna.blood_type.name - M.fields["b_dna"] = H.dna.unique_enzymes - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = H.get_trait_string(medical) - medical += M - - //Security Record - var/datum/data/record/S = new() - S.fields["id"] = id - S.fields["name"] = H.real_name - S.fields["criminal"] = "None" - S.fields["crim"] = list() - S.fields["notes"] = "No notes." - security += S - - //Locked Record - var/datum/data/record/L = new() - L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? - L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role - L.fields["age"] = H.age - L.fields["gender"] = H.gender - if(H.gender == "male") - G.fields["gender"] = "Male" - else if(H.gender == "female") - G.fields["gender"] = "Female" - else - G.fields["gender"] = "Other" - L.fields["blood_type"] = H.dna.blood_type - L.fields["b_dna"] = H.dna.unique_enzymes - L.fields["identity"] = H.dna.uni_identity - L.fields["species"] = H.dna.species.type - L.fields["features"] = H.dna.features - L.fields["image"] = image - L.fields["mindref"] = H.mind - locked += L - return - -/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C, show_directions = list(SOUTH), datum/job/J) - var/datum/preferences/P - if(!C) - C = H.client - if(C) - P = C.prefs - return get_flat_human_icon(null, J, P, DUMMY_HUMAN_SLOT_MANIFEST, show_directions) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index f52b9bdace9e..77949a931f19 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1372,7 +1372,7 @@ return ///Connect this atom to a shuttle -/atom/proc/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock) +/atom/proc/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, handheld = FALSE) return /atom/proc/disconnect_from_shuttle(obj/docking_port/mobile/port) diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 4020895f29bd..bf02f983d244 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -91,6 +91,18 @@ Medical HUD! Basic mode needs suit sensors on. //HELPERS +/mob/proc/get_datacore_key() + return + +/mob/living/carbon/human/get_datacore_key() + var/linked_datacore + var/obj/item/card/id/ID = src.get_idcard() + if(!istype(ID)) + return + if(length(ID.ship_access)) + linked_datacore = ID.ship_access[1] + return linked_datacore + //called when a carbon changes virus /mob/living/carbon/proc/check_virus() var/threat @@ -271,10 +283,10 @@ Security HUDs! Basic mode shows only the job. var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size var/perpname = get_face_name(get_id_name("")) - if(perpname && GLOB.data_core) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) + if(perpname) + var/datum/data/record/R = SSdatacore.get_record_by_name(perpname, get_datacore_key()) if(R) - switch(R.fields["criminal"]) + switch(R.fields[DATACORE_CRIMINAL_STATUS]) if("*Arrest*") holder.icon_state = "hudwanted" return diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 24f66242d58e..c91b557dbf93 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -542,10 +542,10 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( gamer.client.give_award(/datum/award/achievement/misc/gamer, gamer) // PSYCH REPORT NOTE: patient kept rambling about how they did it for an "achievement", recommend continued holding for observation gamer.mind?.adjust_experience(/datum/skill/gaming, 50) // cheevos make u better - if(!isnull(GLOB.data_core.general)) - for(var/datum/data/record/R in GLOB.data_core.general) - if(R.fields["name"] == gamer.name) - R.fields["m_stat"] = "*Unstable*" + if(!isnull(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))) + for(var/datum/data/record/R in SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + if(R.fields[DATACORE_NAME] == gamer.name) + R.fields[DATACORE_MENTAL_HEALTH] = "*Unstable*" return /obj/machinery/computer/arcade/orion_trail/ui_interact(mob/user) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 63f9284c28ae..cb8cee14dfb3 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -180,8 +180,8 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) var/list/dat = list() if (mode == 1) // accessing crew manifest dat += "Crew Manifest:
Please use security record computer to modify entries.

" - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - dat += {"[t.fields["name"]] - [t.fields["rank"]]
"} + for(var/datum/data/record/t in sortRecord(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))) + dat += {"[t.fields[DATACORE_NAME]] - [t.fields[DATACORE_RANK]]
"} dat += "Print

Access ID modification console.
" else @@ -464,8 +464,8 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) sleep(50) var/obj/item/paper/printed_paper = new /obj/item/paper(loc) var/t1 = "Crew Manifest:
" - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - t1 += t.fields["name"] + " - " + t.fields["rank"] + "
" + for(var/datum/data/record/t in sortRecord(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))) + t1 += t.fields[DATACORE_NAME] + " - " + t.fields[DATACORE_RANK] + "
" printed_paper.add_raw_text(t1) printed_paper.name = "paper- 'Crew Manifest'" printing = null diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 3916ad0d4b00..8ec531a03a37 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -63,7 +63,7 @@ . = pod /proc/grow_clone_from_record(obj/machinery/clonepod/pod, datum/data/record/R, empty) - return pod.growclone(R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mindref"], R.fields["last_death"], R.fields["blood_type"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"], empty) + return pod.growclone(R.fields[DATACORE_NAME], R.fields["UI"], R.fields["SE"], R.fields[DATACORE_MINDREF], R.fields["last_death"], R.fields[DATACORE_BLOOD_TYPE], R.fields["mrace"], R.fields[DATACORE_DNA_FEATURES], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"], empty) /obj/machinery/computer/cloning/process() if(!(scanner && LAZYLEN(pods) && autoprocess)) @@ -73,7 +73,7 @@ scan_occupant(scanner.occupant) for(var/datum/data/record/R in records) - var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mindref"]) + var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields[DATACORE_MINDREF]) if(!pod) return @@ -83,8 +83,8 @@ var/result = grow_clone_from_record(pod, R) if(result & CLONING_SUCCESS) - temp = "[R.fields["name"]] => Cloning cycle in progress..." - log_cloning("Cloning of [key_name(R.fields["mindref"])] automatically started via autoprocess - [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].") + temp = "[R.fields[DATACORE_NAME]] => Cloning cycle in progress..." + log_cloning("Cloning of [key_name(R.fields[DATACORE_MINDREF])] automatically started via autoprocess - [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].") if(result & CLONING_DELETE_RECORD) records -= R @@ -231,7 +231,7 @@ dat += "

Current records

" dat += "<< Back

" for(var/datum/data/record/R in records) - dat += "

[R.fields["name"]]

Scan ID [R.fields["id"]] View Record" + dat += "

[R.fields[DATACORE_NAME]]

Scan ID [R.fields[DATACORE_ID]] View Record" if(3) dat += "

Selected Record

" dat += "<< Back
" @@ -240,10 +240,10 @@ dat += "Record not found." else var/body_only = active_record.fields["body_only"] - dat += "

[active_record.fields["name"]][body_only ? " - BODY-ONLY" : ""]

" - dat += "Scan ID [active_record.fields["id"]] \ - [!body_only ? "Clone" : "" ]\ - Empty Clone
" + dat += "

[active_record.fields[DATACORE_NAME]][body_only ? " - BODY-ONLY" : ""]

" + dat += "Scan ID [active_record.fields[DATACORE_ID]] \ + [!body_only ? "Clone" : "" ]\ + Empty Clone
" var/obj/item/implant/health/H = locate(active_record.fields["imp"]) @@ -269,7 +269,7 @@ var/list/L = list() if(diskette.fields["UI"]) L += "Unique Identifier" - if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"]) + if(diskette.fields["UE"] && diskette.fields[DATACORE_NAME] && diskette.fields[DATACORE_BLOOD_TYPE]) L += "Unique Enzymes" if(diskette.fields["SE"]) L += "Structural Enzymes" @@ -369,7 +369,7 @@ else if(href_list["view_rec"]) playsound(src, "terminal_type", 25, FALSE) - active_record = find_record("id", href_list["view_rec"], records) + active_record = SSdatacore.find_record(DATACORE_ID, href_list["view_rec"], records) if(active_record) menu = 3 else @@ -399,8 +399,8 @@ else if (menu == 4) - log_cloning("[key_name(usr)] deleted [key_name(active_record.fields["mindref"])]'s cloning records from [src] at [AREACOORD(src)].") - temp = "[active_record.fields["name"]] => Record deleted." + log_cloning("[key_name(usr)] deleted [key_name(active_record.fields[DATACORE_MINDREF])]'s cloning records from [src] at [AREACOORD(src)].") + temp = "[active_record.fields[DATACORE_NAME]] => Record deleted." records.Remove(active_record) active_record = null playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) @@ -432,7 +432,7 @@ if(include_se) overwrite_field_if_available(active_record, diskette, "SE") - log_cloning("[key_name(usr)] uploaded [key_name(active_record.fields["mindref"])]'s cloning records to [src] at [AREACOORD(src)] via [diskette].") + log_cloning("[key_name(usr)] uploaded [key_name(active_record.fields[DATACORE_MINDREF])]'s cloning records to [src] at [AREACOORD(src)] via [diskette].") temp = "Load successful." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) @@ -448,9 +448,9 @@ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) return - log_cloning("[key_name(usr)] added [key_name(active_record.fields["mindref"])]'s cloning records to [diskette] via [src] at [AREACOORD(src)].") + log_cloning("[key_name(usr)] added [key_name(active_record.fields[DATACORE_MINDREF])]'s cloning records to [diskette] via [src] at [AREACOORD(src)].") diskette.fields = active_record.fields.Copy() - diskette.name = "data disk - '[diskette.fields["name"]]'" + diskette.name = "data disk - '[diskette.fields[DATACORE_NAME]]'" temp = "Save successful." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) @@ -459,7 +459,7 @@ playsound(src, "terminal_type", 25, FALSE) else if (href_list["clone"]) - var/datum/data/record/C = find_record("id", href_list["clone"], records) + var/datum/data/record/C = SSdatacore.find_record(DATACORE_ID, href_list["clone"], records) var/empty = href_list["empty"] //Look for that player! They better be dead! if(C) @@ -484,16 +484,16 @@ else var/result = grow_clone_from_record(pod, C, empty) if(result & CLONING_SUCCESS) - temp = "[C.fields["name"]] => Cloning cycle in progress..." + temp = "[C.fields[DATACORE_NAME]] => Cloning cycle in progress..." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) if(active_record == C) active_record = null menu = 1 success = TRUE if(!empty) - log_cloning("[key_name(usr)] initiated cloning of [key_name(C.fields["mindref"])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].") + log_cloning("[key_name(usr)] initiated cloning of [key_name(C.fields[DATACORE_MINDREF])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].") else - log_cloning("[key_name(usr)] initiated EMPTY cloning of [key_name(C.fields["mindref"])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].") + log_cloning("[key_name(usr)] initiated EMPTY cloning of [key_name(C.fields[DATACORE_MINDREF])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].") if(result & CLONING_DELETE_RECORD) if(active_record == C) active_record = null @@ -501,7 +501,7 @@ records -= C if(!success) - temp = "[C.fields["name"]] => Initialisation failure." + temp = "[C.fields[DATACORE_NAME]] => Initialisation failure." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) else @@ -573,13 +573,13 @@ var/datum/species/rando_race = pick(GLOB.roundstart_races) R.fields["mrace"] = rando_race.type - R.fields["name"] = mob_occupant.real_name - R.fields["id"] = copytext_char(md5(mob_occupant.real_name), 2, 6) + R.fields[DATACORE_NAME] = mob_occupant.real_name + R.fields[DATACORE_ID] = copytext_char(md5(mob_occupant.real_name), 2, 6) R.fields["UE"] = dna.unique_enzymes R.fields["UI"] = dna.uni_identity R.fields["SE"] = dna.mutation_index - R.fields["blood_type"] = dna.blood_type - R.fields["features"] = dna.features + R.fields[DATACORE_BLOOD_TYPE] = dna.blood_type + R.fields[DATACORE_DNA_FEATURES] = dna.features R.fields["factions"] = mob_occupant.faction R.fields["quirks"] = list() for(var/V in mob_occupant.roundstart_quirks) @@ -593,7 +593,7 @@ R.fields["traumas"] = B.get_traumas() R.fields["bank_account"] = has_bank_account - R.fields["mindref"] = "[REF(mob_occupant.mind)]" + R.fields[DATACORE_MINDREF] = "[REF(mob_occupant.mind)]" R.fields["last_death"] = mob_occupant.stat == DEAD && mob_occupant.mind ? mob_occupant.mind.last_death : -1 R.fields["body_only"] = body_only @@ -608,9 +608,9 @@ imp.implant(mob_occupant) R.fields["imp"] = "[REF(imp)]" - var/datum/data/record/old_record = find_record("mindref", REF(mob_occupant.mind), records) + var/datum/data/record/old_record = SSdatacore.find_record("mindref", REF(mob_occupant.mind), records) if(body_only) - old_record = find_record("UE", dna.unique_enzymes, records) //Body-only records cannot be identified by mind, so we use the DNA + old_record = SSdatacore.find_record("UE", dna.unique_enzymes, records) //Body-only records cannot be identified by mind, so we use the DNA if(old_record && ((old_record.fields["UI"] != dna.uni_identity) || (!old_record.fields["body_only"]))) //Never overwrite a mind-and-body record if it exists old_record = null if(old_record) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm deleted file mode 100644 index 17c5dc2ef39c..000000000000 --- a/code/game/machinery/computer/medical.dm +++ /dev/null @@ -1,581 +0,0 @@ - - -/obj/machinery/computer/med_data//TODO:SANITY - name = "medical records console" - desc = "This can be used to check medical records." - icon_screen = "medcomp" - icon_keyboard = "med_key" - req_one_access = list(ACCESS_MEDICAL, ACCESS_FORENSICS_LOCKERS) - circuit = /obj/item/circuitboard/computer/med_data - light_color = LIGHT_COLOR_BLUE - var/rank = null - var/screen = null - var/datum/data/record/active1 - var/datum/data/record/active2 - var/temp = null - var/printing = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending - - -/obj/machinery/computer/med_data/syndie - icon_keyboard = "syndie_key" - -/obj/machinery/computer/med_data/ui_interact(mob/user) - . = ..() - if(isliving(user)) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - var/dat - if(temp) - dat = text("[temp]

Clear Screen") - else - if(authenticated) - switch(screen) - if(1) - dat += {" -Search Records -
List Records -
-
Virus Database -
Medbot Tracking -
-
Record Maintenance -
{Log Out}
-"} - if(2) - dat += {" -

- - - - -
Records:
- - - - - - - - -"} - - - if(!isnull(GLOB.data_core.general)) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general, sortBy, order)) - var/blood_type = "" - var/b_dna = "" - for(var/datum/data/record/E in GLOB.data_core.medical) - if((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - blood_type = E.fields["blood_type"] - b_dna = E.fields["b_dna"] - var/background - - if(R.fields["m_stat"] == "*Insane*" || R.fields["p_stat"] == "*Deceased*") - background = "'background-color:#990000;'" - else if(R.fields["p_stat"] == "*Unconscious*" || R.fields["m_stat"] == "*Unstable*") - background = "'background-color:#CD6500;'" - else if(R.fields["p_stat"] == "Physically Unfit" || R.fields["m_stat"] == "*Watch*") - background = "'background-color:#3BB9FF;'" - else - background = "'background-color:#4F7529;'" - - dat += text("", background, R.fields["id"], R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["fingerprint"], b_dna) - dat += text("", blood_type) - dat += text("", R.fields["p_stat"]) - dat += text("", R.fields["m_stat"]) - dat += "
NameIDFingerprints (F) | DNA UE (D)Blood TypePhysical StatusMental Status
[][]F: []
D: []
[][][]

" - dat += "
Back" - if(3) - dat += "Records Maintenance
\nBackup To Disk
\nUpload From Disk
\nDelete All Records
\n
\nBack" - if(4) - - dat += "" - if(active1 in GLOB.data_core.general) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P1 = active1.fields["photo_front"] - user << browse_rsc(P1.picture.picture_image, "photo_front") - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P2 = active1.fields["photo_side"] - user << browse_rsc(P2.picture.picture_image, "photo_side") - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - else - dat += "" - - dat += "" - if(active2 in GLOB.data_core.medical) - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" //(per disease info placed in log/comment section) - dat += "" - dat += "" - - dat += "" - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - dat += "" - counter++ - dat += "" - - dat += "" - else - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
Medical Record
Name:[active1.fields["name"]]
ID:[active1.fields["id"]]
Gender: [active1.fields["gender"]] 
Age: [active1.fields["age"]] 
Species: [active1.fields["species"]] 
Fingerprint: [active1.fields["fingerprint"]] 
Physical Status: [active1.fields["p_stat"]] 
Mental Status: [active1.fields["m_stat"]] 
General Record Lost!

Medical Data
Blood Type: [active2.fields["blood_type"]] 
DNA: [active2.fields["b_dna"]] 

Minor Disabilities:

 [active2.fields["mi_dis"]] 
Details: [active2.fields["mi_dis_d"]] 

Major Disabilities:

 [active2.fields["ma_dis"]] 
Details: [active2.fields["ma_dis_d"]] 

Allergies:

 [active2.fields["alg"]] 
Details: [active2.fields["alg_d"]] 

Current Diseases:

 [active2.fields["cdi"]] 
Details: [active2.fields["cdi_d"]] 

Important Notes:

 [active2.fields["notes"]] 

Comments/Log
[active2.fields[text("com_[]", counter)]]
Delete Entry
Add Entry

Delete Record (Medical Only)
Medical Record Lost!

New Record
Print Record
Back
" - if(5) - dat += "
Virus Database
" - for(var/Dt in typesof(/datum/disease/)) - var/datum/disease/Dis = new Dt(0) - if(istype(Dis, /datum/disease/advance)) - continue // TODO (tm): Add advance diseases to the virus database which no one uses. - if(!Dis.desc) - continue - dat += "
[Dis.name]" - dat += "
Back" - if(6) - dat += "
Medical Robot Monitor
" - dat += "Back" - dat += "
Medical Robots:" - var/bdat = null - for(var/mob/living/simple_animal/bot/medbot/M in GLOB.alive_mob_list) - if(M.virtual_z() != src.virtual_z()) - continue //only find medibots on the same z-level as the computer - var/turf/bl = get_turf(M) - if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up - bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
" - if(!bdat) - dat += "
None detected
" - else - dat += "
[bdat]" - - else - else - dat += "{Log In}" - var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400) - popup.set_content(dat) - popup.open() - -/obj/machinery/computer/med_data/Topic(href, href_list) - . = ..() - if(.) - return . - if(!(active1 in GLOB.data_core.general)) - active1 = null - if(!(active2 in GLOB.data_core.medical)) - active2 = null - - if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || isAdminGhostAI(usr)) - usr.set_machine(src) - if(href_list["temp"]) - temp = null - else if(href_list["logout"]) - authenticated = null - screen = null - active1 = null - active2 = null - playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) - else if(href_list["choice"]) - // SORTING! - if(href_list["choice"] == "Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) - else if(href_list["login"]) - var/mob/M = usr - var/obj/item/card/id/I = M.get_idcard(TRUE) - if(issilicon(M)) - active1 = null - active2 = null - authenticated = 1 - rank = "AI" - screen = 1 - else if(isAdminGhostAI(M)) - active1 = null - active2 = null - authenticated = 1 - rank = "Central Command" - screen = 1 - else if(istype(I) && check_access(I)) - active1 = null - active2 = null - authenticated = I.registered_name - rank = I.assignment - screen = 1 - else - to_chat(usr, "Unauthorized access.") - playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) - if(authenticated) - if(href_list["screen"]) - screen = text2num(href_list["screen"]) - if(screen < 1) - screen = 1 - - active1 = null - active2 = null - - else if(href_list["vir"]) - var/type = href_list["vir"] - var/datum/disease/Dis = new type(0) - var/AfS = "" - for(var/mob/M in Dis.viable_mobtypes) - AfS += " [initial(M.name)];" - temp = {"Name: [Dis.name] -
Number of stages: [Dis.max_stages] -
Spread: [Dis.spread_text] Transmission -
Possible Cure: [(Dis.cure_text||"none")] -
Affected Lifeforms:[AfS] -
-
Notes: [Dis.desc] -
-
Severity: [Dis.severity]"} - - else if(href_list["del_all"]) - temp = "Are you sure you wish to delete all records?
\n\tYes
\n\tNo
" - - else if(href_list["del_all2"]) - investigate_log("[key_name(usr)] has deleted all medical records.", INVESTIGATE_RECORDS) - GLOB.data_core.medical.Cut() - temp = "All records deleted." - - else if(href_list["field"]) - var/a1 = active1 - var/a2 = active2 - switch(href_list["field"]) - if("fingerprint") - if(active1) - var/t1 = stripped_input("Please input fingerprint hash:", "Med. records", active1.fields["fingerprint"], null) - if(!canUseMedicalRecordsConsole(usr, t1, a1)) - return - active1.fields["fingerprint"] = t1 - if("gender") - if(active1) - if(active1.fields["gender"] == "Male") - active1.fields["gender"] = "Female" - else if(active1.fields["gender"] == "Female") - active1.fields["gender"] = "Other" - else - active1.fields["gender"] = "Male" - if("age") - if(active1) - var/t1 = input("Please input age:", "Med. records", active1.fields["age"], null) as num - if(!canUseMedicalRecordsConsole(usr, t1, a1)) - return - active1.fields["age"] = t1 - if("species") - if(active1) - var/t1 = stripped_input("Please input species name", "Med. records", active1.fields["species"], null) - if(!canUseMedicalRecordsConsole(usr, t1, a1)) - return - active1.fields["species"] = t1 - if("mi_dis") - if(active2) - var/t1 = stripped_input("Please input minor disabilities list:", "Med. records", active2.fields["mi_dis"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["mi_dis"] = t1 - if("mi_dis_d") - if(active2) - var/t1 = stripped_input("Please summarize minor dis.:", "Med. records", active2.fields["mi_dis_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["mi_dis_d"] = t1 - if("ma_dis") - if(active2) - var/t1 = stripped_input("Please input major disabilities list:", "Med. records", active2.fields["ma_dis"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["ma_dis"] = t1 - if("ma_dis_d") - if(active2) - var/t1 = stripped_input("Please summarize major dis.:", "Med. records", active2.fields["ma_dis_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["ma_dis_d"] = t1 - if("alg") - if(active2) - var/t1 = stripped_input("Please state allergies:", "Med. records", active2.fields["alg"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["alg"] = t1 - if("alg_d") - if(active2) - var/t1 = stripped_input("Please summarize allergies:", "Med. records", active2.fields["alg_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["alg_d"] = t1 - if("cdi") - if(active2) - var/t1 = stripped_input("Please state diseases:", "Med. records", active2.fields["cdi"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["cdi"] = t1 - if("cdi_d") - if(active2) - var/t1 = stripped_input("Please summarize diseases:", "Med. records", active2.fields["cdi_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["cdi_d"] = t1 - if("notes") - if(active2) - var/t1 = stripped_input("Please summarize notes:", "Med. records", active2.fields["notes"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["notes"] = t1 - if("p_stat") - if(active1) - temp = "Physical Condition:
\n\t*Deceased*
\n\t*Unconscious*
\n\tActive
\n\tPhysically Unfit
" - if("m_stat") - if(active1) - temp = "Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
" - if("blood_type") - if(active2) - temp = "Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
" - if("b_dna") - if(active2) - var/t1 = stripped_input("Please input DNA hash:", "Med. records", active2.fields["b_dna"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["b_dna"] = t1 - if("show_photo_front") - if(active1) - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - P.show(usr) - if("show_photo_side") - if(active1) - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - P.show(usr) - else - - else if(href_list["p_stat"]) - if(active1) - switch(href_list["p_stat"]) - if("deceased") - active1.fields["p_stat"] = "*Deceased*" - if("unconscious") - active1.fields["p_stat"] = "*Unconscious*" - if("active") - active1.fields["p_stat"] = "Active" - if("unfit") - active1.fields["p_stat"] = "Physically Unfit" - - else if(href_list["m_stat"]) - if(active1) - switch(href_list["m_stat"]) - if("insane") - active1.fields["m_stat"] = "*Insane*" - if("unstable") - active1.fields["m_stat"] = "*Unstable*" - if("watch") - active1.fields["m_stat"] = "*Watch*" - if("stable") - active1.fields["m_stat"] = "Stable" - - - else if(href_list["blood_type"]) - if(active2) - switch(href_list["blood_type"]) - if("an") - active2.fields["blood_type"] = "A-" - if("bn") - active2.fields["blood_type"] = "B-" - if("abn") - active2.fields["blood_type"] = "AB-" - if("on") - active2.fields["blood_type"] = "O-" - if("ap") - active2.fields["blood_type"] = "A+" - if("bp") - active2.fields["blood_type"] = "B+" - if("abp") - active2.fields["blood_type"] = "AB+" - if("op") - active2.fields["blood_type"] = "O+" - - - else if(href_list["del_r"]) - if(active2) - temp = "Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
" - - else if(href_list["del_r2"]) - investigate_log("[key_name(usr)] has deleted the medical records for [active1.fields["name"]].", INVESTIGATE_RECORDS) - if(active2) - qdel(active2) - active2 = null - - else if(href_list["d_rec"]) - active1 = find_record("id", href_list["d_rec"], GLOB.data_core.general) - if(active1) - active2 = find_record("id", href_list["d_rec"], GLOB.data_core.medical) - if(!active2) - active1 = null - screen = 4 - - else if(href_list["new"]) - if((istype(active1, /datum/data/record) && !(istype(active2, /datum/data/record)))) - var/datum/data/record/R = new /datum/data/record() - R.fields["name"] = active1.fields["name"] - R.fields["id"] = active1.fields["id"] - R.name = text("Medical Record #[]", R.fields["id"]) - R.fields["blood_type"] = "Unknown" - R.fields["b_dna"] = "Unknown" - R.fields["mi_dis"] = "None" - R.fields["mi_dis_d"] = "No minor disabilities have been diagnosed." - R.fields["ma_dis"] = "None" - R.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - R.fields["alg"] = "None" - R.fields["alg_d"] = "No allergies have been detected in this patient." - R.fields["cdi"] = "None" - R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - R.fields["notes"] = "No notes." - GLOB.data_core.medical += R - active2 = R - screen = 4 - - else if(href_list["add_c"]) - if(!(active2 in GLOB.data_core.medical)) - return - var/a2 = active2 - var/t1 = stripped_multiline_input("Add Comment:", "Med. records", null, null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], []
[]", authenticated, rank, station_time_timestamp(), sector_datestamp(), t1) - - else if(href_list["del_c"]) - if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" - - else if(href_list["search"]) - var/t1 = stripped_input(usr, "Search String: (Name, DNA, or ID)", "Med. records") - if(!canUseMedicalRecordsConsole(usr, t1)) - return - active1 = null - active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in GLOB.data_core.medical) - if((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) - active2 = R - else - //Foreach continue //goto(3229) - if(!(active2)) - temp = text("Could not locate record [].", sanitize(t1)) - else - for(var/datum/data/record/E in GLOB.data_core.general) - if((E.fields["name"] == active2.fields["name"] || E.fields["id"] == active2.fields["id"])) - active1 = E - else - //Foreach continue //goto(3334) - screen = 4 - - else if(href_list["print_p"]) - if(!(printing)) - printing = 1 - GLOB.data_core.medicalPrintCount++ - playsound(loc, 'sound/items/poster_being_created.ogg', 100, TRUE) - sleep(30) - var/obj/item/paper/printed_paper = new /obj/item/paper(loc) - var/final_paper_text = "
Medical Record - (MR-[GLOB.data_core.medicalPrintCount])

" - if(active1 in GLOB.data_core.general) - final_paper_text += text("Name: [] ID: []
\nGender: []
\nAge: []
", active1.fields["name"], active1.fields["id"], active1.fields["gender"], active1.fields["age"]) - final_paper_text += "\nSpecies: [active1.fields["species"]]
" - final_paper_text += text("\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) - else - final_paper_text += "General Record Lost!
" - if(active2 in GLOB.data_core.medical) - final_paper_text += text("
\n
Medical Data

\nBlood Type: []
\nDNA: []
\n
\nMinor Disabilities: []
\nDetails: []
\n
\nMajor Disabilities: []
\nDetails: []
\n
\nAllergies: []
\nDetails: []
\n
\nCurrent Diseases: [] (per disease info placed in log/comment section)
\nDetails: []
\n
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", active2.fields["blood_type"], active2.fields["b_dna"], active2.fields["mi_dis"], active2.fields["mi_dis_d"], active2.fields["ma_dis"], active2.fields["ma_dis_d"], active2.fields["alg"], active2.fields["alg_d"], active2.fields["cdi"], active2.fields["cdi_d"], active2.fields["notes"]) - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - final_paper_text += text("[]
", active2.fields[text("com_[]", counter)]) - counter++ - printed_paper.name = text("MR-[] '[]'", GLOB.data_core.medicalPrintCount, active1.fields["name"]) - else - final_paper_text += "Medical Record Lost!
" - printed_paper.name = text("MR-[] '[]'", GLOB.data_core.medicalPrintCount, "Record Lost") - final_paper_text += "" - printed_paper.add_raw_text(final_paper_text) - printed_paper.update_appearance() - printing = null - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/med_data/emp_act(severity) - . = ..() - if(!(machine_stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) - for(var/datum/data/record/R in GLOB.data_core.medical) - if(prob(10/severity)) - switch(rand(1,6)) - if(1) - if(prob(10)) - R.fields["name"] = random_unique_lizard_name(R.fields["gender"],1) - else - R.fields["name"] = random_unique_name(R.fields["gender"],1) - if(2) - R.fields["gender"] = pick("Male", "Female", "Other") - if(3) - R.fields["age"] = rand(AGE_MIN, AGE_MAX) - if(4) - var/datum/blood_type/blood = random_blood_type() - R.fields["blood_type"] = blood.name - if(5) - R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit") - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - continue - - else if(prob(1)) - qdel(R) - continue - -/obj/machinery/computer/med_data/proc/canUseMedicalRecordsConsole(mob/user, message = 1, record1, record2) - if(user) - if(message) - if(authenticated) - if(user.canUseTopic(src, !issilicon(user))) - if(!record1 || record1 == active1) - if(!record2 || record2 == active2) - return 1 - return 0 - -/obj/machinery/computer/med_data/laptop - name = "medical laptop" - desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table." - icon_state = "laptop" - icon_screen = "medlaptop" - icon_keyboard = "laptop_key" - pass_flags = PASSTABLE - unique_icon = TRUE diff --git a/code/game/machinery/computer/prisoner/gulag_teleporter.dm b/code/game/machinery/computer/prisoner/gulag_teleporter.dm deleted file mode 100644 index f05ab6b8dea9..000000000000 --- a/code/game/machinery/computer/prisoner/gulag_teleporter.dm +++ /dev/null @@ -1,154 +0,0 @@ -//computer that handle the points and teleports the prisoner -/obj/machinery/computer/prisoner/gulag_teleporter_computer - name = "labor camp teleporter console" - desc = "Used to send criminals to the Labor Camp." - icon_screen = "explosive" - icon_keyboard = "security_key" - req_access = list(ACCESS_ARMORY) - circuit = /obj/item/circuitboard/computer/gulag_teleporter_console - light_color = COLOR_SOFT_RED - - var/default_goal = 200 - var/obj/machinery/gulag_teleporter/teleporter = null - var/obj/structure/gulag_beacon/beacon = null - var/mob/living/carbon/human/prisoner = null - var/datum/data/record/temporary_record = null - - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/Initialize() - . = ..() - scan_machinery() - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "GulagTeleporterConsole", name) - ui.open() - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_data(mob/user) - var/list/data = list() - - var/list/prisoner_list = list() - var/can_teleport = FALSE - - if(teleporter && (teleporter.occupant && ishuman(teleporter.occupant))) - prisoner = teleporter.occupant - prisoner_list["name"] = prisoner.real_name - if(contained_id) - can_teleport = TRUE - if(!isnull(GLOB.data_core.general)) - for(var/r in GLOB.data_core.security) - var/datum/data/record/R = r - if(R.fields["name"] == prisoner_list["name"]) - temporary_record = R - prisoner_list["crimstat"] = temporary_record.fields["criminal"] - - data["prisoner"] = prisoner_list - - if(teleporter) - data["teleporter"] = teleporter - data["teleporter_location"] = "([teleporter.x], [teleporter.y], [teleporter.virtual_z()])" - data["teleporter_lock"] = teleporter.locked - data["teleporter_state_open"] = teleporter.state_open - else - data["teleporter"] = null - if(beacon) - data["beacon"] = beacon - data["beacon_location"] = "([beacon.x], [beacon.y], [beacon.virtual_z()])" - else - data["beacon"] = null - if(contained_id) - data["id"] = contained_id - data["id_name"] = contained_id.registered_name - data["goal"] = contained_id.goal - else - data["id"] = null - data["can_teleport"] = can_teleport - - return data - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_act(action, list/params) - . = ..() - if(.) - return - if(isliving(usr)) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - if(!allowed(usr)) - to_chat(usr, "Access denied.") - return - switch(action) - if("scan_teleporter") - teleporter = findteleporter() - return TRUE - if("scan_beacon") - beacon = findbeacon() - return TRUE - if("handle_id") - if(contained_id) - id_eject(usr) - else - id_insert(usr) - return TRUE - if("set_goal") - var/new_goal = text2num(params["value"]) - if(!isnum(new_goal)) - return - if(!new_goal) - new_goal = default_goal - contained_id.goal = clamp(new_goal, 0, 1000) //maximum 1000 points - return TRUE - if("toggle_open") - if(teleporter.locked) - to_chat(usr, "The teleporter must be unlocked first.") - return - teleporter.toggle_open() - return TRUE - if("teleporter_lock") - if(teleporter.state_open) - to_chat(usr, "The teleporter must be closed first.") - return - teleporter.locked = !teleporter.locked - return TRUE - if("teleport") - if(!teleporter || !beacon) - return - addtimer(CALLBACK(src, PROC_REF(teleport), usr), 5) - return TRUE - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/scan_machinery() - teleporter = findteleporter() - beacon = findbeacon() - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/findteleporter() - var/obj/machinery/gulag_teleporter/teleporterf = null - - for(var/direction in GLOB.cardinals) - teleporterf = locate(/obj/machinery/gulag_teleporter, get_step(src, direction)) - if(teleporterf?.is_operational) - return teleporterf - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/findbeacon() - return locate(/obj/structure/gulag_beacon) - -/obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/teleport(mob/user) - if(!contained_id) //incase the ID was removed after the transfer timer was set. - say("Warning: Unable to transfer prisoner without a valid Prisoner ID inserted!") - return - var/id_goal_not_set - if(!contained_id.goal) - id_goal_not_set = TRUE - contained_id.goal = default_goal - say("[contained_id]'s ID card goal defaulting to [contained_id.goal] points.") - log_game("[key_name(user)] teleported [key_name(prisoner)] to the Labor Camp [COORD(beacon)] for [id_goal_not_set ? "default goal of ":""][contained_id.goal] points.") - teleporter.handle_prisoner(contained_id, temporary_record) - playsound(src, 'sound/weapons/emitter.ogg', 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - prisoner.forceMove(get_turf(beacon)) - prisoner.Paralyze(40) // small travel dizziness - to_chat(prisoner, "The teleportation makes you a little dizzy.") - new /obj/effect/particle_effect/sparks(get_turf(prisoner)) - playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - if(teleporter.locked) - teleporter.locked = FALSE - teleporter.toggle_open() - contained_id = null - temporary_record = null diff --git a/code/game/machinery/computer/record/medical.dm b/code/game/machinery/computer/record/medical.dm new file mode 100644 index 000000000000..959a24556981 --- /dev/null +++ b/code/game/machinery/computer/record/medical.dm @@ -0,0 +1,133 @@ + + +/obj/machinery/computer/records/med//TODO:SANITY + name = "medical records console" + desc = "This can be used to check medical records." + icon_screen = "medcomp" + icon_keyboard = "med_key" + req_one_access = list(ACCESS_MEDICAL, ACCESS_FORENSICS_LOCKERS) + circuit = /obj/item/circuitboard/computer/med_data + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/records/med/ui_interact(mob/user, datum/tgui/ui) + . = ..() + if(.) + return + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "MedicalRecords") + ui.set_autoupdate(FALSE) + ui.open() + +/obj/machinery/computer/records/med/ui_data(mob/user) + var/list/data = ..() + + var/list/records = list() + if(linked_ship) + for(var/datum/data/record/target in SSdatacore.get_records(linked_ship)) + var/list/notes = list() + for(var/datum/medical_note/note in target.fields[DATACORE_NOTES_MEDICAL]) + notes += list(list( + author = note.author, + content = note.content, + note_ref = REF(note), + time = note.time, + )) + records += list(list( + record_ref = REF(target), + rank = target.fields[DATACORE_RANK], + age = target.fields[DATACORE_AGE], + name = target.fields[DATACORE_NAME], + gender = target.fields[DATACORE_GENDER], + species = target.fields[DATACORE_SPECIES], + physical_status = target.fields[DATACORE_PHYSICAL_HEALTH], + mental_status = target.fields[DATACORE_MENTAL_HEALTH], + blood_type = target.fields[DATACORE_BLOOD_TYPE], + dna = target.fields[DATACORE_BLOOD_DNA], + notes = notes, + )) + + data["records"] = records + + return data + +/obj/machinery/computer/records/med/ui_static_data(mob/user) + var/list/data = list() + data["min_age"] = AGE_MIN + data["max_age"] = AGE_MAX + data["physical_statuses"] = PHYSICAL_STATUSES + data["mental_statuses"] = MENTAL_STATUSES + return data + +/obj/machinery/computer/records/med/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + //var/mob/user = ui.user + + var/datum/data/record/target + if(params["record_ref"]) + target = locate(params["record_ref"]) in SSdatacore.get_records(linked_ship) + + if(!target) + return FALSE + + switch(action) + if("add_note") + if(!params["content"]) + return FALSE + var/content = trim(params["content"], MAX_MESSAGE_LEN) + + var/datum/medical_note/new_note = new(usr.name, content) + while(length(target.fields[DATACORE_NOTES_MEDICAL]) > 5) + var/list/medical_notes = target.fields[DATACORE_NOTES_MEDICAL] + medical_notes.Cut(1, 2) + target.fields[DATACORE_NOTES_MEDICAL] = medical_notes + + target.fields[DATACORE_NOTES_MEDICAL] += new_note + + return TRUE + + if("delete_note") + var/datum/medical_note/old_note = locate(params["note_ref"]) in target.fields[DATACORE_NOTES_MEDICAL] + if(!old_note) + return FALSE + + target.fields[DATACORE_NOTES_MEDICAL] -= old_note + qdel(old_note) + + return TRUE + + if("set_physical_status") + var/physical_status = params["physical_status"] + if(!physical_status || !(physical_status in PHYSICAL_STATUSES)) + return FALSE + + target.fields[DATACORE_PHYSICAL_HEALTH] = physical_status + + return TRUE + + if("set_mental_status") + var/mental_status = params["mental_status"] + if(!mental_status || !(mental_status in MENTAL_STATUSES)) + return FALSE + + target.fields[DATACORE_MENTAL_HEALTH] = mental_status + + return TRUE + + return FALSE + +/obj/machinery/computer/records/med/syndie + icon_keyboard = "syndie_key" + +/obj/machinery/computer/records/med/laptop + name = "medical laptop" + desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table." + icon_state = "laptop" + icon_screen = "medlaptop" + icon_keyboard = "laptop_key" + pass_flags = PASSTABLE + unique_icon = TRUE + diff --git a/code/game/machinery/computer/record/records.dm b/code/game/machinery/computer/record/records.dm new file mode 100644 index 000000000000..bd4ccd483e5a --- /dev/null +++ b/code/game/machinery/computer/record/records.dm @@ -0,0 +1,164 @@ +/obj/machinery/computer/records + name = "records console" + desc = "This can be used to check records." + icon_screen = "medcomp" + icon_keyboard = "med_key" + req_one_access = list() + circuit = /obj/item/circuitboard/computer + var/datum/overmap/ship/controlled/linked_ship + +/obj/machinery/computer/records/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock) + . = ..() + linked_ship = port.current_ship + +/obj/machinery/computer/records/disconnect_from_shuttle(obj/docking_port/mobile/port) + . = ..() + linked_ship = null + +/* +/obj/machinery/computer/records/attacked_by(obj/item/attacking_item, mob/living/user) + . = ..() + if(!istype(attacking_item, /obj/item/photo)) + return + insert_new_record(user, attacking_item) +*/ + +/obj/machinery/computer/records/ui_data(mob/user) + var/list/data = ..() + + var/has_access = (authenticated && isliving(user)) || isAdminGhostAI(user) + data["authenticated"] = has_access + data["library_name"] = linked_ship.name + if(!has_access) + return data + + return data + +/obj/machinery/computer/records/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + var/mob/user = ui.user + + var/datum/data/record/target + if(params["record_ref"]) + target = locate(params["record_ref"]) in SSdatacore.get_records(linked_ship) + + switch(action) + if("expunge_record") + if(!target) + return FALSE + + expunge_record_info(target) + balloon_alert(user, "record expunged") + investigate_log("[key_name(user)] expunged the record of [target[DATACORE_NAME]].", INVESTIGATE_RECORDS) + return TRUE + + if("purge_records") + SSdatacore.wipe_records(linked_ship) + return TRUE + + if("new_record") + var/name = stripped_input(user, "Enter the name of the new record.", "New Record", "", MAX_NAME_LEN) + if(!name) + return FALSE + + SSdatacore.create_record(linked_ship, name) + balloon_alert(user, "record created") + return TRUE + + if("login") + authenticated = secure_login(usr) + investigate_log("[key_name(usr)] [authenticated ? "successfully logged" : "failed to log"] into the [src].", INVESTIGATE_RECORDS) + return TRUE + + if("logout") + balloon_alert(usr, "logged out") + playsound(src, 'sound/machines/terminal_off.ogg', 70, TRUE) + authenticated = FALSE + + return TRUE + + if("edit_field") + target = locate(params["ref"]) in SSdatacore.get_records(linked_ship) + var/field = params["field"] + if(!field || !(field in target.fields)) + return FALSE + + var/value = trim(params["value"], MAX_BROADCAST_LEN) + investigate_log("[key_name(usr)] changed the field: \"[field]\" with value: \"[target.fields[field]]\" to new value: \"[value || "Unknown"]\"", INVESTIGATE_RECORDS) + target.fields[field] = value || "Unknown" + + return TRUE + + if("view_record") + if(!target) + return FALSE + + playsound(src, "sound/machines/terminal_button0[rand(1, 8)].ogg", 50, TRUE) + balloon_alert(usr, "viewing record for [target.fields[DATACORE_NAME]]") + return TRUE + + return FALSE + +/obj/machinery/computer/records/proc/secure_login(mob/user) + if(!is_operational) + return FALSE + + if(!allowed(user)) + balloon_alert(user, "access denied") + return FALSE + + balloon_alert(user, "logged in") + playsound(src, 'sound/machines/terminal_on.ogg', 70, TRUE) + + return TRUE + +/// Deletes medical information from a record. +/obj/machinery/computer/records/proc/expunge_record_info(datum/data/record/target) + if(!target) + return FALSE + + target.fields[DATACORE_NAME] = "Unknown" + target.fields[DATACORE_AGE] = 18 + target.fields[DATACORE_GENDER] = "Unknown" + target.fields[DATACORE_SPECIES] = "Unknown" + target.fields[DATACORE_BLOOD_TYPE] = pick(list("A+", "A-", "B+", "B-", "O+", "O-", "AB+", "AB-")) + target.fields[DATACORE_BLOOD_DNA] = "Unknown" + target.fields[DATACORE_DISABILITIES] = "" + target.fields[DATACORE_DISABILITIES_DETAILS] = "" + target.fields[DATACORE_PHYSICAL_HEALTH] = "" + target.fields[DATACORE_MENTAL_HEALTH] = "" + target.fields[DATACORE_RANK] = "Unknown" + + return TRUE + +/* +/obj/machinery/computer/records/proc/insert_new_record(mob/user, obj/item/photo/mugshot) + if(!mugshot || !is_operational) + return FALSE + + if(!authenticated && !allowed(user)) + balloon_alert(user, "access denied") + playsound(src, 'sound/machines/terminal_error.ogg', 70, TRUE) + return FALSE + + if(mugshot.picture.psize_x > world.icon_size || mugshot.picture.psize_y > world.icon_size) + balloon_alert(user, "photo too large!") + playsound(src, 'sound/machines/terminal_error.ogg', 70, TRUE) + return FALSE + + var/trimmed = copytext(mugshot.name, 9, MAX_NAME_LEN) // Remove "photo - " + var/name = stripped_input(user, "Enter the name of the new record.", "New Record", trimmed, MAX_NAME_LEN) + if(!name || !is_operational || !mugshot || QDELETED(mugshot) || QDELETED(src)) + return FALSE + + var/datum/data/record/new_record = SSdatacore.create_record(linked_ship, name) + new_record.fields[DATACORE_APPEARANCE] = mugshot.picture.picture_image + balloon_alert(user, "record created") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 70, TRUE) + + qdel(mugshot) + + return TRUE +*/ diff --git a/code/game/machinery/computer/record/security.dm b/code/game/machinery/computer/record/security.dm new file mode 100644 index 000000000000..29d8f9e2164d --- /dev/null +++ b/code/game/machinery/computer/record/security.dm @@ -0,0 +1,114 @@ +/obj/machinery/computer/records/sec//TODO:SANITY + name = "security records console" + desc = "Used to view and edit personnel's security records." + icon_screen = "security" + icon_keyboard = "security_key" + req_one_access = list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS) + circuit = /obj/item/circuitboard/computer/secure_data + light_color = COLOR_SOFT_RED + +/obj/machinery/computer/records/sec/ui_interact(mob/user, datum/tgui/ui) + . = ..() + if(.) + return + ui = SStgui.try_update_ui(user, src, ui) + if (!ui) + ui = new(user, src, "SecurityRecords") + ui.set_autoupdate(FALSE) + ui.open() + +/obj/machinery/computer/records/sec/ui_data(mob/user) + var/list/data = ..() + + data["current_user"] = user.name + + var/list/records = list() + for(var/datum/data/record/target in SSdatacore.get_records(linked_ship)) + var/list/crimes = list() + for(var/datum/data/crime/crime in target.fields[DATACORE_CRIMES]) + crimes += list(list( + author = crime.author, + crime_ref = REF(crime), + details = crime.crimeDetails, + name = crime.crimeName, + time = crime.time, + )) + records += list(list( + age = target.fields[DATACORE_AGE], + record_ref = REF(target), + fingerprint = target.fields[DATACORE_FINGERPRINT], + gender = target.fields[DATACORE_GENDER], + name = target.fields[DATACORE_NAME], + rank = target.fields[DATACORE_RANK], + species = target.fields[DATACORE_SPECIES], + wanted_status = target.fields[DATACORE_CRIMINAL_STATUS], + security_note = target.fields[DATACORE_NOTES_SECURITY], + )) + + data["records"] = records + + return data + +/obj/machinery/computer/records/sec/ui_static_data(mob/user) + var/list/data = list() + data["min_age"] = AGE_MIN + data["max_age"] = AGE_MAX + data["available_statuses"] = WANTED_STATUSES + return data + +/obj/machinery/computer/records/sec/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return + + var/mob/user = ui.user + + var/datum/data/record/target + if(params["record_ref"]) + target = locate(params["record_ref"]) in SSdatacore.get_records(linked_ship) + + if(!target) + return FALSE + + switch(action) + if("add_crime") + //add_crime(user, target, params) + return TRUE + + if("edit_crime") + //edit_crime(user, target, params) + return TRUE + + if("invalidate_crime") + //invalidate_crime(user, target, params) + return TRUE + + if("set_note") + var/note = trim(params["security_note"], MAX_MESSAGE_LEN) + investigate_log("[user] has changed the security note of record: \"[target]\" from \"[target.fields[DATACORE_NOTES_SECURITY]]\" to \"[note]\".") + target.fields[DATACORE_NOTES_SECURITY] = note + return TRUE + + if("set_wanted_status") + var/wanted_status = params["wanted_status"] + if(!wanted_status || !(wanted_status in WANTED_STATUSES)) + return FALSE + + investigate_log("[target.name] has been set from [target.fields[DATACORE_CRIMINAL_STATUS]] to [wanted_status] by [key_name(usr)].", INVESTIGATE_RECORDS) + target.fields[DATACORE_CRIMINAL_STATUS] = wanted_status + + return TRUE + + return FALSE + +/obj/machinery/computer/records/sec/syndie + icon_keyboard = "syndie_key" + +/obj/machinery/computer/records/sec/laptop + name = "security laptop" + desc = "A cheap Nanotrasen security laptop, it functions as a security records console. It's bolted to the table." + icon_state = "laptop" + icon_screen = "seclaptop" + icon_keyboard = "laptop_key" + pass_flags = PASSTABLE + unique_icon = TRUE diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm deleted file mode 100644 index 37759d04b13e..000000000000 --- a/code/game/machinery/computer/security.dm +++ /dev/null @@ -1,783 +0,0 @@ -/obj/machinery/computer/secure_data//TODO:SANITY - name = "security records console" - desc = "Used to view and edit personnel's security records." - icon_screen = "security" - icon_keyboard = "security_key" - req_one_access = list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS) - circuit = /obj/item/circuitboard/computer/secure_data - light_color = COLOR_SOFT_RED - var/rank = null - var/screen = null - var/datum/data/record/active1 = null - var/datum/data/record/active2 = null - var/temp = null - var/printing = null - var/can_change_id = 0 - var/list/Perp - var/tempname = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending - - -/obj/machinery/computer/secure_data/syndie - icon_keyboard = "syndie_key" - -/obj/machinery/computer/secure_data/laptop - name = "security laptop" - desc = "A cheap Nanotrasen security laptop, it functions as a security records console. It's bolted to the table." - icon_state = "laptop" - icon_screen = "seclaptop" - icon_keyboard = "laptop_key" - pass_flags = PASSTABLE - unique_icon = TRUE - -//Someone needs to break down the dat += into chunks instead of long ass lines. -/obj/machinery/computer/secure_data/ui_interact(mob/user) - . = ..() - if(isliving(user)) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - if(src.z > 6) - to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") - return - var/dat - - if(temp) - dat = "[temp]

Clear Screen" - else - dat = "" - if(authenticated) - switch(screen) - if(1) - - //body tag start + onload and onkeypress (onkeyup) javascript event calls - dat += "" - //search bar javascript - dat += {" - - - - - - - - "} - dat += {" -

"} - dat += "New Record
" - //search bar - dat += {" - - - - -
- Search: -
- "} - dat += {" -

- - - - -
Records:
- - - - - - - - - -"} - if(!isnull(GLOB.data_core.general)) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general, sortBy, order)) - var/crimstat = "" - for(var/datum/data/record/E in GLOB.data_core.security) - if((E.fields["name"] == R.fields["name"]) && (E.fields["id"] == R.fields["id"])) - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#990000;'" - if("Incarcerated") - background = "'background-color:#CD6500;'" - if("Paroled") - background = "'background-color:#CD6500;'" - if("Discharged") - background = "'background-color:#006699;'" - if("None") - background = "'background-color:#4F7529;'" - if("") - background = "''" //"'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += "" - dat += text("", R.fields["name"], R.fields["id"], R.fields["rank"], R.fields["fingerprint"], R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += {" -
NameIDRankFingerprintsCriminal Status
[][][][][]
- -
"} - dat += "Record Maintenance

" - dat += "{Log Out}" - if(2) - dat += "Records Maintenance
" - dat += "
Delete All Records

Back" - if(3) - dat += "Security Record
" - if(istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P1 = active1.fields["photo_front"] - user << browse_rsc(P1.picture.picture_image, "photo_front") - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P2 = active1.fields["photo_side"] - user << browse_rsc(P2.picture.picture_image, "photo_side") - dat += {" -
- - - - "} - dat += "" - dat += {" - - - -
Name: [active1.fields["name"]] 
ID: [active1.fields["id"]] 
Gender: [active1.fields["gender"]] 
Age: [active1.fields["age"]] 
Species: [active1.fields["species"]] 
Rank: [active1.fields["rank"]] 
Fingerprint: [active1.fields["fingerprint"]] 
Physical Status: [active1.fields["p_stat"]] 
Mental Status: [active1.fields["m_stat"]] 
-

- Print photo
- Update front photo

- Print photo
- Update side photo
-
"} - else - dat += "
General Record Lost!
" - if((istype(active2, /datum/data/record) && GLOB.data_core.security.Find(active2))) - dat += "Security Data" - dat += "
Criminal Status: [active2.fields["criminal"]]" - - dat += "

Crimes: Add New" - - dat +={" - - - - - - - "} - for(var/datum/data/crime/c in active2.fields["crim"]) - dat += "" - if(!c.crimeDetails) - dat += "" - else - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
CrimeDetailsAuthorTime AddedDel
[c.crimeName]\[+\][c.crimeDetails][c.author][c.time]\[X\]
" - - dat += "
\nImportant Notes:
\n\t [active2.fields["notes"]] " - dat += "

Comments/Log
" - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - dat += (active2.fields[text("com_[]", counter)] + "
") - if(active2.fields[text("com_[]", counter)] != "Deleted") - dat += text("Delete Entry

", counter) - counter++ - dat += "Add Entry

" - dat += "Delete Record (Security Only)
" - else - dat += "Security Record Lost!
" - dat += "New Security Record

" - dat += "Delete Record (ALL)
Print Record
Print Wanted Poster
Print Missing Persons Poster
Back

" - dat += "{Log Out}" - else - else - dat += "{Log In}" - var/datum/browser/popup = new(user, "secure_rec", "Security Records Console", 600, 400) - popup.set_content(dat) - popup.open() - return - -/*Revised /N -I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. -What a mess.*/ -/obj/machinery/computer/secure_data/Topic(href, href_list) - . = ..() - if(.) - return . - if(!(GLOB.data_core.general.Find(active1))) - active1 = null - if(!(GLOB.data_core.security.Find(active2))) - active2 = null - if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || isAdminGhostAI(usr)) - usr.set_machine(src) - switch(href_list["choice"]) -// SORTING! - if("Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) -//BASIC FUNCTIONS - if("Clear Screen") - temp = null - - if("Return") - screen = 1 - active1 = null - active2 = null - - if("Log Out") - authenticated = null - screen = null - active1 = null - active2 = null - playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) - - if("Log In") - var/mob/M = usr - var/obj/item/card/id/I = M.get_idcard(TRUE) - if(issilicon(M)) - var/mob/living/silicon/borg = M - active1 = null - active2 = null - authenticated = borg.name - rank = "AI" - screen = 1 - else if(isAdminGhostAI(M)) - active1 = null - active2 = null - authenticated = M.client.holder.admin_signature - rank = "Central Command" - screen = 1 - else if(I && check_access(I)) - active1 = null - active2 = null - authenticated = I.registered_name - rank = I.assignment - screen = 1 - else - to_chat(usr, "Unauthorized Access.") - playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) - -//RECORD FUNCTIONS - if("Record Maintenance") - screen = 2 - active1 = null - active2 = null - - if("Browse Record") - var/datum/data/record/R = locate(href_list["d_rec"]) in GLOB.data_core.general - if(!R) - temp = "Record Not Found!" - else - active1 = active2 = R - for(var/datum/data/record/E in GLOB.data_core.security) - if((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - active2 = E - screen = 3 - - if("Print Record") - if(!(printing)) - printing = 1 - GLOB.data_core.securityPrintCount++ - playsound(loc, 'sound/items/poster_being_created.ogg', 100, TRUE) - sleep(30) - var/obj/item/paper/printed_paper = new /obj/item/paper(loc) - var/final_paper_text = "
Security Record - (SR-[GLOB.data_core.securityPrintCount])

" - if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1))) - final_paper_text += text("Name: [] ID: []
\nGender: []
\nAge: []
", active1.fields["name"], active1.fields["id"], active1.fields["gender"], active1.fields["age"]) - final_paper_text += "\nSpecies: [active1.fields["species"]]
" - final_paper_text += text("\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) - else - final_paper_text += "General Record Lost!
" - if((istype(active2, /datum/data/record) && GLOB.data_core.security.Find(active2))) - final_paper_text += text("
\n
Security Data

\nCriminal Status: []", active2.fields["criminal"]) - - final_paper_text += "
\n
\nCrimes:
\n" - final_paper_text +={" - - - - - -"} - for(var/datum/data/crime/c in active2.fields["crim"]) - final_paper_text += "" - final_paper_text += "" - final_paper_text += "" - final_paper_text += "" - final_paper_text += "" - final_paper_text += "
CrimeDetailsAuthorTime Added
[c.crimeName][c.crimeDetails][c.author][c.time]
" - - final_paper_text += text("
\nImportant Notes:
\n\t[]
\n
\n
Comments/Log

", active2.fields["notes"]) - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - final_paper_text += text("[]
", active2.fields[text("com_[]", counter)]) - counter++ - printed_paper.name = text("SR-[] '[]'", GLOB.data_core.securityPrintCount, active1.fields["name"]) - else - final_paper_text += "Security Record Lost!
" - printed_paper.name = text("SR-[] '[]'", GLOB.data_core.securityPrintCount, "Record Lost") - final_paper_text += "" - printed_paper.add_raw_text(final_paper_text) - printed_paper.update_appearance() - printing = null - if("Print Poster") - if(!(printing)) - var/wanted_name = stripped_input(usr, "Please enter an alias for the criminal:", "Print Wanted Poster", active1.fields["name"]) - if(wanted_name) - var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Nanotrasen. Report any sightings to security immediately." - var/list/crimes = active2.fields["crim"] - if(crimes.len) - default_description += "\n[wanted_name] is wanted for the following crimes:\n" - for(var/datum/data/crime/c in active2.fields["crim"]) - default_description += "\n[c.crimeName]\n" - default_description += "[c.crimeDetails]\n" - - var/headerText = stripped_input(usr, "Please enter Poster Heading (Max 7 Chars):", "Print Wanted Poster", "WANTED", 8) - - var/info = stripped_multiline_input(usr, "Please input a description for the poster:", "Print Wanted Poster", default_description, null) - if(info) - playsound(loc, 'sound/items/poster_being_created.ogg', 100, TRUE) - printing = 1 - sleep(30) - if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))//make sure the record still exists. - var/obj/item/photo/photo = active1.fields["photo_front"] - new /obj/item/poster/wanted(loc, photo.picture.picture_image, wanted_name, info, headerText) - printing = 0 - if("Print Missing") - if(!(printing)) - var/missing_name = stripped_input(usr, "Please enter an alias for the missing person:", "Print Missing Persons Poster", active1.fields["name"]) - if(missing_name) - var/default_description = "A poster declaring [missing_name] to be a missing individual, missed by Nanotrasen. Report any sightings to security immediately." - - var/headerText = stripped_input(usr, "Please enter Poster Heading (Max 7 Chars):", "Print Missing Persons Poster", "MISSING", 8) - - var/info = stripped_multiline_input(usr, "Please input a description for the poster:", "Print Missing Persons Poster", default_description, null) - if(info) - playsound(loc, 'sound/items/poster_being_created.ogg', 100, TRUE) - printing = 1 - sleep(30) - if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))//make sure the record still exists. - var/obj/item/photo/photo = active1.fields["photo_front"] - new /obj/item/poster/wanted/missing(loc, photo.picture.picture_image, missing_name, info, headerText) - printing = 0 - -//RECORD DELETE - if("Delete All Records") - temp = "" - temp += "Are you sure you wish to delete all Security records?
" - temp += "Yes
" - temp += "No" - - if("Purge All Records") - investigate_log("[key_name(usr)] has purged all the security records.", INVESTIGATE_RECORDS) - for(var/datum/data/record/R in GLOB.data_core.security) - qdel(R) - GLOB.data_core.security.Cut() - temp = "All Security records deleted." - - if("Add Entry") - if(!(istype(active2, /datum/data/record))) - return - var/a2 = active2 - var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], []
[]", src.authenticated, src.rank, station_time_timestamp(), sector_datestamp(shortened = TRUE), t1) - - if("Delete Record (ALL)") - if(active1) - temp = "
Are you sure you wish to delete the record (ALL)?
" - temp += "Yes
" - temp += "No" - - if("Delete Record (Security)") - if(active2) - temp = "
Are you sure you wish to delete the record (Security Portion Only)?
" - temp += "Yes
" - temp += "No" - - if("Delete Entry") - if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" -//RECORD CREATE - if("New Record (Security)") - if((istype(active1, /datum/data/record) && !(istype(active2, /datum/data/record)))) - var/datum/data/record/R = new /datum/data/record() - R.fields["name"] = active1.fields["name"] - R.fields["id"] = active1.fields["id"] - R.name = text("Security Record #[]", R.fields["id"]) - R.fields["criminal"] = "None" - R.fields["crim"] = list() - R.fields["notes"] = "No notes." - GLOB.data_core.security += R - active2 = R - screen = 3 - - if("New Record (General)") - //General Record - var/datum/data/record/G = new /datum/data/record() - G.fields["name"] = "New Record" - G.fields["id"] = "[num2hex(rand(1, 1.6777215E7), 6)]" - G.fields["rank"] = "Unassigned" - G.fields["gender"] = "Male" - G.fields["age"] = "Unknown" - G.fields["species"] = "Human" - G.fields["photo_front"] = new /icon() - G.fields["photo_side"] = new /icon() - G.fields["fingerprint"] = "?????" - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - GLOB.data_core.general += G - active1 = G - - //Security Record - var/datum/data/record/R = new /datum/data/record() - R.fields["name"] = active1.fields["name"] - R.fields["id"] = active1.fields["id"] - R.name = text("Security Record #[]", R.fields["id"]) - R.fields["criminal"] = "None" - R.fields["crim"] = list() - R.fields["notes"] = "No notes." - GLOB.data_core.security += R - active2 = R - - //Medical Record - var/datum/data/record/M = new /datum/data/record() - M.fields["id"] = active1.fields["id"] - M.fields["name"] = active1.fields["name"] - M.fields["blood_type"] = "?" - M.fields["b_dna"] = "?????" - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = "No notes." - GLOB.data_core.medical += M - - - -//FIELD FUNCTIONS - if("Edit Field") - var/a1 = active1 - var/a2 = active2 - - switch(href_list["field"]) - if("name") - if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input name:", "Secure. records", active1.fields["name"], MAX_MESSAGE_LEN) - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - if(istype(active1, /datum/data/record)) - active1.fields["name"] = t1 - if(istype(active2, /datum/data/record)) - active2.fields["name"] = t1 - if("id") - if(istype(active2, /datum/data/record) || istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input id:", "Secure. records", active1.fields["id"], null) - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - if(istype(active1, /datum/data/record)) - active1.fields["id"] = t1 - if(istype(active2, /datum/data/record)) - active2.fields["id"] = t1 - if("fingerprint") - if(istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - active1.fields["fingerprint"] = t1 - if("gender") - if(istype(active1, /datum/data/record)) - if(active1.fields["gender"] == "Male") - active1.fields["gender"] = "Female" - else if(active1.fields["gender"] == "Female") - active1.fields["gender"] = "Other" - else - active1.fields["gender"] = "Male" - if("age") - if(istype(active1, /datum/data/record)) - var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num|null - - if (!t1) - return - - if(!canUseSecurityRecordsConsole(usr, "age", a1)) - return - active1.fields["age"] = t1 - if("species") - if(istype(active1, /datum/data/record)) - var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_races - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - active1.fields["species"] = t1 - if("show_photo_front") - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - P.show(usr) - if("upd_photo_front") - var/obj/item/photo/photo = get_photo(usr) - if(photo) - qdel(active1.fields["photo_front"]) - //Lets center it to a 32x32. - var/icon/I = photo.picture.picture_image - var/w = I.Width() - var/h = I.Height() - var/dw = w - 32 - var/dh = w - 32 - I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) - active1.fields["photo_front"] = photo - if("print_photo_front") - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - print_photo(P.picture.picture_image, active1.fields["name"]) - if("show_photo_side") - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - P.show(usr) - if("upd_photo_side") - var/obj/item/photo/photo = get_photo(usr) - if(photo) - qdel(active1.fields["photo_side"]) - //Lets center it to a 32x32. - var/icon/I = photo.picture.picture_image - var/w = I.Width() - var/h = I.Height() - var/dw = w - 32 - var/dh = w - 32 - I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) - active1.fields["photo_side"] = photo - if("print_photo_side") - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - print_photo(P.picture.picture_image, active1.fields["name"]) - if("crim_add") - if(istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input crime names:", "Secure. records", "", null) - var/t2 = stripped_input(usr, "Please input crime details:", "Secure. records", "", null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, station_time_timestamp()) - GLOB.data_core.addCrime(active1.fields["id"], crime) - investigate_log("New Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) - if("crim_delete") - if(istype(active1, /datum/data/record)) - if(href_list["cdataid"]) - if(!canUseSecurityRecordsConsole(usr, "delete", null, a2)) - return - GLOB.data_core.removeCrime(active1.fields["id"],href_list["cdataid"]) - if("add_details") - if(istype(active1, /datum/data/record)) - if(href_list["cdataid"]) - var/t1 = stripped_input(usr, "Please input crime details:", "Secure. records", "", null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - GLOB.data_core.addCrimeDetails(active1.fields["id"], href_list["cdataid"], t1) - investigate_log("New Crime details: [t1] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) - if("notes") - if(istype(active2, /datum/data/record)) - var/t1 = stripped_input(usr, "Please summarize notes:", "Secure. records", active2.fields["notes"], null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - active2.fields["notes"] = t1 - if("criminal") - if(istype(active2, /datum/data/record)) - temp = "
Criminal Status:
" - temp += "" - if("rank") - var/list/L = list( "Head of Personnel", "Captain", "AI", "Central Command" ) - //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N - if((istype(active1, /datum/data/record) && L.Find(rank))) - temp = "
Rank:
" - temp += "" - else - alert(usr, "You do not have the required rank to do this!") -//TEMPORARY MENU FUNCTIONS - else//To properly clear as per clear screen. - temp=null - switch(href_list["choice"]) - if("Change Rank") - if(active1) - active1.fields["rank"] = strip_html(href_list["rank"]) - if(href_list["rank"] in get_all_jobs()) - active1.fields["real_rank"] = href_list["real_rank"] - - if("Change Criminal Status") - if(active2) - var/old_field = active2.fields["criminal"] - switch(href_list["criminal2"]) - if("none") - active2.fields["criminal"] = "None" - if("arrest") - active2.fields["criminal"] = "*Arrest*" - if("incarcerated") - active2.fields["criminal"] = "Incarcerated" - if("paroled") - active2.fields["criminal"] = "Paroled" - if("released") - active2.fields["criminal"] = "Discharged" - investigate_log("[active1.fields["name"]] has been set from [old_field] to [active2.fields["criminal"]] by [key_name(usr)].", INVESTIGATE_RECORDS) - for(var/i in GLOB.human_list) - var/mob/living/carbon/human/H = i - H.sec_hud_set_security_status() - if("Delete Record (Security) Execute") - investigate_log("[key_name(usr)] has deleted the security records for [active1.fields["name"]].", INVESTIGATE_RECORDS) - if(active2) - qdel(active2) - active2 = null - - if("Delete Record (ALL) Execute") - if(active1) - investigate_log("[key_name(usr)] has deleted all records for [active1.fields["name"]].", INVESTIGATE_RECORDS) - for(var/datum/data/record/R in GLOB.data_core.medical) - if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) - qdel(R) - break - qdel(active1) - active1 = null - - if(active2) - qdel(active2) - active2 = null - else - temp = "This function does not appear to be working at the moment. Our apologies." - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/secure_data/proc/get_photo(mob/user) - var/obj/item/photo/P = null - if(issilicon(user)) - var/mob/living/silicon/tempAI = user - var/datum/picture/selection = tempAI.GetPhoto(user) - if(selection) - P = new(null, selection) - else if(istype(user.get_active_held_item(), /obj/item/photo)) - P = user.get_active_held_item() - return P - -/obj/machinery/computer/secure_data/proc/print_photo(icon/temp, person_name) - if (printing) - return - printing = TRUE - sleep(20) - var/obj/item/photo/P = new/obj/item/photo(drop_location()) - var/datum/picture/toEmbed = new(name = person_name, desc = "The photo on file for [person_name].", image = temp) - P.set_picture(toEmbed, TRUE, TRUE) - P.pixel_x = rand(-10, 10) - P.pixel_y = rand(-10, 10) - printing = FALSE - -/obj/machinery/computer/secure_data/emp_act(severity) - . = ..() - - if(machine_stat & (BROKEN|NOPOWER) || . & EMP_PROTECT_SELF) - return - - for(var/datum/data/record/R in GLOB.data_core.security) - if(prob(10/severity)) - switch(rand(1,8)) - if(1) - if(prob(10)) - R.fields["name"] = "[pick(lizard_name(MALE),lizard_name(FEMALE))]" - else - R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]" - if(2) - R.fields["gender"] = pick("Male", "Female", "Other") - if(3) - R.fields["age"] = rand(5, 85) - if(4) - R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Paroled", "Discharged") - if(5) - R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit") - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - if(7) - R.fields["species"] = pick(GLOB.roundstart_races) - if(8) - var/datum/data/record/G = pick(GLOB.data_core.general) - R.fields["photo_front"] = G.fields["photo_front"] - R.fields["photo_side"] = G.fields["photo_side"] - continue - - else if(prob(1)) - qdel(R) - continue - -/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2) - if(user) - if(authenticated) - if(user.canUseTopic(src, !issilicon(user))) - if(!trim(message1)) - return 0 - if(!record1 || record1 == active1) - if(!record2 || record2 == active2) - return 1 - return 0 diff --git a/code/game/machinery/computer/warrant.dm b/code/game/machinery/computer/warrant.dm index a5b72e1aae40..f918bc4db2a1 100644 --- a/code/game/machinery/computer/warrant.dm +++ b/code/game/machinery/computer/warrant.dm @@ -17,7 +17,7 @@ if(current) var/background var/notice = "" - switch(current.fields["criminal"]) + switch(current.fields[DATACORE_CRIMINAL_STATUS]) if("*Arrest*") background = "background-color:#990000;" notice = "
**REPORT TO THE BRIG**" @@ -33,12 +33,12 @@ background = "''" //"'background-color:#FFFFFF;'" dat += "Warrant Data" dat += {" - - + +
Name: [current.fields["name"]] 
ID: [current.fields["id"]] 
Name: [current.fields[DATACORE_NAME]] 
ID: [current.fields[DATACORE_ID]] 
"} dat += {"Criminal Status:
- [current.fields["criminal"]][notice] + [current.fields[DATACORE_CRIMINAL_STATUS]][notice]
"} dat += "
Crimes:" @@ -49,7 +49,7 @@ Author Time Added "} - for(var/datum/data/crime/c in current.fields["crim"]) + for(var/datum/data/crime/c in current.fields[DATACORE_CRIMES]) dat += {"[c.crimeName] [c.crimeDetails] [c.author] @@ -74,8 +74,8 @@ var/obj/item/card/id/scan = M.get_idcard(TRUE) authenticated = scan.registered_name if(authenticated) - for(var/datum/data/record/R in GLOB.data_core.security) - if(R.fields["name"] == authenticated) + for(var/datum/data/record/R in SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + if(R.fields[DATACORE_NAME] == authenticated) current = R playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) if("Logout") diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 6b63a3ae83b8..830352fe657e 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -327,17 +327,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod/retro, 17) mob_occupant.mind.special_role = null // Delete them from datacore. - var/announce_rank = null - for(var/datum/data/record/R in GLOB.data_core.medical) - if((R.fields["name"] == mob_occupant.real_name)) - qdel(R) - for(var/datum/data/record/T in GLOB.data_core.security) - if((T.fields["name"] == mob_occupant.real_name)) - qdel(T) - for(var/datum/data/record/G in GLOB.data_core.general) - if((G.fields["name"] == mob_occupant.real_name)) - announce_rank = G.fields["rank"] - qdel(G) + var/announce_rank = SSdatacore.get_record_by_name(mob_occupant.real_name, DATACORE_RECORDS_OUTPOST)?[DATACORE_RANK] + SSdatacore.demanifest(mob_occupant.real_name) var/datum/overmap/ship/controlled/original_ship = mob_occupant.mind.original_ship.resolve() original_ship.manifest -= mob_occupant.real_name diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index 3632c204f36b..575ab512ebc9 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -157,7 +157,7 @@ The console is located at computer/gulag_teleporter.dm if(id) prisoner.equip_to_appropriate_slot(id) if(R) - R.fields["criminal"] = "Incarcerated" + R.fields[DATACORE_CRIMINAL_STATUS] = "Incarcerated" /obj/item/circuitboard/machine/gulag_teleporter name = "labor camp teleporter (Machine Board)" diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 3f5620c35f06..49efa36737ec 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -555,8 +555,8 @@ DEFINE_BITFIELD(turret_flags, list( if(turret_flags & TURRET_FLAG_SHOOT_CRIMINALS) //if the turret can check the records, check if they are set to *Arrest* on records var/perpname = perp.get_face_name(perp.get_id_name()) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) - if(!R || (R.fields["criminal"] == "*Arrest*")) + var/datum/data/record/R = SSdatacore.get_record_by_name(perpname, DATACORE_RECORDS_OUTPOST) + if(!R || (R.fields[DATACORE_CRIMINAL_STATUS] == "*Arrest*")) threatcount += 4 if((turret_flags & TURRET_FLAG_SHOOT_UNSHIELDED) && (!HAS_TRAIT(perp, TRAIT_MINDSHIELD))) diff --git a/code/game/machinery/scan_gate.dm b/code/game/machinery/scan_gate.dm index cf83233598aa..681058dced13 100644 --- a/code/game/machinery/scan_gate.dm +++ b/code/game/machinery/scan_gate.dm @@ -105,8 +105,8 @@ if(ishuman(M)) var/mob/living/carbon/human/H = M var/perpname = H.get_face_name(H.get_id_name()) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) - if(!R || (R.fields["criminal"] == "*Arrest*")) + var/datum/data/record/R = SSdatacore.get_record_by_name(perpname, DATACORE_RECORDS_OUTPOST) + if(!R || (R.fields[DATACORE_CRIMINAL_STATUS] == "*Arrest*")) beep = TRUE if(SCANGATE_MINDSHIELD) if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 9aece73946cc..f289ad4d35e4 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -232,7 +232,7 @@ /obj/item/circuitboard/computer/med_data name = "Medical Records Console (Computer Board)" icon_state = "medical" - build_path = /obj/machinery/computer/med_data + build_path = /obj/machinery/computer/records/med /obj/item/circuitboard/computer/operating name = "Operating Computer (Computer Board)" @@ -322,11 +322,6 @@ //Security -/obj/item/circuitboard/computer/gulag_teleporter_console - name = "Labor Camp teleporter console (Computer Board)" - icon_state = "security" - build_path = /obj/machinery/computer/prisoner/gulag_teleporter_computer - /obj/item/circuitboard/computer/prisoner name = "Prisoner Management Console (Computer Board)" icon_state = "security" @@ -335,7 +330,7 @@ /obj/item/circuitboard/computer/secure_data name = "Security Records Console (Computer Board)" icon_state = "security" - build_path = /obj/machinery/computer/secure_data + build_path = /obj/machinery/computer/records/sec /obj/item/circuitboard/computer/warrant name = "Security Warrant Viewer (Computer Board)" diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index e259e56ccd0e..3e9d8a668fe0 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -248,10 +248,6 @@ GLOBAL_LIST_EMPTY(PDAs) dat += "
  • [PDAIMG(status)] Set Status Display
  • " if(cartridge.access & CART_ENGINE) dat += "
  • [PDAIMG(power)] Power Monitor
  • " - if(cartridge.access & CART_MEDICAL) - dat += "
  • [PDAIMG(medical)] Medical Records
  • " - if(cartridge.access & CART_SECURITY) - dat += "
  • [PDAIMG(cuffs)] Security Records
  • " if(cartridge.access & CART_QUARTERMASTER) dat += "
  • [PDAIMG(crate)] Supply Records
  • " @@ -361,12 +357,6 @@ GLOBAL_LIST_EMPTY(PDAs) dat += tnote dat += "
    " - if(41) //crew manifest - dat += "

    Crew Manifest

    " - dat += "
    " - dat += SSovermap.get_manifest_html() - dat += "
    " - if(3) dat += "

    [PDAIMG(atmos)] Atmospheric Readings

    " diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 65bda2aa1f54..28a35332b334 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -231,10 +231,6 @@ Code: + +

    Send Signal
    "} - if (41) //crew manifest - menu = "

    [PDAIMG(notes)] Crew Manifest

    " - menu += "
    [SSovermap.get_manifest_html()]
    " - if (42) //status displays menu = "

    [PDAIMG(status)] Station Status Display Interlink

    " @@ -313,99 +309,6 @@ Code: menu += "" - if (44) //medical records //This thing only displays a single screen so it's hard to really get the sub-menu stuff working. - menu = "

    [PDAIMG(medical)] Medical Record List

    " - if(GLOB.data_core.general) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) - menu += "[PDAIMG(medical)] [R.fields["id"]]: [R.fields["name"]]
    " - menu += "
    " - if(441) - 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 (45) //security records - menu = "

    [PDAIMG(cuffs)] Security Record List

    " - if(GLOB.data_core.general) - for (var/datum/data/record/R in sortRecord(GLOB.data_core.general)) - menu += "[PDAIMG(cuffs)] [R.fields["id"]]: [R.fields["name"]]
    " - - menu += "
    " - if(451) - 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 (49) //janitorial locator // hey there people, so there were two in world loops here that didnt have a timer assosciated with them. // and instead of redoing this to not be actually god awful for perf and malcontent issues, I've removed it entirely. @@ -469,22 +372,6 @@ Code: 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.mode = 441 - 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.mode = 451 - if(!active3) - active1 = null - if("Send Signal") INVOKE_ASYNC(radio, TYPE_PROC_REF(/obj/item/integrated_signaler, send_activation)) diff --git a/code/modules/antagonists/traitor/equipment/contractor.dm b/code/modules/antagonists/traitor/equipment/contractor.dm index b1d68a719070..138dc8e36042 100644 --- a/code/modules/antagonists/traitor/equipment/contractor.dm +++ b/code/modules/antagonists/traitor/equipment/contractor.dm @@ -57,10 +57,6 @@ CONTRACT_PAYOUT_SMALL ) - //What the fuck - if(length(to_generate) > length(GLOB.data_core.locked)) - to_generate.Cut(1, length(GLOB.data_core.locked)) - // We don't want the sum of all the payouts to be under this amount var/lowest_TC_threshold = 30 diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm index d6bbba359303..95846e9a1a8f 100644 --- a/code/modules/antagonists/traitor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/syndicate_contract.dm @@ -20,10 +20,10 @@ var/datum/data/record/record if (contract.target) - record = find_record("name", contract.target.name, GLOB.data_core.general) + record = SSdatacore.get_record_by_name(contract.target.name, DATACORE_RECORDS_OUTPOST) if (record) - target_rank = record.fields["rank"] + target_rank = record.fields[DATACORE_RANK] else target_rank = "Unknown" diff --git a/code/modules/datacore/crime.dm b/code/modules/datacore/crime.dm new file mode 100644 index 000000000000..1028ba9818e7 --- /dev/null +++ b/code/modules/datacore/crime.dm @@ -0,0 +1,9 @@ +/datum/data/crime + name = "crime" + var/crimeName = "" + var/crimeDetails = "" + var/author = "" + var/time = "" + var/fine = 0 + var/paid = 0 + var/dataId = 0 diff --git a/code/modules/datacore/library.dm b/code/modules/datacore/library.dm new file mode 100644 index 000000000000..b2f5d0280249 --- /dev/null +++ b/code/modules/datacore/library.dm @@ -0,0 +1,21 @@ +/datum/data_library + var/list/datum/data/record/records = list() + var/list/datum/data/record/records_by_name = list() + +/// Returns a data record or null. +/datum/data_library/proc/get_record_by_name(name) + RETURN_TYPE(/datum/data/record) + + return records_by_name[name] + +/// Inject a record into this library. +/datum/data_library/proc/inject_record(datum/data/record/new_record) + if(!istype(new_record)) + CRASH("You fucked it this time!!!") + + if(!new_record.fields[DATACORE_NAME]) + CRASH("Cannot inject a record with no name!") + + records += new_record + records_by_name[new_record.fields[DATACORE_NAME]] = new_record + new_record.library = src diff --git a/code/modules/datacore/medical_note.dm b/code/modules/datacore/medical_note.dm new file mode 100644 index 000000000000..a1843394c2ae --- /dev/null +++ b/code/modules/datacore/medical_note.dm @@ -0,0 +1,15 @@ +/** + * Player-written medical note. + */ +/datum/medical_note + /// Player that wrote the note + var/author + /// Details of the note + var/content + /// Station timestamp + var/time + +/datum/medical_note/New(author = "Anonymous", content = "No details provided.") + src.author = author + src.content = content + src.time = station_time_timestamp() diff --git a/code/modules/datacore/records.dm b/code/modules/datacore/records.dm new file mode 100644 index 000000000000..ad06a81a0a9b --- /dev/null +++ b/code/modules/datacore/records.dm @@ -0,0 +1,107 @@ +/datum/data + var/name = "data" + +/datum/data/record + name = "record" + /// A ref to the library we're contained in. + var/datum/data_library/library + /// The data + var/list/fields = list() + +/datum/data/record/Destroy(force, ...) + if(library) + library.records -= src + library.records_by_name -= fields["name"] + return ..() + +/// Creates a copy of the record, without it's library. +/datum/data/record/proc/Copy() + var/datum/data/record/new_record = new type() + new_record.fields = fields.Copy() + return new_record + + +/// A helper proc to get the front photo of a character from the record. +/// Handles calling `get_photo()`, read its documentation for more information. +/datum/data/record/proc/get_front_photo() + return get_photo("photo_front", SOUTH) + +/// A helper proc to get the side photo of a character from the record. +/// Handles calling `get_photo()`, read its documentation for more information. +/datum/data/record/proc/get_side_photo() + return get_photo("photo_side", WEST) + + +/** + * You shouldn't be calling this directly, use `get_front_photo()` or `get_side_photo()` + * instead. + * + * This is the proc that handles either fetching (if it was already generated before) or + * generating (if it wasn't) the specified photo from the specified record. This is only + * intended to be used by records that used to try to access `fields["photo_front"]` or + * `fields["photo_side"]`, and will return an empty icon if there isn't any of the necessary + * fields. + * + * Arguments: + * * field_name - The name of the key in the `fields` list, of the record itself. + * * orientation - The direction in which you want the character appearance to be rotated + * in the outputed photo. + * + * Returns an empty `/icon` if there was no `character_appearance` entry in the `fields` list, + * returns the generated/cached photo otherwise. + */ +/datum/data/record/proc/get_photo(field_name, orientation) + if(!field_name) + return + + if(!fields[DATACORE_APPEARANCE]) + return new /icon() + + var/mutable_appearance/character_appearance = fields[DATACORE_APPEARANCE] + + var/icon/picture_image + if(!isicon(character_appearance)) + var/mutable_appearance/appearance = character_appearance + appearance.setDir(orientation) + picture_image = getFlatIcon(appearance) + else + picture_image = character_appearance + + var/datum/picture/picture = new + picture.picture_name = "[fields[DATACORE_NAME]]" + picture.picture_desc = "This is [fields[DATACORE_NAME]]." + picture.picture_image = picture_image + + var/obj/item/photo/photo = new(null, picture) + fields[field_name] = photo + return photo + +/// Set the criminal status of a crew member in the security records. +/datum/data/record/proc/set_criminal_status(new_status) + var/old_status = DATACORE_CRIMINAL_STATUS + if(old_status == new_status) + return FALSE + + fields[DATACORE_CRIMINAL_STATUS] = new_status + return TRUE + +/datum/data/record/proc/add_crime(datum/data/crime/crime) + fields[DATACORE_CRIMES] |= crime + +/datum/data/record/proc/remove_crime(cDataId) + if(istext(cDataId)) + cDataId = text2num(cDataId) + + for(var/datum/data/crime/crime in fields[DATACORE_CRIMES]) + if(crime.dataId == cDataId) + fields[DATACORE_CRIMES] -= crime + return + +/datum/data/record/proc/add_crime_details(cDataId, details) + if(istext(cDataId)) + cDataId = text2num(cDataId) + + for(var/datum/data/crime/crime in fields[DATACORE_CRIMES]) + if(crime.dataId == cDataId) + crime.crimeDetails = details + return diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index 6b7f6f19fa2f..7ac63719b60c 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -46,7 +46,7 @@ // Create our paper var/obj/item/paper/report_paper = new(get_turf(src)) - //This could be a global count like sec and med record printouts. See GLOB.data_core.medicalPrintCount AKA datacore.dm + //This could be a global count like sec and med record printouts. See SSdatacore.medicalPrintCount AKA datacore.dm var/frNum = ++forensicPrintCount report_paper.name = text("FR-[] 'Forensic Record'", frNum) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 8fbf9c32a38e..62c77f3bd18b 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -327,10 +327,9 @@ if(ishuman(character)) //These procs all expect humans var/mob/living/carbon/human/humanc = character ship.manifest_inject(humanc, client, job) - GLOB.data_core.manifest_inject(humanc, client) + SSdatacore.inject_library(humanc, client, DATACORE_RECORDS_OUTPOST) ship.add_mob_to_crew_guestbook(humanc) AnnounceArrival(humanc, job.name, ship) - AddEmploymentContract(humanc) SSblackbox.record_feedback("tally", "species_spawned", 1, humanc.dna.species.name) if(GLOB.summon_guns_triggered) @@ -348,13 +347,6 @@ minor_announce("[job.name] [character.real_name] on deck!", zlevel = ship.shuttle_port.virtual_z()) return TRUE -/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee) - //TODO: figure out a way to exclude wizards/nukeops/demons from this. - for(var/C in GLOB.employmentCabinets) - var/obj/structure/filingcabinet/employment/employmentCabinet = C - if(!employmentCabinet.virgin) - employmentCabinet.addFile(employee) - /mob/dead/new_player/proc/LateChoices() if(auth_check) return diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index cf3f5ec725ec..e29bb4401681 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -342,14 +342,37 @@ if (!isnull(trait_exam)) . += trait_exam - var/traitstring = get_trait_string() - var/perpname = get_face_name(get_id_name("")) if(perpname && (HAS_TRAIT(user, TRAIT_SECURITY_HUD) || HAS_TRAIT(user, TRAIT_MEDICAL_HUD))) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general) - if(R) - . += "Rank: [R.fields["rank"]]\n\[Front photo\]\[Side photo\]" + var/linked_datacore = user.get_datacore_key() + var/datum/data/record/target_record + if(linked_datacore) + target_record = SSdatacore.get_record_by_name(perpname, linked_datacore) + if(target_record) + . += "
    Found record for datacore: [linked_datacore]." + . += "Rank: [target_record.fields[DATACORE_RANK]]. Name: [target_record.fields[DATACORE_NAME]]." + . += "\[Front photo\]\[Side photo\]" + if(HAS_TRAIT(user, TRAIT_MEDICAL_HUD)) + . += "\[[target_record.fields[DATACORE_PHYSICAL_HEALTH]]\]" + . += "\[[target_record.fields[DATACORE_MENTAL_HEALTH]]\]" + + if(HAS_TRAIT(user, TRAIT_SECURITY_HUD)) + var/criminal = "None" + criminal = target_record.fields[DATACORE_CRIMINAL_STATUS] + + . += "Criminal status: \[[criminal]\]" + . += jointext(list("Security record: \[View\]", + "\[Add crime\]", + "\[View comment log\]", + "\[Add comment\]"), "") + else if(!linked_datacore) + . += "
    No linked datacore." + else + . += "
    no linked record in datacore: [linked_datacore]" + if(HAS_TRAIT(user, TRAIT_MEDICAL_HUD)) + . += "
    \[Medical Evaluation\]" + . += "\[See traits\]" var/cyberimp_detect for(var/obj/item/organ/cyberimp/CI in internal_organs) if(CI.status == ORGAN_ROBOTIC && !CI.syndicate_implant) @@ -357,34 +380,6 @@ if(cyberimp_detect) . += "Detected cybernetic modifications:" . += "[cyberimp_detect]" - if(R) - var/health_r = R.fields["p_stat"] - . += "\[[health_r]\]" - health_r = R.fields["m_stat"] - . += "\[[health_r]\]" - R = find_record("name", perpname, GLOB.data_core.medical) - if(R) - . += "\[Medical evaluation\]
    " - if(traitstring) - . += "Detected physiological traits:" - . += "[traitstring]" - - if(HAS_TRAIT(user, TRAIT_SECURITY_HUD)) - if(!user.stat && user != src) - //|| !user.canmove || user.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. - var/criminal = "None" - - R = find_record("name", perpname, GLOB.data_core.security) - if(R) - criminal = R.fields["criminal"] - - . += "Criminal status: \[[criminal]\]" - . += jointext(list("Security record: \[View\]", - "\[Add crime\]", - "\[View comment log\]", - "\[Add comment\]"), "") - else if(isobserver(user) && traitstring) - . += "Traits: [traitstring]" //No flavor text unless the face can be seen. Prevents certain metagaming with impersonation. var/invisible_man = skipface || get_visible_name() == "Unknown" @@ -394,7 +389,6 @@ var/flavor = print_flavor_text() if(flavor) . += flavor - . += "*---------*" SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 27fa569de7cd..ee0298a8e756 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -277,29 +277,32 @@ if(href_list["hud"]) if(!ishuman(usr)) return - var/mob/living/carbon/human/H = usr + var/mob/living/carbon/human/human_or_ghost_user = usr var/perpname = get_face_name(get_id_name("")) - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD) && !HAS_TRAIT(H, TRAIT_MEDICAL_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD) && !HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD)) return - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general) + var/linked_datacore = human_or_ghost_user.get_datacore_key() + var/datum/data/record/target_record = SSdatacore.get_record_by_name(perpname, linked_datacore) if(href_list["photo_front"] || href_list["photo_side"]) - if(!R) + if(!target_record) return - if(!H.canUseHUD()) - return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD) && !HAS_TRAIT(H, TRAIT_MEDICAL_HUD)) + if(ishuman(human_or_ghost_user)) + var/mob/living/carbon/human/human_user = human_or_ghost_user + if(!human_user.canUseHUD()) + return + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD) && !HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD)) return - var/obj/item/photo/P = null + var/obj/item/photo/photo_from_record = null if(href_list["photo_front"]) - P = R.fields["photo_front"] + photo_from_record = target_record.get_front_photo() else if(href_list["photo_side"]) - P = R.fields["photo_side"] - if(P) - P.show(H) + photo_from_record = target_record.get_side_photo() + if(photo_from_record) + photo_from_record.show(human_or_ghost_user) return if(href_list["hud"] == "m") - if(!HAS_TRAIT(H, TRAIT_MEDICAL_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD)) return if(href_list["evaluation"]) if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20) @@ -341,85 +344,98 @@ to_chat(usr, "Patient has signs of suffocation, emergency treatment may be required!") if(getToxLoss() > 20) to_chat(usr, "Gathered data is inconsistent with the analysis, possible cause: poisoning.") - if(!H.wear_id) //You require access from here on out. - to_chat(H, "ERROR: Invalid access") + var/obj/item/card/id/id_card = human_or_ghost_user.get_idcard() + if(!id_card) //You require access from here on out. + to_chat(human_or_ghost_user, "ERROR: Invalid access") return - var/list/access = H.wear_id.GetAccess() + var/list/access = id_card.GetAccess() if(!(ACCESS_MEDICAL in access)) - to_chat(H, "ERROR: Invalid access") + to_chat(human_or_ghost_user, "ERROR: Invalid access") return if(href_list["p_stat"]) - var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel") - if(!R) + var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", target_record.fields[DATACORE_PHYSICAL_HEALTH]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel") + if(!target_record) return - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_MEDICAL_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD)) return if(health_status && health_status != "Cancel") - R.fields["p_stat"] = health_status + target_record.fields[DATACORE_PHYSICAL_HEALTH] = health_status return if(href_list["m_stat"]) - var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel") - if(!R) + var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", target_record.fields[DATACORE_MENTAL_HEALTH]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel") + if(!target_record) return - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_MEDICAL_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_MEDICAL_HUD)) return if(health_status && health_status != "Cancel") - R.fields["m_stat"] = health_status + target_record.fields[DATACORE_MENTAL_HEALTH] = health_status return + if(href_list["quirk"]) + var/quirkstring = get_trait_string() + if(quirkstring) + to_chat(human_or_ghost_user, "Detected physiological traits:\n[quirkstring]") + else + to_chat(human_or_ghost_user, "No physiological traits found.") return //Medical HUD ends here. if(href_list["hud"] == "s") - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten // Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access var/allowed_access = null - var/obj/item/clothing/glasses/hud/security/G = H.glasses - if(istype(G) && (G.obj_flags & EMAGGED)) + var/user_name = null + var/obj/item/clothing/glasses/hud/security/sec_hud = human_or_ghost_user.glasses + if(istype(sec_hud) && (sec_hud.obj_flags & EMAGGED)) allowed_access = "@%&ERROR_%$*" else //Implant and standard glasses check access - if(H.wear_id) - var/list/access = H.wear_id.GetAccess() + var/obj/item/card/id/id_card = human_or_ghost_user.get_idcard() + if(id_card) + var/list/access = id_card.GetAccess() if(ACCESS_SEC_DOORS in access) - allowed_access = H.get_authentification_name() + allowed_access = TRUE + user_name = human_or_ghost_user.get_authentification_name() if(!allowed_access) - to_chat(H, "ERROR: Invalid access.") + to_chat(human_or_ghost_user, "ERROR: Invalid access.") return + if(!user_name) + to_chat(human_or_ghost_user, "ERROR: Invalid name on ID.") + if(!perpname) - to_chat(H, "ERROR: Can not identify target.") + to_chat(human_or_ghost_user, "ERROR: Can not identify target.") return - R = find_record("name", perpname, GLOB.data_core.security) - if(!R) + + if(!target_record) to_chat(usr, "ERROR: Unable to locate data core entry for target.") return if(href_list["status"]) - var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Paroled", "Discharged", "Cancel") + var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", target_record.fields[DATACORE_CRIMINAL_STATUS]) in list("None", "*Arrest*", "Incarcerated", "Paroled", "Discharged", "Cancel") if(setcriminal != "Cancel") - if(!R) + if(!target_record) return - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return - investigate_log("[key_name(src)] has been set from [R.fields["criminal"]] to [setcriminal] by [key_name(usr)].", INVESTIGATE_RECORDS) - R.fields["criminal"] = setcriminal + investigate_log("[key_name(src)] has been set from [target_record.fields[DATACORE_CRIMINAL_STATUS]] to [setcriminal] by [key_name(usr)].", INVESTIGATE_RECORDS) + target_record.fields[DATACORE_CRIMINAL_STATUS] = setcriminal sec_hud_set_security_status() return if(href_list["view"]) - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return - to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]") - for(var/datum/data/crime/c in R.fields["crim"]) + to_chat(usr, "Name: [target_record.fields[DATACORE_NAME]]\nCriminal Status: [target_record.fields[DATACORE_CRIMINAL_STATUS]]") + for(var/datum/data/crime/c in target_record.fields[DATACORE_CRIMES]) to_chat(usr, "Crime: [c.crimeName]") if (c.crimeDetails) to_chat(usr, "Details: [c.crimeDetails]") @@ -427,62 +443,64 @@ to_chat(usr, "Details: \[Add details]") to_chat(usr, "Added by [c.author] at [c.time]") to_chat(usr, "----------") - to_chat(usr, "Notes: [R.fields["notes"]]") + to_chat(usr, "Notes: [target_record.fields[DATACORE_NOTES]]") return if(href_list["add_crime"]) var/t1 = stripped_input("Please input crime name:", "Security HUD", "", null) - if(!R || !t1 || !allowed_access) + if(!target_record || !t1 || !allowed_access) return - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return - var/crime = GLOB.data_core.createCrimeEntry(t1, null, allowed_access, station_time_timestamp()) - GLOB.data_core.addCrime(R.fields["id"], crime) - investigate_log("New Crime: [t1] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) - to_chat(usr, "Successfully added a crime.") + + var/crime = SSdatacore.new_crime_entry(t1, null, user_name, station_time_timestamp()) + target_record.add_crime(crime) + investigate_log("New Crime: [t1] | Added to [target_record.fields[DATACORE_NAME]] by [key_name(usr)]", INVESTIGATE_RECORDS) + to_chat(usr, span_notice("Successfully added a crime.")) return if(href_list["add_details"]) var/t1 = stripped_input(usr, "Please input crime details:", "Secure. records", "", null) - if(!R || !t1 || !allowed_access) + if(!target_record || !t1 || !allowed_access) return - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return + if(href_list["cdataid"]) - GLOB.data_core.addCrimeDetails(R.fields["id"], href_list["cdataid"], t1) - investigate_log("New Crime details: [t1] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) - to_chat(usr, "Successfully added details.") + target_record.add_crime_details(href_list["cdataid"], t1) + investigate_log("New Crime details: [t1] | Added to [target_record.fields[DATACORE_NAME]] by [key_name(usr)]", INVESTIGATE_RECORDS) + to_chat(usr, span_notice("Successfully added details.")) return if(href_list["view_comment"]) - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return to_chat(usr, "Comments/Log:") var/counter = 1 - while(R.fields[text("com_[]", counter)]) - to_chat(usr, R.fields[text("com_[]", counter)]) + while(target_record.fields[text("com_[]", counter)]) + to_chat(usr, target_record.fields[text("com_[]", counter)]) to_chat(usr, "----------") counter++ return if(href_list["add_comment"]) var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null) - if (!R || !t1 || !allowed_access) + if (!target_record || !t1 || !allowed_access) return - if(!H.canUseHUD()) + if(!human_or_ghost_user.canUseHUD()) return - if(!HAS_TRAIT(H, TRAIT_SECURITY_HUD)) + if(!HAS_TRAIT(human_or_ghost_user, TRAIT_SECURITY_HUD)) return var/counter = 1 - while(R.fields[text("com_[]", counter)]) + while(target_record.fields[text("com_[]", counter)]) counter++ - R.fields[text("com_[]", counter)] = text("Made by [] on [], []
    []", allowed_access, station_time_timestamp(), sector_datestamp(shortened = TRUE), t1) + target_record.fields[text("com_[]", counter)] = text("Made by [] on [], []
    []", allowed_access, station_time_timestamp(), sector_datestamp(shortened = TRUE), t1) to_chat(usr, "Successfully added comment.") return @@ -555,19 +573,6 @@ if(weaponcheck.Invoke(belt) || weaponcheck.Invoke(back)) //if a weapon is present in the belt or back slot threatcount += 2 //not enough to trigger look_for_perp() on it's own unless they also have criminal status. - //Check for arrest warrant - if(judgement_criteria & JUDGE_RECORDCHECK) - var/perpname = get_face_name(get_id_name()) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) - if(R && R.fields["criminal"]) - switch(R.fields["criminal"]) - if("*Arrest*") - threatcount += 5 - if("Incarcerated") - threatcount += 2 - if("Paroled") - threatcount += 2 - //Check for dresscode violations if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard)) threatcount += 2 @@ -829,10 +834,13 @@ return TRUE /mob/living/carbon/human/replace_records_name(oldname,newname) // Only humans have records right now, move this up if changed. - for(var/list/L in list(GLOB.data_core.general,GLOB.data_core.medical,GLOB.data_core.security,GLOB.data_core.locked)) - var/datum/data/record/R = find_record("name", oldname, L) - if(R) - R.fields["name"] = newname + for(var/id as anything in SSdatacore.library) + var/datum/data_library/library = SSdatacore.library[id] + var/datum/data/record/target_record = library.get_record_by_name(oldname) + if(target_record) + target_record.fields[DATACORE_NAME] = newname + library.records_by_name -= oldname + library.records_by_name[newname] = target_record /mob/living/carbon/human/get_total_tint() . = ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index b7c5b9877120..d3e9cbc0259c 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -26,9 +26,11 @@ var/obj/item/card/id/id = get_idcard(FALSE) if(id) return id.registered_name + /* var/obj/item/pda/pda = wear_id if(istype(pda)) return pda.owner + */ return if_no_id /mob/living/carbon/human/get_visible_name() @@ -43,7 +45,7 @@ if(head && (head.flags_inv & HIDEFACE)) return if_no_face //Likewise for hats var/obj/item/bodypart/O = get_bodypart(BODY_ZONE_HEAD) - if(!O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name) //disfigured. use id-name if possible + if(!O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate) > 2 || cloneloss > 50 || !real_name) //disfigured. use id-name if possible return if_no_face return real_name diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index cfd7d9153c8d..7bddf83e8090 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -629,8 +629,8 @@ if("Crew Member") var/list/personnel_list = list() - for(var/datum/data/record/t in GLOB.data_core.locked)//Look in data core locked. - personnel_list["[t.fields["name"]]: [t.fields["rank"]]"] = t.fields["image"]//Pull names, rank, and image. + for(var/datum/data/record/t in SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))//Look in data core locked. + personnel_list["[t.fields[DATACORE_NAME]]: [t.fields[DATACORE_RANK]]"] = t.fields[DATACORE_IMAGE]//Pull names, rank, and image. if(personnel_list.len) input = input("Select a crew member:") as null|anything in sortList(personnel_list) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 9f3b85fd4a92..15543a46a5bb 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -45,7 +45,7 @@ var/secHUD = 0 // Toggles whether the Security HUD is active or not var/medHUD = 0 // Toggles whether the Medical HUD is active or not - var/datum/data/record/medicalActive1 // Datacore record declarations for record software + var/datum/data/record/active_record // Datacore record declarations for record software var/datum/data/record/medicalActive2 var/datum/data/record/securityActive1 // Could probably just combine all these into one diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index 061c4a74a4b1..667c7c6d68d6 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -308,21 +308,15 @@ GLOBAL_LIST_INIT(pai_faces_icons, list( if("medicalrecord") // Accessing medical records if(subscreen == 1) - medicalActive1 = find_record("id", href_list["med_rec"], GLOB.data_core.general) - if(medicalActive1) - medicalActive2 = find_record("id", href_list["med_rec"], GLOB.data_core.medical) - if(!medicalActive2) - medicalActive1 = null - temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." + active_record = SSdatacore.find_record(DATACORE_ID, href_list["med_rec"], DATACORE_RECORDS_OUTPOST) + if(!active_record) + temp = "Unable to locate requested record. Record may have been deleted, or never have existed." if("securityrecord") if(subscreen == 1) - securityActive1 = find_record("id", href_list["sec_rec"], GLOB.data_core.general) - if(securityActive1) - securityActive2 = find_record("id", href_list["sec_rec"], GLOB.data_core.security) - if(!securityActive2) - securityActive1 = null - temp = "Unable to locate requested security record. Record may have been deleted, or never have existed." + active_record = SSdatacore.find_record(DATACORE_ID, href_list["sec_rec"], DATACORE_RECORDS_OUTPOST) + if(!active_record) + temp = "Unable to locate requested record. Record may have been deleted, or never have existed." if("securityhud") if(href_list["toggle"]) @@ -530,9 +524,9 @@ GLOBAL_LIST_INIT(pai_faces_icons, list( // Crew Manifest /mob/living/silicon/pai/proc/softwareManifest() . += "

    Crew Manifest



    " - if(GLOB.data_core.general) - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - . += "[t.fields["name"]] - [t.fields["rank"]]
    " + if(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + for(var/datum/data/record/t in sortRecord(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))) + . += "[t.fields[DATACORE_NAME]] - [t.fields[DATACORE_RANK]]
    " . += "" return . @@ -541,17 +535,14 @@ GLOBAL_LIST_INIT(pai_faces_icons, list( switch(subscreen) if(0) . += "

    Medical Records


    " - if(GLOB.data_core.general) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) - . += "[R.fields["id"]]: [R.fields["name"]]
    " + if(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + for(var/datum/data/record/R in sortRecord(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))) + . += "
    [R.fields[DATACORE_ID]]: [R.fields[DATACORE_NAME]]
    " if(1) . += "
    Medical Record

    " - if(medicalActive1 in GLOB.data_core.general) - . += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]
    \nGender: [medicalActive1.fields["gender"]]
    \nAge: [medicalActive1.fields["age"]]
    \nFingerprint: [medicalActive1.fields["fingerprint"]]
    \nPhysical Status: [medicalActive1.fields["p_stat"]]
    \nMental Status: [medicalActive1.fields["m_stat"]]
    " - else - . += "
    Requested medical record not found.

    " - if(medicalActive2 in GLOB.data_core.medical) - . += "
    \n
    Medical Data

    \nBlood Type:
    [medicalActive2.fields["blood_type"]]
    \nDNA (UE): [medicalActive2.fields["b_dna"]]
    \n
    \nMinor Disabilities: [medicalActive2.fields["mi_dis"]]
    \nDetails: [medicalActive2.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [medicalActive2.fields["ma_dis"]]
    \nDetails: [medicalActive2.fields["ma_dis_d"]]
    \n
    \nAllergies: [medicalActive2.fields["alg"]]
    \nDetails: [medicalActive2.fields["alg_d"]]
    \n
    \nCurrent Diseases: [medicalActive2.fields["cdi"]] (per disease info placed in log/comment section)
    \nDetails: [medicalActive2.fields["cdi_d"]]
    \n
    \nImportant Notes:
    \n\t[medicalActive2.fields["notes"]]
    \n
    \n
    Comments/Log

    " + if(active_record in SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + . += "Name: [active_record.fields[DATACORE_NAME]] ID: [active_record.fields[DATACORE_ID]]
    \nGender: [active_record.fields[DATACORE_GENDER]]
    \nAge: [active_record.fields[DATACORE_AGE]]
    \nFingerprint: [active_record.fields[DATACORE_FINGERPRINT]]
    \nPhysical Status: [active_record.fields[DATACORE_PHYSICAL_HEALTH]]
    \nMental Status: [active_record.fields[DATACORE_MENTAL_HEALTH]]
    " + . += "
    \n
    Medical Data

    \nBlood Type: [active_record.fields[DATACORE_BLOOD_TYPE]]
    \nDNA (UE): [active_record.fields[DATACORE_BLOOD_DNA]]
    \n
    \nMinor Disabilities: [active_record.fields["mi_dis"]]
    \nDetails: [active_record.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [active_record.fields[DATACORE_DISABILITIES]]
    \nDetails: [active_record.fields[DATACORE_DISABILITIES_DETAILS]]
    \n
    \nAllergies: [active_record.fields["alg"]]
    \nDetails: [active_record.fields["alg_d"]]
    \n
    \nCurrent Diseases: [active_record.fields[DATACORE_DISEASES]] (per disease info placed in log/comment section)
    \nDetails: [active_record.fields[DATACORE_DISEASES_DETAILS]]
    \n
    \nImportant Notes:
    \n\t[active_record.fields[DATACORE_NOTES]]
    \n
    \n
    Comments/Log

    " else . += "
    Requested medical record not found.

    " . += "
    \nBack
    " @@ -563,17 +554,14 @@ GLOBAL_LIST_INIT(pai_faces_icons, list( switch(subscreen) if(0) . += "

    Security Records


    " - if(GLOB.data_core.general) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general)) - . += "[R.fields["id"]]: [R.fields["name"]]
    " + if(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + for(var/datum/data/record/R in sortRecord(SSdatacore.get_records(DATACORE_RECORDS_OUTPOST))) + . += "
    [R.fields[DATACORE_ID]]: [R.fields[DATACORE_NAME]]
    " if(1) . += "

    Security Record

    " - if(securityActive1 in GLOB.data_core.general) - . += "Name:
    [securityActive1.fields["name"]] ID: [securityActive1.fields["id"]]
    \nGender: [securityActive1.fields["gender"]]
    \nAge: [securityActive1.fields["age"]]
    \nRank: [securityActive1.fields["rank"]]
    \nFingerprint: [securityActive1.fields["fingerprint"]]
    \nPhysical Status: [securityActive1.fields["p_stat"]]
    \nMental Status: [securityActive1.fields["m_stat"]]
    " - else - . += "
    Requested security record not found,

    " - if(securityActive2 in GLOB.data_core.security) - . += "
    \nSecurity Data
    \nCriminal Status: [securityActive2.fields["criminal"]]
    \n
    \nCrimes: [securityActive2.fields["crim"]]
    \nDetails: [securityActive2.fields["crim_d"]]
    \n
    \nImportant Notes:
    \n\t[securityActive2.fields["notes"]]
    \n
    \n
    Comments/Log

    " + if(active_record in SSdatacore.get_records(DATACORE_RECORDS_OUTPOST)) + . += "Name: [active_record.fields[DATACORE_NAME]] ID: [active_record.fields[DATACORE_ID]]
    \nGender: [active_record.fields[DATACORE_GENDER]]
    \nAge: [active_record.fields[DATACORE_AGE]]
    \nRank: [active_record.fields[DATACORE_RANK]]
    \nFingerprint: [active_record.fields[DATACORE_FINGERPRINT]]
    \nPhysical Status: [active_record.fields[DATACORE_PHYSICAL_HEALTH]]
    \nMental Status: [active_record.fields[DATACORE_MENTAL_HEALTH]]
    " + . += "
    \nSecurity Data
    \nCriminal Status: [active_record.fields[DATACORE_CRIMINAL_STATUS]]
    \n
    \nCrimes: [active_record.fields[DATACORE_CRIMES]]
    \nDetails: [active_record.fields["crim_d"]]
    \n
    \nImportant Notes:
    \n\t[active_record.fields[DATACORE_NOTES]]
    \n
    \n
    Comments/Log

    " else . += "
    Requested security record not found,

    " . += "
    \nBack
    " diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index b1788a7aa50d..9980ba6e5cf5 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1166,7 +1166,7 @@ /** * Fully update the name of a mob * - * This will update a mob's name, real_name, mind.name, GLOB.data_core records, pda, id and traitor text + * This will update a mob's name, real_name, mind.name, SS data_core records, pda, id and traitor text * * Calling this proc without an oldname will only update the mob and skip updating the pda, id and records ~Carn */ @@ -1201,7 +1201,7 @@ obj.update_explanation_text() return 1 -///Updates GLOB.data_core records with new name , see mob/living/carbon/human +///Updates SS data_core records with new name , see mob/living/carbon/human /mob/proc/replace_records_name(oldname,newname) return diff --git a/code/modules/overmap/ships/controlled_ship_datum.dm b/code/modules/overmap/ships/controlled_ship_datum.dm index 5d851e52f4fd..2e09fb1901c2 100644 --- a/code/modules/overmap/ships/controlled_ship_datum.dm +++ b/code/modules/overmap/ships/controlled_ship_datum.dm @@ -70,6 +70,7 @@ ///Stations the ship has been blacklisted from landing at, associative station = reason var/list/blacklisted = list() + var/datum/data_library/ship_record var/datum/faction/faction_datum /datum/overmap/ship/controlled/Rename(new_name, force = FALSE) @@ -112,6 +113,7 @@ refresh_engines() ship_account = new(name, source_template.starting_funds) + ship_record = SSdatacore.create_library(src) faction_datum = source_template.faction_datum #ifdef UNIT_TESTS @@ -310,6 +312,9 @@ job_holder_refs[human_job] = list() job_holder_refs[human_job] += WEAKREF(H) + if(ship_record) + SSdatacore.inject_library(H, C, ship_record) + /** * adds a mob's real name to a crew's guestbooks * diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 72f5d1326ead..7634704ef62b 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -125,115 +125,63 @@ /* * Security Record Cabinets */ -/obj/structure/filingcabinet/security - var/virgin = 1 -/obj/structure/filingcabinet/security/proc/populate() - if(virgin) - for(var/datum/data/record/G in GLOB.data_core.general) - var/datum/data/record/S = find_record("name", G.fields["name"], GLOB.data_core.security) - if(!S) - continue - var/obj/item/paper/sec_record_paper = new /obj/item/paper(src) - var/sec_record_text = "
    Security Record

    " - sec_record_text += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nGender: [G.fields["gender"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " - sec_record_text += "
    \n
    Security Data

    \nCriminal Status: [S.fields["criminal"]]
    \n
    \nCrimes: [S.fields["crim"]]
    \nDetails: [S.fields["crim_d"]]
    \n
    \nImportant Notes:
    \n\t[S.fields["notes"]]
    \n
    \n
    Comments/Log

    " - var/counter = 1 - while(S.fields["com_[counter]"]) - sec_record_text += "[S.fields["com_[counter]"]]
    " - counter++ - sec_record_text += "" - sec_record_paper.add_raw_text(sec_record_text) - sec_record_paper.name = "paper - '[G.fields["name"]]'" - sec_record_paper.update_appearance() - virgin = 0 //tabbing here is correct- it's possible for people to try and use it - //before the records have been generated, so we do this inside the loop. +/obj/structure/filingcabinet/record + var/datum/overmap/ship/controlled/linked_ship + var/virgin = 1 -/obj/structure/filingcabinet/security/attack_hand() - populate() +/obj/structure/filingcabinet/record/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock) . = ..() + linked_ship = port.current_ship + if(linked_ship) + name = "[name] - [linked_ship.name]" -/obj/structure/filingcabinet/security/attack_tk() - populate() - ..() - -/* - * Medical Record Cabinets - */ -/obj/structure/filingcabinet/medical - var/virgin = 1 +/obj/structure/filingcabinet/record/disconnect_from_shuttle(obj/docking_port/mobile/port) + . = ..() + linked_ship = null -/obj/structure/filingcabinet/medical/proc/populate() - if(virgin) - for(var/datum/data/record/G in GLOB.data_core.general) - var/datum/data/record/M = find_record("name", G.fields["name"], GLOB.data_core.medical) - if(!M) - continue - var/obj/item/paper/med_record_paper = new /obj/item/paper(src) - var/med_record_text = "
    Medical Record

    " - med_record_text += "Name: [G.fields["name"]] ID: [G.fields["id"]]
    \nGender: [G.fields["gender"]]
    \nAge: [G.fields["age"]]
    \nFingerprint: [G.fields["fingerprint"]]
    \nPhysical Status: [G.fields["p_stat"]]
    \nMental Status: [G.fields["m_stat"]]
    " - med_record_text += "
    \n
    Medical Data

    \nBlood Type: [M.fields["blood_type"]]
    \nDNA: [M.fields["b_dna"]]
    \n
    \nMinor Disabilities: [M.fields["mi_dis"]]
    \nDetails: [M.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [M.fields["ma_dis"]]
    \nDetails: [M.fields["ma_dis_d"]]
    \n
    \nAllergies: [M.fields["alg"]]
    \nDetails: [M.fields["alg_d"]]
    \n
    \nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section)
    \nDetails: [M.fields["cdi_d"]]
    \n
    \nImportant Notes:
    \n\t[M.fields["notes"]]
    \n
    \n
    Comments/Log

    " - var/counter = 1 - while(M.fields["com_[counter]"]) - med_record_text += "[M.fields["com_[counter]"]]
    " - counter++ - med_record_text += "" - med_record_paper.add_raw_text(med_record_text) - med_record_paper.name = "paper - '[G.fields["name"]]'" - med_record_paper.update_appearance() - virgin = 0 //tabbing here is correct- it's possible for people to try and use it - //before the records have been generated, so we do this inside the loop. +/obj/structure/filingcabinet/record/proc/populate() + return -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/filingcabinet/medical/attack_hand() +/obj/structure/filingcabinet/record/attack_hand() populate() . = ..() -/obj/structure/filingcabinet/medical/attack_tk() +/obj/structure/filingcabinet/record/attack_tk() populate() ..() -/* - * Employment contract Cabinets - */ - -GLOBAL_LIST_EMPTY(employmentCabinets) - -/obj/structure/filingcabinet/employment - var/cooldown = 0 - icon_state = "employmentcabinet" - var/virgin = 1 - -/obj/structure/filingcabinet/employment/Initialize() - . = ..() - GLOB.employmentCabinets += src - -/obj/structure/filingcabinet/employment/Destroy() - GLOB.employmentCabinets -= src - return ..() - -/obj/structure/filingcabinet/employment/proc/fillCurrent() - //This proc fills the cabinet with the current crew. - for(var/record in GLOB.data_core.locked) - var/datum/data/record/G = record - if(!G) - continue - var/datum/mind/M = G.fields["mindref"] - if(M && ishuman(M.current)) - addFile(M.current) - - -/obj/structure/filingcabinet/employment/proc/addFile(mob/living/carbon/human/employee) - new /obj/item/paper/contract/employment(src, employee) - -/obj/structure/filingcabinet/employment/interact(mob/user) - if(!cooldown) - if(virgin) - fillCurrent() - virgin = 0 - cooldown = TRUE - // prevents the devil from just instantly emptying the cabinet, ensuring an easy win. - addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10 SECONDS) - else - to_chat(user, "[src] is jammed, give it a few seconds.") - ..() +/obj/structure/filingcabinet/record/populate() + if(virgin) + for(var/datum/data/record/G in SSdatacore.get_records(linked_ship)) + var/obj/item/paper/record_paper = new /obj/item/paper(src) + var/record_text = get_record_text(G) + record_paper.add_raw_text(record_text) + record_paper.name = "paper - '[linked_ship.name] - [G.fields[DATACORE_NAME]]'" + record_paper.update_appearance() + virgin = 0 //tabbing here is correct- it's possible for people to try and use it + //before the records have been generated, so we do this inside the loop. + linked_ship = null + +/obj/structure/filingcabinet/record/proc/get_record_text(datum/data/record/G) + return + +/obj/structure/filingcabinet/record/security/get_record_text(datum/data/record/G) + var/record_text = "
    Security Record

    " + record_text += "Name: [G.fields[DATACORE_NAME]] ID: [G.fields[DATACORE_ID]]
    \nGender: [G.fields[DATACORE_GENDER]]
    \nAge: [G.fields[DATACORE_AGE]]
    \nFingerprint: [G.fields[DATACORE_FINGERPRINT]]
    \nPhysical Status: [G.fields[DATACORE_PHYSICAL_HEALTH]]
    \nMental Status: [G.fields[DATACORE_MENTAL_HEALTH]]
    " + record_text += "
    \n
    Security Data

    \nCriminal Status: [G.fields[DATACORE_CRIMINAL_STATUS]]
    \n
    \nCrimes: [G.fields[DATACORE_CRIMES]]
    \nDetails: [G.fields["crim_d"]]
    \n
    \nImportant Notes:
    \n\t[G.fields[DATACORE_NOTES]]
    \n
    \n
    Comments/Log

    " + record_text += "" + return record_text + +/obj/structure/filingcabinet/record/medical/get_record_text(datum/data/record/G) + var/record_text = "
    Medical Record

    " + record_text += "Name: [G.fields[DATACORE_NAME]] ID: [G.fields[DATACORE_ID]]
    \nGender: [G.fields[DATACORE_GENDER]]
    \nAge: [G.fields[DATACORE_AGE]]
    \nFingerprint: [G.fields[DATACORE_FINGERPRINT]]
    \nPhysical Status: [G.fields[DATACORE_PHYSICAL_HEALTH]]
    \nMental Status: [G.fields[DATACORE_MENTAL_HEALTH]]
    " + record_text += "
    \n
    Medical Data

    \nBlood Type: [G.fields[DATACORE_BLOOD_TYPE]]
    \nDNA: [G.fields[DATACORE_BLOOD_DNA]]
    \n
    \nMinor Disabilities: [G.fields["mi_dis"]]
    \nDetails: [G.fields["mi_dis_d"]]
    \n
    \nMajor Disabilities: [G.fields[DATACORE_DISABILITIES]]
    \nDetails: [G.fields[DATACORE_DISABILITIES_DETAILS]]
    \n
    \nAllergies: [G.fields["alg"]]
    \nDetails: [G.fields["alg_d"]]
    \n
    \nCurrent Diseases: [G.fields[DATACORE_DISEASES]] (per disease info placed in log/comment section)
    \nDetails: [G.fields[DATACORE_DISEASES_DETAILS]]
    \n
    \nImportant Notes:
    \n\t[G.fields[DATACORE_NOTES]]
    \n
    \n
    Comments/Log

    " + record_text += "" + return record_text + +/obj/structure/filingcabinet/record/gen/get_record_text(datum/data/record/G) + var/record_text = "
    General Record

    " + record_text += "Name: [G.fields[DATACORE_NAME]] ID: [G.fields[DATACORE_ID]]
    \nGender: [G.fields[DATACORE_GENDER]]
    \nAge: [G.fields[DATACORE_AGE]]
    \nFingerprint: [G.fields[DATACORE_FINGERPRINT]]
    \nPhysical Status: [G.fields[DATACORE_PHYSICAL_HEALTH]]
    \nMental Status: [G.fields[DATACORE_MENTAL_HEALTH]]
    " + record_text += "" + return record_text diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index e91a03e421f3..5b6db18d6d92 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -173,8 +173,8 @@ if(!isturf(target_turf)) blending = FALSE return FALSE - size_x = clamp(size_x, CAMERA_PICTURE_SIZE_HARD_MINIMUM, CAMERA_PICTURE_SIZE_HARD_LIMIT) - size_y = clamp(size_y, CAMERA_PICTURE_SIZE_HARD_MINIMUM, CAMERA_PICTURE_SIZE_HARD_LIMIT) + size_x = clamp(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT) + size_y = clamp(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT) var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.") var/list/mobs_spotted = list() var/list/dead_spotted = list() diff --git a/shiptest.dme b/shiptest.dme index 3e1776300873..e0bc791bfc9a 100644 --- a/shiptest.dme +++ b/shiptest.dme @@ -51,6 +51,7 @@ #include "code\__DEFINES\contracts.dm" #include "code\__DEFINES\cooldowns.dm" #include "code\__DEFINES\cult.dm" +#include "code\__DEFINES\datacore.dm" #include "code\__DEFINES\directional.dm" #include "code\__DEFINES\diseases.dm" #include "code\__DEFINES\DNA.dm" @@ -334,6 +335,7 @@ #include "code\controllers\subsystem\callback.dm" #include "code\controllers\subsystem\chat.dm" #include "code\controllers\subsystem\communications.dm" +#include "code\controllers\subsystem\datacore.dm" #include "code\controllers\subsystem\dbcore.dm" #include "code\controllers\subsystem\dcs.dm" #include "code\controllers\subsystem\discord.dm" @@ -422,7 +424,6 @@ #include "code\datums\cinematic.dm" #include "code\datums\cogbar.dm" #include "code\datums\dash_weapon.dm" -#include "code\datums\datacore.dm" #include "code\datums\datum.dm" #include "code\datums\datumvars.dm" #include "code\datums\dna.dm" @@ -971,17 +972,17 @@ #include "code\game\machinery\computer\dna_console.dm" #include "code\game\machinery\computer\launchpad_control.dm" #include "code\game\machinery\computer\law.dm" -#include "code\game\machinery\computer\medical.dm" #include "code\game\machinery\computer\Operating.dm" #include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\robot.dm" -#include "code\game\machinery\computer\security.dm" #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\computer\teleporter.dm" #include "code\game\machinery\computer\warrant.dm" #include "code\game\machinery\computer\prisoner\_prisoner.dm" -#include "code\game\machinery\computer\prisoner\gulag_teleporter.dm" #include "code\game\machinery\computer\prisoner\management.dm" +#include "code\game\machinery\computer\record\medical.dm" +#include "code\game\machinery\computer\record\records.dm" +#include "code\game\machinery\computer\record\security.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_electronics.dm" #include "code\game\machinery\doors\airlock_types.dm" @@ -2083,6 +2084,10 @@ #include "code\modules\clothing\under\jobs\Plasmaman\engineering.dm" #include "code\modules\clothing\under\jobs\Plasmaman\medsci.dm" #include "code\modules\clothing\under\jobs\Plasmaman\security.dm" +#include "code\modules\datacore\crime.dm" +#include "code\modules\datacore\library.dm" +#include "code\modules\datacore\medical_note.dm" +#include "code\modules\datacore\records.dm" #include "code\modules\detectivework\detective_work.dm" #include "code\modules\detectivework\evidence.dm" #include "code\modules\detectivework\footprints_and_rag.dm" diff --git a/sound/machines/terminal_error.ogg b/sound/machines/terminal_error.ogg new file mode 100644 index 000000000000..22556e5ea4b0 Binary files /dev/null and b/sound/machines/terminal_error.ogg differ diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/NoteKeeper.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/NoteKeeper.tsx new file mode 100644 index 000000000000..f0e29d1d68cf --- /dev/null +++ b/tgui/packages/tgui/interfaces/MedicalRecords/NoteKeeper.tsx @@ -0,0 +1,129 @@ +import { useBackend, useLocalState } from 'tgui/backend'; +import { + BlockQuote, + Box, + Button, + Icon, + LabeledList, + Section, + Tabs, + TextArea, + Tooltip, +} from 'tgui/components'; + +import { getMedicalRecord } from './helpers'; +import { MedicalNote, MedicalRecordsData } from './types'; + +/** Small section for adding notes. Passes a ref and note to Byond. */ +export const NoteKeeper = (props, context) => { + const foundRecord = getMedicalRecord(props, context); + if (!foundRecord) return <> ; + + const { act } = useBackend(context); + const { record_ref } = foundRecord; + + const [selectedNote, setSelectedNote] = useLocalState< + MedicalNote | undefined + >(context, 'selectedNote', undefined); + + const [writing, setWriting] = useLocalState(context, 'note', false); + + const addNote = (event, value: string) => { + act('add_note', { + record_ref: record_ref, + content: value, + }); + setWriting(false); + }; + + const deleteNote = () => { + if (!selectedNote) return; + act('delete_note', { + record_ref: record_ref, + note_ref: selectedNote.note_ref, + }); + setSelectedNote(undefined); + }; + + return ( +
    } fill scrollable title="Notes"> + {writing && ( +