diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 6c58eaa8c8fb..32e76893cd9d 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -1305,7 +1305,7 @@ /obj/effect/turf_decal/tile/brown{ dir = 1 }, -/obj/machinery/photocopier/gratis, +/obj/machinery/photocopier/gratis/prebuilt, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) "gQ" = ( diff --git a/_maps/RandomRuins/SpaceRuins/allamericandiner.dmm b/_maps/RandomRuins/SpaceRuins/allamericandiner.dmm index c0125ed5398d..c9da64d2e8c3 100644 --- a/_maps/RandomRuins/SpaceRuins/allamericandiner.dmm +++ b/_maps/RandomRuins/SpaceRuins/allamericandiner.dmm @@ -371,7 +371,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/allamericandiner) "tg" = ( -/obj/machinery/photocopier/gratis, +/obj/machinery/photocopier/gratis/prebuilt, /obj/structure/sign/flag/ssc/directional/north, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/grimy, diff --git a/_maps/RandomRuins/SpaceRuins/derelict_sulaco.dmm b/_maps/RandomRuins/SpaceRuins/derelict_sulaco.dmm index 995a736c620e..498a13896021 100644 --- a/_maps/RandomRuins/SpaceRuins/derelict_sulaco.dmm +++ b/_maps/RandomRuins/SpaceRuins/derelict_sulaco.dmm @@ -589,7 +589,7 @@ /turf/open/floor/iron/showroomfloor, /area/ruin/space/has_grav/derelictsulaco) "tp" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/pod/light, diff --git a/_maps/RandomRuins/SpaceRuins/hellfactory.dmm b/_maps/RandomRuins/SpaceRuins/hellfactory.dmm index 5e2038ac70a1..aa9b462d2c6d 100644 --- a/_maps/RandomRuins/SpaceRuins/hellfactory.dmm +++ b/_maps/RandomRuins/SpaceRuins/hellfactory.dmm @@ -182,7 +182,7 @@ /turf/open/floor/plastic, /area/ruin/space/has_grav/hellfactory) "aE" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/ruin/space/has_grav/hellfactoryoffice) "aF" = ( diff --git a/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm b/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm index c338834ad7c3..e83499a74091 100644 --- a/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm +++ b/_maps/RandomRuins/SpaceRuins/hilbertresearchfacility.dmm @@ -1635,7 +1635,7 @@ /turf/open/floor/engine, /area/ruin/space/has_grav/powered/hilbertresearchfacility) "Lr" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/ruin/space/has_grav/powered/hilbertresearchfacility) "Lw" = ( diff --git a/_maps/RandomRuins/SpaceRuins/meatderelict.dmm b/_maps/RandomRuins/SpaceRuins/meatderelict.dmm index 3e4bece11e8e..7e1fcc4803b3 100644 --- a/_maps/RandomRuins/SpaceRuins/meatderelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/meatderelict.dmm @@ -2324,7 +2324,7 @@ /turf/open/indestructible/meat, /area/ruin/space/has_grav/powered/biooutpost/vault) "Ue" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/purple/opposingcorners, /turf/open/indestructible/white, /area/ruin/space/has_grav/powered/biooutpost) diff --git a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm index ea2ca46c0921..d2cf049c0a57 100644 --- a/_maps/RandomRuins/SpaceRuins/originalcontent.dmm +++ b/_maps/RandomRuins/SpaceRuins/originalcontent.dmm @@ -840,7 +840,7 @@ /obj/structure/fluff/paper{ dir = 10 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/indestructible/paper, /area/ruin/space/has_grav/powered) "cq" = ( diff --git a/_maps/RandomRuins/SpaceRuins/waystation.dmm b/_maps/RandomRuins/SpaceRuins/waystation.dmm index 5642e9b85c3c..022e4889c46e 100644 --- a/_maps/RandomRuins/SpaceRuins/waystation.dmm +++ b/_maps/RandomRuins/SpaceRuins/waystation.dmm @@ -218,7 +218,7 @@ /area/ruin/space/has_grav/waystation/cargobay) "ea" = ( /obj/effect/turf_decal/tile/brown/half/contrasted, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/ruin/space/has_grav/waystation/cargooffice) @@ -946,7 +946,7 @@ /turf/open/floor/iron, /area/ruin/space/has_grav/waystation/dorms) "pl" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/ruin/space/has_grav/waystation/qm) "pm" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 6a77ae8388d7..8d69c91deff6 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1586,7 +1586,7 @@ /area/station/security/checkpoint/arrivals) "amx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/button/door/directional/east{ id = "left_arrivals_shutters"; name = "Left Arrivals Hallway Shutters"; @@ -8531,7 +8531,7 @@ /turf/open/floor/iron/dark, /area/station/security/detectives_office) "bJm" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/status_display/ai/directional/north, /obj/structure/reagent_dispensers/wall/peppertank/directional/east, /obj/effect/turf_decal/bot_white, @@ -17527,7 +17527,7 @@ dir = 8 }, /obj/machinery/airalarm/directional/south, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/science/research) "ddW" = ( @@ -18773,7 +18773,7 @@ name = "medbay camera"; network = list("ss13","medbay") }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/medical/medbay) "dlO" = ( @@ -28526,7 +28526,7 @@ /turf/open/floor/iron, /area/station/hallway/primary/central/aft) "ffd" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/requests_console/directional/north{ department = "Head of Security's Desk"; name = "Head of Security's Requests Console" @@ -32609,7 +32609,7 @@ /area/station/ai_monitored/turret_protected/aisat_interior) "goP" = ( /obj/item/radio/intercom/directional/north, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/checker, /area/station/hallway/secondary/service) "goR" = ( @@ -41737,7 +41737,7 @@ /turf/open/floor/iron, /area/station/hallway/secondary/entry) "iKf" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/east, /turf/open/floor/carpet/royalblack, /area/station/service/chapel/office) @@ -45268,7 +45268,7 @@ /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) "jNF" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/bot_white, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -50708,7 +50708,7 @@ /obj/effect/decal/cleanable/cobweb, /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/newspaper{ pixel_x = 3; pixel_y = 3 @@ -51895,7 +51895,7 @@ /turf/open/floor/iron, /area/station/commons/storage/tools) "lEN" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/computer/security/telescreen/entertainment/directional/west, /turf/open/floor/wood, /area/station/command/heads_quarters/captain/private) @@ -52695,7 +52695,7 @@ /turf/open/floor/plating, /area/station/maintenance/department/security) "lSF" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/computer/security/telescreen/entertainment/directional/north, /turf/open/floor/wood/large, /area/station/service/library) @@ -56419,7 +56419,7 @@ /turf/open/floor/iron, /area/station/engineering/main) "mUF" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, /obj/effect/turf_decal/bot_white, @@ -56697,7 +56697,7 @@ /area/station/command/heads_quarters/rd) "mYI" = ( /obj/machinery/light_switch/directional/north, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/light/directional/north, /turf/open/floor/wood, /area/station/command/heads_quarters/captain) @@ -60653,7 +60653,7 @@ /turf/open/floor/iron/dark, /area/station/science/robotics/lab) "ocD" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/structure/sign/poster/official/work_for_a_future/directional/east, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) @@ -70156,7 +70156,7 @@ /area/station/maintenance/department/science) "qKC" = ( /obj/effect/turf_decal/stripes/white/line, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/engineering/break_room) "qKF" = ( @@ -73946,7 +73946,7 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "rPg" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/broken/directional/south, /turf/open/floor/plating, @@ -77136,7 +77136,7 @@ /area/station/service/kitchen/abandoned) "sKa" = ( /obj/structure/cable, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/command/meeting_room/council) "sKd" = ( @@ -78639,7 +78639,7 @@ /area/station/hallway/primary/central/fore) "tiI" = ( /obj/machinery/newscaster/directional/east, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/bot_white, /obj/machinery/light/small/directional/east, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -80010,7 +80010,7 @@ /turf/open/floor/iron, /area/station/cargo/storage) "tEy" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/status_display/evac/directional/east, /obj/machinery/camera/directional/east{ c_tag = "Lawyer's Office" @@ -80606,7 +80606,7 @@ /turf/open/floor/iron/dark, /area/station/science/genetics) "tMm" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/south, /obj/effect/turf_decal/box/white, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -83196,7 +83196,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) "uyF" = ( @@ -84305,7 +84305,7 @@ /turf/open/floor/iron/dark, /area/station/engineering/main) "uOw" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 }, @@ -91781,7 +91781,7 @@ /turf/open/floor/iron/dark, /area/station/security/courtroom) "wPU" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 1 }, diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 3f2cd29fc509..8fdff6e0d46e 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -193,7 +193,7 @@ /area/station/science/xenobiology) "adZ" = ( /obj/effect/turf_decal/tile/brown/fourcorners, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/engineering/lobby) "aee" = ( @@ -17599,7 +17599,7 @@ /turf/open/floor/iron, /area/station/hallway/primary/starboard) "fgm" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/structure/sign/poster/official/random/directional/east, /turf/open/floor/wood, /area/station/service/library) @@ -23772,7 +23772,7 @@ /turf/open/floor/iron, /area/station/hallway/primary/starboard) "hbp" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/command/meeting_room) "hbt" = ( @@ -24476,7 +24476,7 @@ /turf/open/openspace, /area/station/science/xenobiology) "hnP" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/cafeteria{ dir = 8 }, @@ -25303,7 +25303,7 @@ }, /area/station/science/research) "hAo" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood/corner, /obj/structure/sign/calendar/directional/west, /turf/open/floor/wood, @@ -28536,7 +28536,7 @@ /obj/structure/disposalpipe/segment{ dir = 5 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) "iyL" = ( @@ -33506,7 +33506,7 @@ /turf/open/floor/iron, /area/station/hallway/primary/starboard) "kaw" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/north, /turf/open/floor/iron, /area/station/cargo/office) @@ -61156,7 +61156,7 @@ /area/station/science/ordnance) "sbi" = ( /obj/machinery/newscaster/directional/north, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron, /area/station/command/heads_quarters/hop) "sbv" = ( @@ -73360,7 +73360,7 @@ /turf/open/floor/plating, /area/station/maintenance/aft/greater) "vLt" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 8 }, @@ -73954,7 +73954,7 @@ /obj/machinery/light_switch/directional/west{ pixel_y = 5 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/airalarm/directional/north, /turf/open/floor/wood, /area/station/hallway/secondary/service) diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index ee1cdc76a9d0..bb4f167d9440 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -831,7 +831,7 @@ /turf/open/floor/plating/airless, /area/space/nearstation) "aeM" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, @@ -13162,7 +13162,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/bot, /turf/open/floor/iron/dark, /area/station/security/detectives_office) @@ -28199,7 +28199,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -39173,7 +39173,7 @@ /area/station/maintenance/starboard/aft) "imu" = ( /obj/machinery/light/small/directional/west, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -52088,7 +52088,7 @@ /area/station/security/prison/safe) "mAS" = ( /obj/effect/turf_decal/tile/red, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/structure/sign/poster/official/space_cops/directional/south, /turf/open/floor/iron, /area/station/security/office) @@ -54435,7 +54435,7 @@ /obj/structure/sign/painting/library{ pixel_x = 32 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/south, /obj/effect/turf_decal/box/white, /turf/open/floor/iron/dark, @@ -58767,7 +58767,7 @@ /turf/open/floor/iron, /area/station/cargo/storage) "oMj" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, @@ -76110,7 +76110,7 @@ "uou" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -78254,7 +78254,7 @@ /area/station/cargo/warehouse) "vaK" = ( /obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/newspaper{ pixel_x = 4; pixel_y = 4 @@ -86702,7 +86702,7 @@ }, /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) "xJP" = ( diff --git a/_maps/map_files/LimaStation/LimaStation.dmm b/_maps/map_files/LimaStation/LimaStation.dmm index 2b0f7a1c944e..6a3d4b8040f0 100644 --- a/_maps/map_files/LimaStation/LimaStation.dmm +++ b/_maps/map_files/LimaStation/LimaStation.dmm @@ -5752,7 +5752,7 @@ /area/station/security/lockers) "bTN" = ( /obj/machinery/firealarm/directional/east, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark/side{ dir = 4 }, @@ -6917,7 +6917,7 @@ /turf/open/floor/wood, /area/station/service/library) "cra" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/service/library) "crf" = ( @@ -10831,7 +10831,7 @@ /obj/structure/secure_safe{ pixel_x = -23 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/commons/vacant_room/office) "dEN" = ( @@ -17654,7 +17654,7 @@ /turf/open/floor/iron/dark, /area/station/engineering/atmos/experiment_room) "fQB" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/newscaster/directional/south, /obj/effect/turf_decal/bot_white, /obj/effect/turf_decal/siding/wood{ @@ -29553,7 +29553,7 @@ /turf/open/floor/iron/grimy, /area/station/service/library) "jEc" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/status_display/evac/directional/west, /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/grimy, @@ -39365,7 +39365,7 @@ }, /area/station/service/bar) "mHl" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood{ dir = 1 }, @@ -55167,7 +55167,7 @@ /turf/open/floor/iron/sepia, /area/station/hallway/secondary/service) "rvi" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/status_display/supply{ pixel_y = 30 }, @@ -66132,7 +66132,7 @@ /area/station/hallway/secondary/exit) "uMU" = ( /obj/machinery/status_display/ai/directional/west, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/structure/cable, /obj/effect/turf_decal/bot_white, /turf/open/floor/iron/dark/telecomms, @@ -68714,7 +68714,7 @@ /turf/closed/wall/r_wall, /area/station/medical/abandoned) "vHB" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood{ dir = 4 }, @@ -69387,7 +69387,7 @@ /obj/structure/secure_safe/hos{ pixel_y = 34 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) "vTG" = ( @@ -73258,7 +73258,7 @@ /turf/open/floor/engine, /area/station/engineering/supermatter) "xfM" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 }, diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index fa683179a155..5fbbe49938c2 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -13216,7 +13216,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/south, /turf/open/floor/carpet, /area/station/command/heads_quarters/hos) @@ -17780,7 +17780,7 @@ "eJb" = ( /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/stripes/corner, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/yellow/half/contrasted, /turf/open/floor/iron, /area/station/engineering/break_room) @@ -20446,7 +20446,7 @@ /area/station/science/xenobiology) "fFD" = ( /obj/structure/cable, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) "fFJ" = ( @@ -21688,7 +21688,7 @@ /turf/open/floor/carpet, /area/station/service/theater) "gdY" = ( -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 3 }, /turf/open/floor/wood, @@ -27647,7 +27647,7 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "isH" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/science/research) "isK" = ( @@ -32142,7 +32142,7 @@ /area/station/maintenance/port/fore) "kjv" = ( /obj/effect/decal/cleanable/cobweb, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/service/library) "kjG" = ( @@ -32872,7 +32872,7 @@ /turf/open/floor/iron, /area/station/commons/locker) "kyN" = ( -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 3 }, /turf/open/floor/iron/dark, @@ -34266,7 +34266,7 @@ /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/medical/office) "lcd" = ( @@ -54456,7 +54456,7 @@ /turf/open/floor/plating, /area/station/maintenance/port/aft) "sJV" = ( -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 3 }, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -54635,7 +54635,7 @@ /turf/open/floor/iron/dark, /area/station/service/chapel) "sOr" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/camera/directional/east{ c_tag = "Law Office" }, @@ -64771,7 +64771,7 @@ /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) "wNe" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 8 }, diff --git a/_maps/map_files/NebulaStation/NebulaStation.dmm b/_maps/map_files/NebulaStation/NebulaStation.dmm index a503bca5c450..2f537e54506e 100644 --- a/_maps/map_files/NebulaStation/NebulaStation.dmm +++ b/_maps/map_files/NebulaStation/NebulaStation.dmm @@ -4764,7 +4764,7 @@ /turf/open/floor/iron/dark, /area/station/medical/morgue) "aKP" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/bot, /obj/structure/sign/calendar/directional/north, /turf/open/floor/iron/dark/textured_large, @@ -7074,7 +7074,7 @@ }, /area/station/engineering/atmos/storage) "bcE" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/bot_white, /turf/open/floor/iron/dark/textured, /area/station/security/office) @@ -7575,7 +7575,7 @@ dir = 1 }, /obj/effect/turf_decal/siding/wood, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/north, /turf/open/floor/wood/large, /area/station/security/detectives_office) @@ -28968,7 +28968,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/camera/autoname/directional/east, /turf/open/floor/wood/large, /area/station/service/lawoffice) @@ -29263,7 +29263,7 @@ /obj/effect/turf_decal/siding/wood/corner{ dir = 8 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood/large, /area/station/service/library) "eqr" = ( @@ -32849,7 +32849,7 @@ /turf/open/floor/iron/dark, /area/station/cargo/storage) "eSx" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, /turf/open/floor/iron/dark, @@ -34560,7 +34560,7 @@ /area/station/maintenance/port/aft) "ffC" = ( /obj/effect/turf_decal/siding/wood/end, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood/large, /area/station/service/chapel/office) "ffE" = ( @@ -45004,7 +45004,7 @@ /turf/open/floor/iron/dark/textured, /area/station/commons/fitness/recreation) "gIo" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood{ dir = 5 }, @@ -50104,7 +50104,7 @@ dir = 10 }, /obj/machinery/firealarm/directional/south, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/cargo/office) "hvR" = ( @@ -70321,7 +70321,7 @@ /turf/open/floor/iron/dark, /area/station/hallway/primary/port) "ksS" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/structure/sign/flag/ssc/directional/south, /turf/open/floor/iron/dark, /area/station/command/meeting_room) @@ -75122,7 +75122,7 @@ dir = 4 }, /obj/machinery/light_switch/directional/west, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/command) "lfg" = ( @@ -82169,7 +82169,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 6 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood/large, /area/station/command/heads_quarters/ce) "mkx" = ( @@ -84746,7 +84746,7 @@ /obj/effect/turf_decal/siding/thinplating_new/dark/corner{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/camera/autoname/directional/south, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/lobby) @@ -99845,7 +99845,7 @@ /obj/effect/turf_decal/siding/wood/corner{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood/large, /area/station/service/library/upper) "oQA" = ( @@ -123360,7 +123360,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 9 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/toy/figure/hos{ pixel_y = 12; pixel_x = 3 @@ -140328,7 +140328,7 @@ /turf/open/floor/iron/dark, /area/station/hallway/secondary/service) "uVy" = ( -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 4 }, /obj/effect/turf_decal/siding/wood{ @@ -142364,7 +142364,7 @@ }, /obj/effect/turf_decal/trimline/white/line, /obj/structure/table/reinforced/rglass, -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 4 }, /turf/open/floor/iron/dark/textured_large, @@ -150554,7 +150554,7 @@ /turf/open/floor/plating, /area/station/maintenance/department/science) "wwD" = ( -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 3 }, /obj/machinery/newscaster/directional/north, @@ -151376,7 +151376,7 @@ /turf/open/misc/asteroid/airless, /area/space/nearstation) "wCZ" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood{ dir = 6 }, @@ -157183,7 +157183,7 @@ }, /obj/machinery/airalarm/directional/east, /obj/structure/table/glass, -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 5 }, /turf/open/floor/iron/white, diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 8aca9bf29ad1..bb83ed43d2c0 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -9869,7 +9869,7 @@ /turf/open/floor/iron/white, /area/station/medical/office) "cuK" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hop) "cuL" = ( @@ -41052,7 +41052,7 @@ /turf/open/floor/engine, /area/station/maintenance/floor4/starboard/aft) "kFJ" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/camera/autoname/directional/north, /obj/machinery/light_switch/directional/north, /turf/open/floor/wood/tile, @@ -50770,7 +50770,7 @@ }, /area/station/commons/fitness/recreation) "naI" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/purple/opposingcorners, /turf/open/floor/iron/white, /area/station/science/circuits) @@ -53740,7 +53740,7 @@ /turf/open/floor/iron/dark, /area/station/hallway/floor4/aft) "nMD" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/half{ dir = 1 }, @@ -54640,7 +54640,7 @@ /turf/open/floor/iron, /area/station/hallway/floor3/aft) "nXJ" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/science/lower) "nXO" = ( @@ -55727,7 +55727,7 @@ "omG" = ( /obj/effect/turf_decal/bot, /obj/effect/turf_decal/bot, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark/textured_large, /area/station/service/library/printer) "omK" = ( @@ -57408,7 +57408,7 @@ /turf/open/floor/iron/dark/smooth_large, /area/station/engineering/storage/tech) "oKD" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/requests_console/directional/west{ department = "Detective"; name = "Detective Requests Console" @@ -58506,7 +58506,7 @@ "oYL" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/carpet, /area/station/command/heads_quarters/captain) "oYT" = ( @@ -61804,7 +61804,7 @@ }, /obj/structure/window/reinforced/spawner/directional/west, /obj/machinery/status_display/ai/directional/south, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark/side{ dir = 8 }, @@ -70343,7 +70343,7 @@ /turf/open/floor/plating, /area/station/maintenance/floor4/port/aft) "sfR" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood/parquet, /area/station/service/lawoffice) diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 6964f67be16d..181d04a347bb 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -360,7 +360,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 8 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/command/bridge) "abn" = ( @@ -576,6 +576,7 @@ dir = 2 }, /obj/machinery/meter/layer4, +/obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/solars/port/fore) "abU" = ( @@ -1620,7 +1621,7 @@ /turf/open/floor/iron/dark/side, /area/station/command/heads_quarters/hop) "aeL" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/side, /area/station/command/heads_quarters/hop) @@ -2288,11 +2289,18 @@ /area/station/command/heads_quarters/hop) "agr" = ( /obj/structure/table/wood, -/obj/item/paper_bin, +/obj/item/paper_bin{ + pixel_y = 2; + pixel_x = 2 + }, /obj/item/pen, /obj/item/stamp/head/hop, /obj/effect/mapping_helpers/broken_floor, /obj/structure/cable, +/obj/item/ashtray{ + pixel_y = -5; + pixel_x = -8 + }, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) "ags" = ( @@ -2492,6 +2500,10 @@ /obj/item/folder/blue, /obj/item/melee/chainofcommand, /obj/item/stamp/head/captain, +/obj/item/ashtray{ + pixel_y = 12; + pixel_x = -6 + }, /turf/open/floor/carpet/royalblue, /area/station/command/heads_quarters/captain/private) "agR" = ( @@ -2786,6 +2798,10 @@ /obj/structure/table/wood, /obj/item/folder/red, /obj/item/stamp/head/hos, +/obj/item/ashtray{ + pixel_y = 12; + pixel_x = -6 + }, /turf/open/floor/carpet/red, /area/station/command/heads_quarters/hos) "ahF" = ( @@ -2837,7 +2853,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/newscaster/directional/south, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/captain/private) "ahM" = ( @@ -3614,7 +3630,7 @@ /obj/effect/turf_decal/tile/brown{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron, /area/station/cargo/storage) "ajO" = ( @@ -3630,7 +3646,7 @@ /turf/open/floor/plating, /area/station/security/prison) "ajR" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/firealarm/directional/west{ pixel_y = -5 }, @@ -3699,6 +3715,10 @@ dir = 8 }, /obj/machinery/newscaster/directional/east, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = -7 + }, /turf/open/floor/iron/dark, /area/station/hallway/primary/fore) "ajW" = ( @@ -4701,6 +4721,10 @@ c_tag = "Engineering - Chief Engineer's Office"; network = list("ss13","engine","heads") }, +/obj/item/ashtray{ + pixel_y = -5; + pixel_x = -8 + }, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/ce) "amG" = ( @@ -5610,6 +5634,10 @@ }, /obj/item/gavelhammer, /obj/machinery/airalarm/directional/south, +/obj/item/ashtray{ + pixel_y = -4; + pixel_x = -2 + }, /turf/open/floor/carpet/green, /area/station/service/lawoffice) "aoE" = ( @@ -5840,13 +5868,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/cargo/miningdock) -"apn" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "apo" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -7418,7 +7439,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, /obj/structure/table/wood, -/obj/item/stack/medical/gauze/improvised, +/obj/item/stack/medical/wrap/gauze/improvised, /obj/item/restraints/handcuffs/cable, /turf/open/floor/wood, /area/station/maintenance/department/science) @@ -7482,7 +7503,7 @@ "atC" = ( /obj/effect/decal/cleanable/cobweb, /obj/effect/mapping_helpers/broken_floor, -/obj/machinery/photocopier/gratis, +/obj/machinery/photocopier/gratis/prebuilt, /obj/machinery/airalarm/directional/west, /turf/open/floor/wood, /area/station/maintenance/department/science) @@ -8038,6 +8059,10 @@ /obj/effect/turf_decal/siding/wood{ dir = 8 }, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = 5 + }, /turf/open/floor/iron/dark/side{ dir = 8 }, @@ -8504,6 +8529,7 @@ "awX" = ( /obj/structure/table/reinforced, /obj/effect/turf_decal/tile/neutral, +/obj/item/ashtray/random_contents, /turf/open/floor/iron/dark/side{ dir = 4 }, @@ -9178,6 +9204,10 @@ /obj/effect/turf_decal/siding/wood{ dir = 8 }, +/obj/item/ashtray{ + pixel_y = -4; + pixel_x = 5 + }, /turf/open/floor/iron/dark/side{ dir = 8 }, @@ -9877,6 +9907,10 @@ /obj/structure/table/reinforced, /obj/item/folder/red, /obj/effect/turf_decal/stripes/line, +/obj/item/ashtray{ + pixel_y = -3; + pixel_x = -8 + }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) "aBg" = ( @@ -10843,6 +10877,7 @@ "aEa" = ( /obj/structure/table, /obj/effect/turf_decal/delivery, +/obj/item/storage/medkit/emergency, /turf/open/floor/iron/dark/side{ dir = 4 }, @@ -11168,6 +11203,10 @@ name = "Station Intercom"; pixel_y = -26 }, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = 5 + }, /turf/open/floor/iron/dark/side, /area/station/service/theater) "aEU" = ( @@ -11423,9 +11462,8 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/atmospherics/components/unary/airlock_pump/unbolt_only{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/department/cargo) "aFC" = ( @@ -11486,7 +11524,6 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/obj/item/kirbyplants/organic/plant22, /obj/machinery/camera/directional/west{ c_tag = "Cafeteria - Aft"; network = list("ss13","service") @@ -11535,6 +11572,10 @@ /obj/item/storage/fancy/donut_box{ pixel_y = 15 }, +/obj/item/ashtray{ + pixel_y = 3; + pixel_x = -4 + }, /turf/open/floor/iron, /area/station/service/kitchen) "aFR" = ( @@ -12273,6 +12314,7 @@ }, /obj/machinery/status_display/ai/directional/east, /obj/machinery/light/directional/east, +/obj/item/kirbyplants/organic/plant21, /turf/open/floor/iron, /area/station/service/cafeteria) "aHW" = ( @@ -12654,6 +12696,7 @@ }, /obj/effect/turf_decal/tile/red/opposingcorners, /obj/machinery/newscaster/directional/east, +/obj/machinery/restaurant_portal/restaurant, /turf/open/floor/iron, /area/station/service/cafeteria) "aIR" = ( @@ -12766,6 +12809,10 @@ pixel_y = 7; pixel_x = 7 }, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = -8 + }, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/cmo) "aJg" = ( @@ -13105,9 +13152,9 @@ dir = 8 }, /obj/effect/turf_decal/tile/red/opposingcorners, -/obj/item/kirbyplants/organic/plant21, /obj/structure/sign/poster/official/random/directional/east, /obj/effect/landmark/start/hangover, +/obj/structure/closet/crate/bin, /turf/open/floor/iron, /area/station/service/cafeteria) "aJY" = ( @@ -13174,6 +13221,10 @@ req_access = list("cargo") }, /obj/effect/turf_decal/delivery, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = -8 + }, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) "aKj" = ( @@ -13193,6 +13244,7 @@ dir = 1 }, /obj/effect/landmark/event_spawn, +/mob/living/basic/bot/cleanbot/medbay, /turf/open/floor/iron/white, /area/station/medical/treatment_center) "aKm" = ( @@ -13636,7 +13688,7 @@ /turf/open/floor/iron, /area/station/service/cafeteria) "aLg" = ( -/obj/machinery/restaurant_portal/restaurant, +/obj/machinery/vending/coffee, /turf/open/floor/iron/dark/side{ dir = 4 }, @@ -13990,6 +14042,7 @@ dir = 4 }, /obj/structure/table/reinforced, +/obj/item/storage/medkit/emergency, /turf/open/floor/iron, /area/station/engineering/main) "aMe" = ( @@ -15045,7 +15098,7 @@ /area/station/science/lab) "aOY" = ( /obj/structure/table/reinforced, -/obj/item/stack/medical/gauze{ +/obj/item/stack/medical/wrap/gauze{ pixel_x = 8 }, /obj/item/stack/medical/suture, @@ -15069,7 +15122,6 @@ }, /obj/machinery/airalarm/directional/east, /obj/machinery/camera/autoname/directional/east, -/obj/machinery/light/small/directional/east, /turf/open/floor/iron/white, /area/station/commons/long_term_storage) "aPc" = ( @@ -16616,6 +16668,10 @@ }, /obj/structure/table/reinforced, /obj/structure/sign/poster/official/ue_no/directional/north, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = -8 + }, /turf/open/floor/iron, /area/station/command/heads_quarters/rd) "aTp" = ( @@ -16691,11 +16747,15 @@ /area/station/science/ordnance/testlab) "aTy" = ( /obj/structure/table/wood, -/obj/item/flashlight/lamp, +/obj/item/flashlight/lamp{ + pixel_y = 5; + pixel_x = -3 + }, /obj/machinery/status_display/evac/directional/north, /obj/effect/turf_decal/siding/thinplating{ dir = 8 }, +/obj/item/stack/medical/wrap/gauze, /turf/open/floor/iron/grimy, /area/station/hallway/primary/aft) "aTz" = ( @@ -16795,19 +16855,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/science/lab) -"aTM" = ( -/obj/machinery/door/airlock/external{ - name = "External Docking Port" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/hallway/secondary/exit/departure_lounge) "aTO" = ( /obj/machinery/door/airlock/maintenance_hatch{ name = "Science Maintenance" @@ -16822,6 +16869,9 @@ "aTS" = ( /obj/effect/landmark/blobstart, /obj/effect/mapping_helpers/burnt_floor, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, /turf/open/floor/plating, /area/station/maintenance/department/science) "aTU" = ( @@ -16890,7 +16940,7 @@ /turf/closed/wall/rust, /area/station/maintenance/department/engine) "aUj" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood{ dir = 8 }, @@ -17125,6 +17175,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/effect/mapping_helpers/cycling_airlock_old/marker/inner_door{ + dir = 2 + }, /turf/open/floor/iron, /area/station/medical/virology) "aUL" = ( @@ -17493,6 +17546,10 @@ "aVP" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = -8 + }, /turf/open/floor/iron/dark/side{ dir = 10 }, @@ -17862,6 +17919,10 @@ /obj/machinery/camera/directional/east{ c_tag = "Library - Starboard" }, +/obj/item/ashtray{ + pixel_y = -2; + pixel_x = -8 + }, /turf/open/floor/iron/dark, /area/station/service/library) "aWH" = ( @@ -17899,6 +17960,9 @@ /obj/structure/cable, /obj/machinery/airalarm/directional/north, /obj/machinery/light/small/directional/north, +/obj/effect/mapping_helpers/cycling_airlock_old{ + access = list("virology") + }, /turf/open/floor/iron/white, /area/station/medical/virology) "aWL" = ( @@ -17906,7 +17970,9 @@ dir = 8 }, /obj/machinery/duct, -/obj/machinery/firealarm/directional/east, +/obj/machinery/firealarm/directional/east{ + pixel_y = -6 + }, /obj/effect/turf_decal/stripes/line{ dir = 4 }, @@ -17980,6 +18046,10 @@ /obj/effect/turf_decal/siding/thinplating{ dir = 4 }, +/obj/item/ashtray{ + pixel_y = 3; + pixel_x = -4 + }, /turf/open/floor/iron/grimy, /area/station/hallway/primary/aft) "aWU" = ( @@ -18049,6 +18119,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/effect/mapping_helpers/cycling_airlock_old/marker/outer_door{ + dir = 2 + }, /turf/open/floor/iron/white, /area/station/maintenance/department/medical) "aXe" = ( @@ -18310,7 +18383,6 @@ /obj/structure/sign/warning/secure_area/directional/west{ pixel_y = -32 }, -/obj/structure/sign/departments/virology/directional/west, /turf/open/floor/plating, /area/station/maintenance/department/medical) "aXP" = ( @@ -18355,7 +18427,7 @@ /area/station/medical/treatment_center) "aXT" = ( /obj/structure/table/reinforced, -/obj/item/stack/medical/gauze{ +/obj/item/stack/medical/wrap/gauze{ pixel_x = 8 }, /obj/item/stack/medical/mesh, @@ -18553,6 +18625,9 @@ c_tag = "Medical - Virology Airlock"; network = list("ss13","medbay","viro") }, +/obj/machinery/firealarm/directional/west{ + pixel_y = -6 + }, /turf/open/floor/iron/white, /area/station/medical/virology) "aYA" = ( @@ -20106,6 +20181,9 @@ /obj/effect/turf_decal/caution{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/airlock_pump/unbolt_only{ + dir = 8 + }, /turf/open/floor/iron, /area/station/maintenance/department/cargo) "bcL" = ( @@ -21327,11 +21405,11 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 }, -/obj/item/radio/intercom/directional/south, /obj/effect/turf_decal/siding/green, /obj/effect/turf_decal/trimline/green/end{ dir = 1 }, +/obj/structure/sign/departments/virology/directional/south, /turf/open/floor/iron/white, /area/station/medical/virology) "bfN" = ( @@ -21775,7 +21853,8 @@ "bhp" = ( /obj/machinery/door/morgue{ name = "Relic Closet"; - req_one_access = list("chapel_office", "crematorium") + req_one_access = list("chapel_office", "crematorium"); + dir = 1 }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -22442,7 +22521,7 @@ /turf/open/floor/circuit/telecomms, /area/station/science/xenobiology) "bjJ" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/radio/intercom/directional/west, /obj/machinery/computer/security/telescreen/entertainment/directional/south, /turf/open/floor/iron/grimy, @@ -22584,6 +22663,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, +/mob/living/basic/bot/medbot/autopatrol, /turf/open/floor/iron, /area/station/medical/treatment_center) "bkt" = ( @@ -23722,7 +23802,6 @@ /turf/open/floor/iron, /area/station/hallway/primary/fore) "bNe" = ( -/obj/structure/closet/crate/bin, /obj/effect/landmark/start/hangover, /turf/open/floor/iron/dark/side{ dir = 8 @@ -23924,7 +24003,7 @@ /obj/effect/turf_decal/siding/wood{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/item/newspaper{ pixel_x = 3; pixel_y = 3 @@ -23966,18 +24045,14 @@ }, /area/station/hallway/secondary/service) "cgi" = ( -/obj/effect/turf_decal/caution{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 8 }, -/obj/machinery/atmospherics/components/unary/airlock_pump{ +/obj/effect/turf_decal/caution{ dir = 8 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/department/science) "cgO" = ( @@ -24118,8 +24193,15 @@ /turf/open/floor/iron, /area/station/service/hydroponics) "cpo" = ( -/obj/machinery/vending/coffee, /obj/structure/sign/warning/doors/directional/south, +/obj/structure/table, +/obj/effect/spawner/random/trash/food_packaging, +/obj/effect/spawner/random/trash/cigbutt, +/obj/effect/spawner/random/trash/cigbutt, +/obj/item/ashtray{ + pixel_y = 3; + pixel_x = -4 + }, /turf/open/floor/iron/dark/side{ dir = 10 }, @@ -25744,7 +25826,6 @@ /area/station/science/ordnance/testlab) "fcU" = ( /obj/item/cigbutt, -/obj/structure/sign/warning/secure_area/directional/south, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -25872,6 +25953,7 @@ /obj/structure/sign/nanotrasen{ pixel_y = -32 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron{ heat_capacity = 1e+006 }, @@ -29773,6 +29855,15 @@ }, /turf/open/floor/iron, /area/station/security/prison) +"mdS" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/airlock_pump{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/maintenance/department/science) "meo" = ( /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=5.2-Cargo"; @@ -29878,6 +29969,9 @@ dir = 1 }, /area/station/hallway/secondary/entry) +"mlz" = ( +/turf/closed/wall/r_wall/rust, +/area/station/maintenance/department/medical) "mmf" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -29892,6 +29986,7 @@ dir = 1 }, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/aft) "mmW" = ( @@ -30026,6 +30121,12 @@ /obj/item/inspector, /turf/open/floor/iron, /area/station/security/brig) +"mtl" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/ashtray/random_contents, +/turf/open/floor/iron, +/area/station/service/cafeteria) "mvj" = ( /obj/machinery/atmospherics/pipe/smart/simple/supply/hidden{ dir = 9 @@ -30462,9 +30563,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer5, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"nhh" = ( -/turf/closed/wall, -/area/space) "nhB" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, @@ -31211,6 +31309,7 @@ dir = 1 }, /obj/effect/turf_decal/tile/neutral/anticorner/contrasted, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/aft) "oCy" = ( @@ -32539,6 +32638,15 @@ }, /turf/open/floor/iron/dark/corner, /area/station/cargo/bitrunning/den) +"qQo" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "qQO" = ( /obj/machinery/door/firedoor, /obj/structure/sign/departments/medbay/alt/directional/south, @@ -32555,7 +32663,7 @@ /turf/open/floor/iron, /area/station/hallway/primary/central) "qRz" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/newscaster/directional/east, /turf/open/floor/carpet/green, /area/station/service/lawoffice) @@ -33022,6 +33130,7 @@ /area/space/nearstation) "rFA" = ( /obj/structure/table, +/obj/item/storage/medkit/emergency, /turf/open/floor/iron, /area/station/commons/dorms) "rIZ" = ( @@ -33070,6 +33179,21 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/supermatter/room) +"rMs" = ( +/obj/effect/turf_decal/tile/red{ + dir = 1 + }, +/obj/effect/turf_decal/tile/red, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/effect/landmark/start/hangover, +/obj/item/kirbyplants/organic/plant21, +/turf/open/floor/iron, +/area/station/service/cafeteria) "rOb" = ( /obj/machinery/atmospherics/pipe/smart/simple/orange/hidden{ dir = 4 @@ -33753,6 +33877,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, +/obj/machinery/light/cold/dim/directional/south, /turf/open/floor/iron/white, /area/station/commons/long_term_storage) "sHz" = ( @@ -34417,6 +34542,10 @@ pixel_x = 7; pixel_y = 2 }, +/obj/item/ashtray{ + pixel_y = -5; + pixel_x = -8 + }, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) "sMe" = ( @@ -35208,6 +35337,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer5, /turf/open/floor/iron/white/corner, /area/station/hallway/primary/starboard) +"tbZ" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/hallway/secondary/entry) "tdz" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/table, @@ -35267,6 +35402,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/ashtray{ + pixel_y = 6; + pixel_x = 2 + }, /turf/open/floor/iron, /area/station/service/cafeteria) "tin" = ( @@ -35328,6 +35467,7 @@ /obj/effect/mapping_helpers/airlock/unres{ dir = 4 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/science) "tlg" = ( @@ -35344,6 +35484,7 @@ dir = 1 }, /obj/effect/turf_decal/tile/neutral, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white/corner{ dir = 8 }, @@ -35666,6 +35807,13 @@ /obj/effect/landmark/start/station_engineer, /turf/open/floor/iron, /area/station/engineering/main) +"tVj" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/hallway/primary/aft) "tVp" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, @@ -35690,7 +35838,8 @@ }, /obj/machinery/door/morgue{ name = "Curator's Study"; - req_access = list("library") + req_access = list("library"); + dir = 1 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, @@ -36091,6 +36240,7 @@ /obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron{ heat_capacity = 1e+006 }, @@ -36148,6 +36298,12 @@ /obj/machinery/iv_drip, /turf/open/floor/iron, /area/station/medical/treatment_center) +"uAP" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/hallway/secondary/exit/departure_lounge) "uBJ" = ( /obj/machinery/computer/security{ dir = 1 @@ -36892,6 +37048,7 @@ /area/station/science/breakroom) "wdt" = ( /obj/effect/turf_decal/bot, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/side{ dir = 4 }, @@ -37172,6 +37329,13 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/cargo/storage) +"wAa" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/department/science) "wAw" = ( /turf/open/space, /area/space) @@ -37994,6 +38158,10 @@ /obj/effect/turf_decal/siding/wood{ dir = 1 }, +/obj/item/ashtray{ + pixel_y = -2; + pixel_x = -8 + }, /turf/open/floor/iron/dark, /area/station/service/library) "xSs" = ( @@ -38067,7 +38235,6 @@ /turf/open/floor/iron/dark, /area/station/science/ordnance/storage) "xZz" = ( -/obj/item/kirbyplants/organic/plant22, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/yellow{ dir = 4 @@ -38079,6 +38246,7 @@ dir = 1 }, /obj/effect/landmark/start/hangover, +/obj/structure/tank_holder/extinguisher, /turf/open/floor/iron, /area/station/service/cafeteria) "xZL" = ( @@ -38295,10 +38463,10 @@ dir = 6 }, /obj/structure/closet/l3closet/virology, -/obj/machinery/firealarm/directional/south, /obj/effect/turf_decal/siding/green{ dir = 6 }, +/obj/item/radio/intercom/directional/south, /turf/open/floor/iron/white, /area/station/medical/virology) "ylH" = ( @@ -63922,7 +64090,7 @@ aSs aUl aKm ayM -bea +mlz aWJ bfM bea @@ -64179,7 +64347,7 @@ aTb aUp aTU jXv -aKV +bxN aWM ylF aKV @@ -68307,7 +68475,7 @@ aaa aaa aaa aaa -aaa +bwz aaa aaa aaa @@ -68563,15 +68731,15 @@ aaa aaa aaa aaa -aaa -bwz -aaa -aaa -aaa -aaa +bgU +bkj +bgU aaa aaa aaa +bgU +bkj +bgU aaa aaa aaa @@ -68821,13 +68989,13 @@ aaa aaa aaa bgU -bkj +eIU bgU sdX sdX sdX bgU -bkj +eIU bgU aaa aaa @@ -69078,13 +69246,13 @@ aae aae aae bgU -eIU +tbZ bgU bgP bgU bgP bgU -eIU +tbZ bgU aae aae @@ -70363,13 +70531,13 @@ aae aae aae bgU -bki +tbZ bgU bgP bgU bgP bgU -bki +tbZ bgU aae aae @@ -70620,13 +70788,13 @@ aaa aaa aaa bgU -btl +bki bgU sdX sdX sdX bgU -btl +bki bgU aaa aaa @@ -70876,15 +71044,15 @@ aaa aaa aaa aaa +bgU +btl +bgU aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa +bgU +btl +bgU aaa aaa aaa @@ -71401,7 +71569,7 @@ aaa aaa aaa aaa -lUq +aaa aaa aaa aaa @@ -71658,7 +71826,7 @@ aaa aaa aaa aaa -aaa +lUq aaa aaa aaa @@ -71850,7 +72018,7 @@ auc pcN avg awl -aBZ +mtl gpG rdB eZj @@ -71861,7 +72029,7 @@ eZj oTd aFO kcP -aBZ +mtl sAA pcN auc @@ -72379,7 +72547,7 @@ vPL vPL asg hDi -ubG +rMs arb aOq aPn @@ -72658,7 +72826,7 @@ bcq bfJ aDE bfJ -aDE +tVj qks rJx bhH @@ -73686,7 +73854,7 @@ bcu bdm beh sKP -xKp +wAa sJL pej hrd @@ -79295,7 +79463,7 @@ aaa aae amD aol -gtS +qQo aqu amD aae @@ -79552,7 +79720,7 @@ aaa aae ant aom -apn +gtS aqv nzE aae @@ -79862,7 +80030,7 @@ eBJ aiQ pMh pMh -sKH +mdS pMh uTo aaa @@ -80118,8 +80286,9 @@ aiQ aiQ aiQ aiQ -aiQ -bvg +pMh +sKH +pMh uTo aaa aaa @@ -80210,7 +80379,6 @@ aaa aaa aaa aaa -aaa "} (164,1,1) = {" aaa @@ -80376,6 +80544,7 @@ aiQ aiQ aiQ aiQ +bvg uTo aaa aaa @@ -80467,7 +80636,6 @@ aaa aaa aaa aaa -aaa "} (165,1,1) = {" aaa @@ -80632,7 +80800,7 @@ aiQ aiQ aiQ aiQ -aaa +aiQ aaa aaa aaa @@ -80887,8 +81055,8 @@ aDw imR ozW aHq -aaa -aaa +aiQ +uTo aaa aaa aaa @@ -82130,7 +82298,7 @@ aaa aaa aaf aae -nhh +aKh sDP azb azb @@ -82142,7 +82310,7 @@ aKh aGc aKh azb -aTM +aBh aCn aBh azb @@ -82391,17 +82559,17 @@ rel aae aae azb -aDh +uAP azb -aDh +uAP azb aae aae aae azb -aDh +uAP azb -aDh +uAP azb aae rel @@ -82648,17 +82816,17 @@ aaa aaa aaa azb -fWz +aDh azb -fWz +aDh azb -aaa -aaa -aaa +aae +aae +aae azb -fWz +aDh azb -fWz +aDh azb aaa aaa @@ -82671,7 +82839,7 @@ aaa aaa aaa aaa -jYq +aae uTo xUx uTo @@ -82904,19 +83072,19 @@ aaa aaa aaa aaa +azb +fWz +azb +fWz +azb aaa aaa aaa -fsl -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +azb +fWz +azb +fWz +azb aaa aaa aaa @@ -83164,7 +83332,7 @@ aaa aaa aaa aaa -aaa +fsl aaa aaa aaa diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 501ef891da57..3091f52612ab 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -2685,7 +2685,7 @@ /turf/open/floor/iron/large, /area/station/security) "ajp" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/computer/security/telescreen/entertainment/directional/north, /turf/open/floor/iron/large, /area/station/security) @@ -7981,7 +7981,7 @@ /turf/open/floor/wood, /area/station/command/heads_quarters/hop) "aBC" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/airalarm/directional/north, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) @@ -10460,7 +10460,7 @@ /turf/open/floor/iron, /area/station/commons/storage/art) "aLz" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -21119,7 +21119,7 @@ /obj/machinery/light_switch/directional/east{ name = "Light Switch" }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) "bDy" = ( @@ -28283,7 +28283,7 @@ /turf/open/floor/plating, /area/station/maintenance/department/chapel/monastery) "ckl" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/light/small/directional/west, /turf/open/floor/iron/dark/smooth_large, /area/station/service/library/lounge) @@ -33008,7 +33008,7 @@ /obj/effect/turf_decal/trimline/brown/filled/line, /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/station/cargo/sorting) "dWk" = ( @@ -40117,7 +40117,7 @@ /area/station/cargo/storage) "jdj" = ( /obj/structure/disposalpipe/segment, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/siding/wood/corner{ dir = 8 }, @@ -42600,7 +42600,7 @@ /obj/effect/turf_decal/tile/yellow/half{ dir = 4 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/edge{ dir = 4 }, @@ -42979,7 +42979,7 @@ /turf/open/floor/plating, /area/station/maintenance/department/cargo) "lui" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/station/security/detectives_office) "luA" = ( @@ -59405,7 +59405,7 @@ /turf/open/floor/iron/dark/smooth_edge, /area/station/command/heads_quarters/rd) "wrU" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, /turf/open/floor/wood, diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index f0d3d9663262..3930eb7343ea 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -909,7 +909,7 @@ /turf/open/floor/grass, /area/centcom/central_command_areas/control) "hx" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/briefing) "hz" = ( @@ -2872,7 +2872,7 @@ /turf/open/floor/iron, /area/centcom/central_command_areas/supply) "ou" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -4641,7 +4641,7 @@ /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) "vJ" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/machinery/button/door/indestructible{ id = "XCCFerry"; name = "Hanger Bay Shutters"; diff --git a/_maps/map_files/tramstation/maintenance_modules/secbarupper_attachment_a_1.dmm b/_maps/map_files/tramstation/maintenance_modules/secbarupper_attachment_a_1.dmm index c709ff932851..e4c4505d62e2 100644 --- a/_maps/map_files/tramstation/maintenance_modules/secbarupper_attachment_a_1.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/secbarupper_attachment_a_1.dmm @@ -85,7 +85,7 @@ /area/station/maintenance/department/security) "Q" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/smooth, /area/station/maintenance/department/security) "T" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 697c14b8f9a8..f38086a022e1 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -6241,7 +6241,7 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/central) "bbM" = ( -/obj/machinery/photocopier{ +/obj/machinery/photocopier/prebuilt{ pixel_y = 3 }, /obj/structure/sign/clock/directional/west, @@ -6721,7 +6721,7 @@ /area/station/engineering/atmos/pumproom) "bnh" = ( /obj/item/radio/intercom/directional/north, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/wood, /area/station/service/lawoffice) "bnY" = ( @@ -19880,7 +19880,7 @@ /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 8 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/white, /area/station/science/lower) "gbp" = ( @@ -39022,7 +39022,7 @@ /turf/open/floor/iron, /area/station/cargo/sorting) "mNV" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/grimy, /area/station/service/library/lounge) "mOi" = ( @@ -51979,7 +51979,7 @@ /turf/open/floor/iron, /area/station/commons/dorms) "rxN" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) @@ -61265,7 +61265,7 @@ /area/station/cargo/miningdock) "uHb" = ( /obj/machinery/airalarm/directional/north, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/brown/fourcorners, /turf/open/floor/iron, /area/station/cargo/sorting) @@ -66266,7 +66266,7 @@ /obj/effect/turf_decal/trimline/dark_green/filled/corner{ dir = 1 }, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /obj/effect/turf_decal/tile/purple/fourcorners, /turf/open/floor/iron/white, /area/station/science/research) diff --git a/_maps/shuttles/emergency_monastery.dmm b/_maps/shuttles/emergency_monastery.dmm index 07a9ef7acdc6..5f89a426c1a3 100644 --- a/_maps/shuttles/emergency_monastery.dmm +++ b/_maps/shuttles/emergency_monastery.dmm @@ -556,7 +556,7 @@ /area/shuttle/escape) "iB" = ( /obj/machinery/light/small/directional/west, -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/iron/dark, /area/shuttle/escape) "iE" = ( diff --git a/_maps/shuttles/pirate_irs.dmm b/_maps/shuttles/pirate_irs.dmm index 82c0ac6185b6..838b0080347b 100644 --- a/_maps/shuttles/pirate_irs.dmm +++ b/_maps/shuttles/pirate_irs.dmm @@ -1721,7 +1721,7 @@ /turf/open/floor/iron, /area/shuttle/pirate) "SQ" = ( -/obj/machinery/photocopier/gratis, +/obj/machinery/photocopier/gratis/prebuilt, /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/white, /area/shuttle/pirate) diff --git a/_maps/templates/lazy_templates/ninja_den.dmm b/_maps/templates/lazy_templates/ninja_den.dmm index 1713ec116bb3..b16e571cc687 100644 --- a/_maps/templates/lazy_templates/ninja_den.dmm +++ b/_maps/templates/lazy_templates/ninja_den.dmm @@ -34,7 +34,7 @@ /turf/open/floor/bamboo/tatami/purple, /area/centcom/central_command_areas/holding) "bH" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/catwalk_floor, /area/centcom/central_command_areas/holding) "bP" = ( diff --git a/_maps/virtual_domains/meta_central.dmm b/_maps/virtual_domains/meta_central.dmm index 024799dcc897..750d22e34700 100644 --- a/_maps/virtual_domains/meta_central.dmm +++ b/_maps/virtual_domains/meta_central.dmm @@ -2174,7 +2174,7 @@ /turf/open/floor/wood, /area/virtual_domain) "rX" = ( -/obj/machinery/photocopier, +/obj/machinery/photocopier/prebuilt, /turf/open/floor/carpet, /area/virtual_domain) "sa" = ( diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm index 391ed0112ac9..5446ab83fcc2 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_lighting.dm @@ -42,3 +42,18 @@ ///Called when an atom has a light template applied to it. Frombase of [/datum/light_template/proc/mirror_onto]: () #define COMSIG_ATOM_LIGHT_TEMPLATE_MIRRORED "atom_light_template_mirrored" + +///Called when an atom's overlay component applies visuals, from base of [/datum/component/overlay_lighting/proc/show_to_holder]: (image/mask, image/cone, atom/movable/light_holder) +#define COMSIG_ATOM_OVERLAY_LIGHT_APPLIED "atom_overlay_light_applied" +///Above, but send to the holder of the light instead of the light source itself: (image/mask, image/cone, atom/movable/light_source) +#define COMSIG_ATOM_HOLDER_OVERLAY_LIGHT_APPLIED "atom_holder_overlay_light_applied" + +///Called when an atom's overlay component hides its visuals, from base of [/datum/component/overlay_lighting/proc/hide_from_holder]: (atom/movable/light_holder) +#define COMSIG_ATOM_OVERLAY_LIGHT_REMOVED "atom_overlay_light_removed" +///Above, but send to the holder of the light instead of the light source itself: (atom/movable/light_source) +#define COMSIG_ATOM_HOLDER_OVERLAY_LIGHT_REMOVED "atom_holder_overlay_light_removed" + +/// Called when a light fixture is broken, from base of [/obj/machinery/light/break_light_tube]: (was_ok) +#define COMSIG_LIGHT_FIXTURE_BROKEN "light_fixture_broken" +/// Called when a light fixture is toggled on or off, from base of [/obj/machinery/light/toggle_light]: (new_status) +#define COMSIG_LIGHT_FIXTURE_TOGGLED "light_fixture_toggled" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index a1303046e1f6..e8dbddc50827 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -310,6 +310,9 @@ #define COMSIG_LIVING_PERCEIVE_EXAMINE_NAME "living_perceive_examine_name" #define COMPONENT_EXAMINE_NAME_OVERRIDEN (1<<0) +/// From /obj/item/book/bible/attack() : (mob/living/user, obj/item/book/bible/bible, bless_result) +#define COMSIG_LIVING_BLESSED "living_blessed" + /// From /datum/element/death_drops/on_death(mob/living/target, gibbed) : (list/loot, gibbed) #define COMSIG_LIVING_DROP_LOOT "living_drop_loot" /// Prevent loot from being dropped diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 986e5290186b..ed3ba0553bf9 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -595,3 +595,32 @@ /// Sent from /obj/effect/rune/convert/try_sacrifice_item(obj/effect/rune/convert/rune) #define COMSIG_ITEM_CULT_SACRIFICE "item_cult_sacrifice" #define COMPONENT_SACRIFICE_SUCCESSFUL (1<<0) + +/// Send to items that have been unwrapped from a gift +#define COMSIG_ITEM_OPENED_FROM_GIFT "gift_opened" + +/// From /obj/machinery/vending/ui_interact(): (mob/user, datum/vending_ui/ui) +#define COMSIG_VENDING_UI_INTERACT "vending_ui_interact" + #define VENDING_DENIED (1<<0) + +/// From /obj/machinery/vending/dispense(): (obj/item/vended_item) +#define COMSIG_VENDING_DISPENSED "vending_dispensed" + +/// From /obj/machinery/vending/vend(): (mob/user, obj/machinery/vending_machine, obj/item/vended_item) +#define COMSIG_MOB_VENDING_PURCHASE "mob_vending_purchase" + /// Stops the mob from picking up whatevr they just purchased (it just goes to the floor) + #define VENDING_NO_PICKUP (1<<0) + +/// Sent from /datum/component/reflection when the reflection is updated to the mob reflecting: (atom/movable/reflecting_in, obj/effect/abstract/reflection) +#define COMSIG_REFLECTION_UPDATED "reflection_updated" + +/// Sent from /datum/component/reflection when the reflection is updated to the component parent: (obj/effect/abstract/reflection) +#define COMSIG_REFLECTED_IMAGE_UPDATED "reflected_image_updated" + +/// From /datum/element/weapon_description: (list/readout) +#define COMSIG_ITEM_WEAPON_LABEL_READOUT "item_weapon_label_readout" + +/// Sent from /obj/machinery/door/airlock/close, to a movable blocking it from closing: (obj/machinery/door/being_blocked, force_close, force_crush) +#define COMSIG_MOVABLE_BLOCKING_AIRLOCK "movable_blocking_airlock" + /// Forces the airlock to crush whatever's blocking it even if it normally wouldn't + #define AIRLOCK_BLOCK_FORCE_CRUSH (1<<0) diff --git a/code/datums/components/crafting/furniture.dm b/code/datums/components/crafting/furniture.dm index 39f5a25a19f8..c03e1d0fc286 100644 --- a/code/datums/components/crafting/furniture.dm +++ b/code/datums/components/crafting/furniture.dm @@ -71,3 +71,37 @@ tool_behaviors = list(TOOL_SCREWDRIVER) category = CAT_FURNITURE time = 10 SECONDS + +/datum/crafting_recipe/lamp + name = "Desk Lamp" + result = /obj/item/flashlight/lamp + reqs = list( + /obj/item/flashlight = 1, + /obj/item/stack/rods = 1, + /obj/item/light/bulb = 1, + ) + // crafting_flags = CRAFT_SKIP_MATERIALS_PARITY + tool_behaviors = list(TOOL_SCREWDRIVER) + category = CAT_FURNITURE + +/datum/crafting_recipe/lamp/New() + . = ..() + blacklist += subtypesof(/obj/item/flashlight) + +/datum/crafting_recipe/lamp/green + name = "Green Desk Lamp" + result = /obj/item/flashlight/lamp/green + +/datum/crafting_recipe/banana_lamp + name = "Banana Lamp" + result = /obj/item/flashlight/lamp/bananalamp + reqs = list( + /obj/item/flashlight/lamp = 1, + /obj/item/grown/bananapeel = 1, + ) + blacklist = list( + /obj/item/flashlight/lamp/bananalamp, + ) + // requirements_mats_blacklist = list(/obj/item/grown/bananapeel) + tool_behaviors = list(TOOL_SCREWDRIVER) + category = CAT_FURNITURE diff --git a/code/datums/components/crafting/tools.dm b/code/datums/components/crafting/tools.dm index 46faafa75613..32b9976c88ca 100644 --- a/code/datums/components/crafting/tools.dm +++ b/code/datums/components/crafting/tools.dm @@ -90,3 +90,15 @@ // crafting_flags = CRAFT_SKIP_MATERIALS_PARITY tool_behaviors = list(TOOL_SCREWDRIVER) category = CAT_TOOLS + +/datum/crafting_recipe/lantern + name = "Lantern" + result = /obj/item/flashlight/lantern + reqs = list( + /obj/item/flashlight/flare/candle = 1, + /obj/item/stack/rods = 1, + /obj/item/stack/sheet/glass = 1, + ) + // crafting_flags = CRAFT_SKIP_MATERIALS_PARITY + tool_behaviors = list(TOOL_SCREWDRIVER) + category = CAT_TOOLS diff --git a/code/datums/components/omen.dm b/code/datums/components/omen.dm index 75cce3ee3d4a..f6aa7ce76689 100644 --- a/code/datums/components/omen.dm +++ b/code/datums/components/omen.dm @@ -16,22 +16,28 @@ var/luck_mod = 1 /// Base damage from negative events. Cursed take 25% of this damage. var/damage_mod = 1 - -/datum/component/omen/Initialize(obj/vessel, incidents_left, luck_mod, damage_mod) + /// If TRUE being blessed by the chaplain can remove the omen + var/bless_fixable = TRUE + /// Callback invoked on death + var/datum/callback/on_death + /// List of light fixtures nearby - we track their state to see if they break or toggle + VAR_FINAL/list/tracked_lights = list() + +/datum/component/omen/Initialize(obj/vessel, incidents_left = INFINITY, luck_mod = 1, damage_mod = 1, bless_fixable = TRUE, datum/callback/on_death) if(!isliving(parent)) return COMPONENT_INCOMPATIBLE if(istype(vessel)) src.vessel = vessel RegisterSignal(vessel, COMSIG_QDELETING, PROC_REF(vessel_qdeleting)) - if(!isnull(incidents_left)) - src.incidents_left = incidents_left - if(!isnull(luck_mod)) - src.luck_mod = luck_mod - if(!isnull(damage_mod)) - src.damage_mod = damage_mod - ADD_TRAIT(parent, TRAIT_CURSED, SMITE_TRAIT) + src.incidents_left = incidents_left + src.luck_mod = luck_mod + src.damage_mod = damage_mod + src.bless_fixable = bless_fixable + src.on_death = on_death + + ADD_TRAIT(parent, TRAIT_CURSED, REF(src)) /** * This is a omen eat omen world! The stronger omen survives. @@ -52,7 +58,8 @@ /datum/component/omen/Destroy(force) var/mob/living/person = parent - REMOVE_TRAIT(person, TRAIT_CURSED, SMITE_TRAIT) + REMOVE_TRAIT(person, TRAIT_CURSED, REF(src)) + REMOVE_TRAIT(person, TRAIT_NO_MIRROR_REFLECTION, REF(src)) to_chat(person, span_nicegreen("You feel a horrible omen lifted off your shoulders!")) if(vessel) @@ -61,6 +68,9 @@ vessel.burn() vessel = null + for(var/obj/machinery/light/to_untrack as anything in tracked_lights) + untrack_light(to_untrack) + return ..() /datum/component/omen/RegisterWithParent() @@ -68,164 +78,251 @@ RegisterSignal(parent, COMSIG_ON_CARBON_SLIP, PROC_REF(check_slip)) RegisterSignal(parent, COMSIG_CARBON_MOOD_UPDATE, PROC_REF(check_bless)) RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(check_death)) + RegisterSignal(parent, COMSIG_MOVABLE_BLOCKING_AIRLOCK, PROC_REF(check_airlock_crush)) + RegisterSignal(parent, COMSIG_MOB_VENDING_PURCHASE, PROC_REF(check_vending)) + RegisterSignal(parent, COMSIG_LIVING_LIFE, PROC_REF(on_life)) /datum/component/omen/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ON_CARBON_SLIP, COMSIG_MOVABLE_MOVED, COMSIG_CARBON_MOOD_UPDATE, COMSIG_LIVING_DEATH)) + UnregisterSignal(parent, list( + COMSIG_ON_CARBON_SLIP, + COMSIG_MOVABLE_MOVED, + COMSIG_LIVING_BLESSED, + COMSIG_LIVING_DEATH, + COMSIG_MOVABLE_BLOCKING_AIRLOCK, + COMSIG_MOB_VENDING_PURCHASE, + COMSIG_LIVING_LIFE, + )) /datum/component/omen/proc/consume_omen() + if(incidents_left == INFINITY) + return + incidents_left-- if(incidents_left < 1) qdel(src) -/** - * check_accident() is called each step we take - * - * While we're walking around, roll to see if there's any environmental hazards on one of the adjacent tiles we can trigger. - * We do the prob() at the beginning to A. add some tension for /when/ it will strike, and B. (more importantly) ameliorate the fact that we're checking up to 5 turfs's contents each time - */ -/datum/component/omen/proc/check_accident(atom/movable/our_guy) +/// Roll an accident happening, factoring in a few things, based on some base change. +/datum/component/omen/proc/roll_for_accident(base_chance = 4) + var/chance = base_chance * luck_mod + for(var/mob/viewer in viewers(parent)) + if(!viewer.client?.is_afk()) + chance *= 2 + break + + return prob(chance) + +/// When we obstruct an airlock, there's a chance it will crush us instead of stopping like it should +/datum/component/omen/proc/check_airlock_crush(mob/living/source, obj/machinery/door/airlock/darth_airlock, forced, force_crush) SIGNAL_HANDLER - if(!isliving(our_guy)) + if(force_crush || !roll_for_accident(25)) + return NONE + + consume_omen() + to_chat(parent, span_warning("As you stand in [darth_airlock], it doesn't stop closing like it should...")) + return AIRLOCK_BLOCK_FORCE_CRUSH + +/// When we vend an item from a vending machine, there's a chance the machine will tip +/datum/component/omen/proc/check_vending(mob/living/source, obj/machinery/vending/darth_vendor, obj/item/vended_item) + SIGNAL_HANDLER + + if(!source.Adjacent(darth_vendor) || !roll_for_accident(10)) + return NONE + + consume_omen() + to_chat(source, span_warning("As you grab [vended_item] from the slot, [darth_vendor] wobbles ominously...")) + INVOKE_ASYNC(darth_vendor, TYPE_PROC_REF(/obj/machinery/vending, tilt), source) + return VENDING_NO_PICKUP + +/// On life tick, run a few generic checks for accidents, and track nearby lights +/datum/component/omen/proc/on_life(mob/living/source) + SIGNAL_HANDLER + + if(source.stat == DEAD || HAS_TRAIT(source, TRAIT_STASIS)) return - var/mob/living/living_guy = our_guy + if(roll_for_accident(0.001)) + spontaneous_combustion(source) + return - if(prob(0.001) && (living_guy.stat != DEAD)) // You hit the lottery! Kinda. - living_guy.visible_message(span_danger("[living_guy] suddenly bursts into flames!"), span_danger("You suddenly burst into flames!")) - INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") - living_guy.adjust_fire_stacks(20) - living_guy.ignite_mob(silent = TRUE) - consume_omen() + if(HAS_TRAIT(source, TRAIT_SHOCKIMMUNE)) + for(var/obj/machinery/light/to_untrack as anything in tracked_lights) + untrack_light(to_untrack) return - var/effective_luck = luck_mod + var/list/light_list = list() + for(var/obj/machinery/light/evil_light in view(2, source)) + if(evil_light.status == LIGHT_OK) + light_list += evil_light + for(var/obj/machinery/light/to_track as anything in light_list - tracked_lights) + track_light(to_track) + for(var/obj/machinery/light/to_untrack as anything in tracked_lights - light_list) + untrack_light(to_untrack) + +/// Start tracking a light, because it's near us and could be a threat +/datum/component/omen/proc/track_light(obj/machinery/light/evil_light) + tracked_lights += evil_light + RegisterSignal(evil_light, COMSIG_LIGHT_FIXTURE_BROKEN, PROC_REF(check_break_zap)) + RegisterSignal(evil_light, COMSIG_LIGHT_FIXTURE_TOGGLED, PROC_REF(check_toggle_zap)) + RegisterSignal(evil_light, COMSIG_QDELETING, PROC_REF(untrack_light)) + +/// Stop tracking a light, either because it broke or we moved away from it +/datum/component/omen/proc/untrack_light(obj/machinery/light/evil_light) + SIGNAL_HANDLER - // If there's nobody to witness the misfortune, make it less likely. - // This way, we allow for people to be able to get into hilarious situations without making the game nigh unplayable most of the time. + tracked_lights -= evil_light + UnregisterSignal(evil_light, list(COMSIG_LIGHT_FIXTURE_BROKEN, COMSIG_LIGHT_FIXTURE_TOGGLED, COMSIG_QDELETING)) - var/has_watchers = FALSE - for(var/mob/viewer in viewers(our_guy, world.view)) - if(viewer.client) - has_watchers = TRUE - break - if(!has_watchers) - effective_luck *= 0.5 +/// When a light we track breaks, there's a chance of zapping us +/datum/component/omen/proc/check_break_zap(obj/machinery/light/evil_light, was_ok) + SIGNAL_HANDLER + + if(was_ok && !HAS_TRAIT(parent, TRAIT_SHOCKIMMUNE) && roll_for_accident(10)) + evil_light.visible_message(span_boldwarning("A bolt of electricity jumps from [evil_light] to [parent] as it breaks!")) + light_zap(evil_light) + consume_omen() + // always untrack because it's broken now + untrack_light(evil_light) - if(!prob(8 * effective_luck)) +/// When a light we track is toggled on or off, there's a chance of zapping us +/datum/component/omen/proc/check_toggle_zap(obj/machinery/light/evil_light, new_status) + SIGNAL_HANDLER + + if(HAS_TRAIT(parent, TRAIT_SHOCKIMMUNE) || !roll_for_accident(20)) return - var/our_guy_pos = get_turf(living_guy) - for(var/obj/machinery/door/airlock/darth_airlock in our_guy_pos) - if(darth_airlock.locked || !darth_airlock.hasPower()) - continue + evil_light.visible_message(span_boldwarning("A bolt of electricity jumps from [evil_light] to [parent] as it turns [new_status ? "on" : "off"]!")) + light_zap(evil_light) + consume_omen() + // we're about to break it, so untrack to avoid a double zap + untrack_light(evil_light) + // and then actually break the thing + evil_light.break_light_tube() + +/// Zap the target with electricity from a light fixture +/datum/component/omen/proc/light_zap(obj/machinery/light/evil_light) + PRIVATE_PROC(TRUE) + + var/mob/living/target = parent + evil_light.Beam(target, icon_state = "lightning[rand(1, 12)]", time = 0.5 SECONDS) + target.electrocute_act(35 * damage_mod, evil_light, flags = SHOCK_NOGLOVES) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") + consume_omen() + +/// Randomly burst into flames +/datum/component/omen/proc/spontaneous_combustion() + var/mob/living/target = parent + target.adjust_fire_stacks(20) + if(!target.ignite_mob(silent = TRUE)) + return FALSE + + target.visible_message( + span_danger("[target] suddenly bursts into flames!"), + span_userdanger("You suddenly burst into flames!"), + ) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, emote), "scream") + consume_omen() + return TRUE + +/// Every time we move we need to check a few things for potential incidents +/datum/component/omen/proc/check_accident(mob/living/source) + SIGNAL_HANDLER + + if(mirror_interaction()) + return - to_chat(living_guy, span_warning("A malevolent force launches your body to the floor...")) - living_guy.Paralyze(1 SECONDS, ignore_canstun = TRUE) - INVOKE_ASYNC(src, PROC_REF(slam_airlock), darth_airlock) + if(fall_down()) return - for(var/turf/the_turf as anything in get_adjacent_open_turfs(living_guy)) - if(istype(the_turf, /turf/open/floor/glass/reinforced/tram)) // don't fall off the tram bridge, we want to hit you instead - return - if(living_guy.can_z_move(DOWN, the_turf, z_move_flags = ZMOVE_FALL_FLAGS)) - to_chat(living_guy, span_warning("A malevolent force guides you towards the edge...")) - living_guy.throw_at(the_turf, 1, 10, force = MOVE_FORCE_EXTREMELY_STRONG) - consume_omen() - return - - for(var/obj/machinery/vending/darth_vendor in the_turf) - if(!darth_vendor.tiltable || darth_vendor.tilted) - continue - to_chat(living_guy, span_warning("A malevolent force tugs at the [darth_vendor]...")) - INVOKE_ASYNC(darth_vendor, TYPE_PROC_REF(/obj/machinery/vending, tilt), living_guy) - consume_omen() - return - - for(var/obj/machinery/light/evil_light in the_turf) - if((evil_light.status == LIGHT_BURNED || evil_light.status == LIGHT_BROKEN) || (HAS_TRAIT(living_guy, TRAIT_SHOCKIMMUNE))) // we cant do anything :( // Why in the world is there no get_siemens_coeff proc??? - to_chat(living_guy, span_warning("[evil_light] sparks weakly for a second.")) - do_sparks(2, FALSE, evil_light) // hey maybe it'll ignite them - return - - to_chat(living_guy, span_warning("[evil_light] glows ominously...")) // omenously - evil_light.visible_message(span_boldwarning("[evil_light] suddenly flares brightly and sparks!")) - evil_light.break_light_tube(skip_sound_and_sparks = FALSE) - do_sparks(number = 4, cardinal_only = FALSE, source = evil_light) - evil_light.Beam(living_guy, icon_state = "lightning[rand(1,12)]", time = 0.5 SECONDS) - living_guy.electrocute_act(35 * (damage_mod * 0.5), evil_light, flags = SHOCK_NOGLOVES) - INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") - consume_omen() - - for(var/obj/structure/mirror/evil_mirror in the_turf) - to_chat(living_guy, span_warning("You pass by the mirror and glance at it...")) - if(evil_mirror.broken) - to_chat(living_guy, span_notice("You feel lucky, somehow.")) - return - switch(rand(1, 5)) - if(1) - to_chat(living_guy, span_warning("The mirror explodes into a million pieces! Wait, does that mean you're even more unlucky?")) - evil_mirror.take_damage(evil_mirror.max_integrity, BRUTE, MELEE, FALSE) - if(prob(50 * effective_luck)) // sometimes - luck_mod += 0.25 - damage_mod += 0.25 - if(2 to 3) - to_chat(living_guy, span_big(span_hypnophrase("Oh god, you can't see your reflection!!"))) - if(HAS_TRAIT(living_guy, TRAIT_NO_MIRROR_REFLECTION)) // not so living i suppose - to_chat(living_guy, span_green("Well, obviously.")) - return - INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") - - if(4 to 5) - if(HAS_TRAIT(living_guy, TRAIT_NO_MIRROR_REFLECTION)) - to_chat(living_guy, span_warning("You don't see anything of notice. Huh.")) - return - to_chat(living_guy, span_userdanger("You see your reflection, but it is grinning malevolently and staring directly at you!")) - INVOKE_ASYNC(living_guy, TYPE_PROC_REF(/mob, emote), "scream") - - living_guy.set_jitter_if_lower(25 SECONDS) - if(prob(7 * effective_luck)) - to_chat(living_guy, span_warning("You are completely shocked by this turn of events!")) - to_chat(living_guy, span_userdanger("You clutch at your heart!")) - var/mob/living/carbon/carbon_guy = living_guy - if(istype(carbon_guy)) - carbon_guy.set_heartattack(status = TRUE) - - consume_omen() - -/datum/component/omen/proc/slam_airlock(obj/machinery/door/airlock/darth_airlock) - . = darth_airlock.close(force_crush = TRUE) - if(.) +/// Attempts to throw us down a nearby open space +/datum/component/omen/proc/fall_down() + var/mob/living/our_guy = parent + var/turf/open/mob_turf = get_turf(our_guy) + if(isgroundlessturf(mob_turf) || istype(mob_turf, /turf/open/floor/glass/reinforced/tram)) // snowflake check is to increase likelihood of being hit with the tram + return FALSE + + for(var/turf/adjacent_turf as anything in get_adjacent_open_turfs(mob_turf)) + if(!our_guy.can_z_move(DOWN, adjacent_turf, z_move_flags = ZMOVE_FALL_FLAGS)) + continue + if(!roll_for_accident(4)) + return FALSE + + var/obj/structure/railing/rail = locate() in mob_turf + to_chat(our_guy, span_warning("As you step on [mob_turf], you lose footing and fall[rail ? " over the railing and" : ""] off the edge!")) + our_guy.throw_at(adjacent_turf, 1, 10, force = MOVE_FORCE_EXTREMELY_STRONG) consume_omen() + return TRUE + + return FALSE + +/// Gaze into a mirror and see if something bad happens +/datum/component/omen/proc/mirror_interaction() + var/mob/living/our_guy = parent + var/obj/structure/mirror/evil_mirror = locate() in get_turf(our_guy) + if(isnull(evil_mirror) || !roll_for_accident(10)) + REMOVE_TRAIT(our_guy, TRAIT_NO_MIRROR_REFLECTION, REF(src)) + return FALSE + + to_chat(our_guy, span_warning("You pass by the mirror and glance at it...")) + if(evil_mirror.broken) + to_chat(our_guy, span_notice("...You feel lucky, somehow.")) + return TRUE + + switch(rand(1, 5)) + if(1) + to_chat(our_guy, span_warning("...The mirror explodes into a million pieces! Wait, does that mean you're even more unlucky?")) + evil_mirror.take_damage(evil_mirror.max_integrity, BRUTE, MELEE, FALSE) + if(roll_for_accident(20)) + luck_mod += 0.25 + damage_mod += 0.25 + + if(2 to 3) + if(HAS_TRAIT(our_guy, TRAIT_NO_MIRROR_REFLECTION)) // not so living i suppose + to_chat(our_guy, span_green("...Oh god, you can't see your reflection - wait, that's normal.")) + return TRUE + to_chat(our_guy, span_big(span_hypnophrase("...Oh god, you can't see your reflection!!"))) + INVOKE_ASYNC(our_guy, TYPE_PROC_REF(/mob, emote), "scream") + ADD_TRAIT(our_guy, TRAIT_NO_MIRROR_REFLECTION, REF(src)) + + if(4 to 5) + if(HAS_TRAIT(our_guy, TRAIT_NO_MIRROR_REFLECTION)) + to_chat(our_guy, span_warning("...but you don't see anything of notice.")) + return TRUE + to_chat(our_guy, span_userdanger("You see your reflection, but it is grinning malevolently and staring directly at you!")) + INVOKE_ASYNC(our_guy, TYPE_PROC_REF(/mob, emote), "scream") + + our_guy.set_jitter_if_lower(25 SECONDS) + if(roll_for_accident(2)) + to_chat(our_guy, span_warning("You are completely shocked by this turn of events!")) + to_chat(our_guy, span_userdanger("You clutch at your heart!")) + if(iscarbon(our_guy)) + var/mob/living/carbon/carbon_guy = our_guy + carbon_guy.set_heartattack(status = TRUE) + + consume_omen() + return TRUE /// If we get knocked down, see if we have a really bad slip and bash our head hard /datum/component/omen/proc/check_slip(mob/living/our_guy, amount) SIGNAL_HANDLER - if(prob(30)) // AAAA - INVOKE_ASYNC(our_guy, TYPE_PROC_REF(/mob, emote), "scream") - to_chat(our_guy, span_warning("What a horrible night... To have a curse!")) - - if(prob(30 * luck_mod)) /// Bonk! - var/obj/item/bodypart/the_head = our_guy.get_bodypart(BODY_ZONE_HEAD) - if(!the_head) - return - playsound(our_guy, 'sound/effects/tableheadsmash.ogg', 90, TRUE) - our_guy.visible_message(span_danger("[our_guy] hits [our_guy.p_their()] head really badly falling down!"), span_userdanger("You hit your head really badly falling down!")) - our_guy.apply_damage(75 * damage_mod, BRUTE, the_head, attacking_item = "slipping") - our_guy.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100 * damage_mod) - consume_omen() + if(!our_guy.get_bodypart(BODY_ZONE_HEAD) || !roll_for_accident(15)) // Bonk! + return - return + playsound(our_guy, 'sound/effects/tableheadsmash.ogg', 90, TRUE) + our_guy.visible_message( + span_danger("[our_guy] hits [our_guy.p_their()] head really badly falling down!"), + span_userdanger("You hit your head really badly falling down!"), + ) + our_guy.apply_damage(75 * damage_mod, BRUTE, BODY_ZONE_HEAD, attacking_item = "slipping") + our_guy.apply_damage(100 * damage_mod, BRAIN) + consume_omen() /// Hijack the mood system to see if we get the blessing mood event to cancel the omen -/datum/component/omen/proc/check_bless(mob/living/our_guy, category) +/datum/component/omen/proc/check_bless(mob/living/our_guy, mob/blesser, obj/item/bible, bless_result) SIGNAL_HANDLER - if(incidents_left == INFINITY) - return - - if(!("blessing" in our_guy.mob_mood.mood_events)) + if(incidents_left == INFINITY || !bless_result/* != BLESSING_SUCCESS*/ || !bless_fixable) return playsound(our_guy, 'sound/effects/pray_chaplain.ogg', 40, TRUE) @@ -237,6 +334,7 @@ /datum/component/omen/proc/check_death(mob/living/our_guy) SIGNAL_HANDLER + on_death?.Invoke(src) if(incidents_left == INFINITY) return @@ -256,53 +354,6 @@ UnregisterSignal(vessel, COMSIG_QDELETING) vessel = null -/** - * The smite omen. Permanent. - */ -/datum/component/omen/smite - -/datum/component/omen/smite/check_death(mob/living/our_guy) - if(incidents_left == INFINITY) - return ..() - - death_explode(our_guy) - our_guy.gib(DROP_ALL_REMAINS) - -/** - * The quirk omen. Permanent. - * Has only a 50% chance of bad things happening, and takes only 25% of normal damage. - */ -/datum/component/omen/quirk - incidents_left = INFINITY - luck_mod = 0.3 // 30% chance of bad things happening - damage_mod = 0.25 // 25% of normal damage - -/datum/component/omen/quirk/RegisterWithParent() - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(check_accident)) - RegisterSignal(parent, COMSIG_ON_CARBON_SLIP, PROC_REF(check_slip)) - RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(check_death)) - -/datum/component/omen/quirk/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ON_CARBON_SLIP, COMSIG_MOVABLE_MOVED, COMSIG_LIVING_DEATH)) - -/datum/component/omen/quirk/check_death(mob/living/our_guy) - if(!iscarbon(our_guy)) - our_guy.gib(DROP_ALL_REMAINS) - return - - // Don't explode if buckled to a stasis bed - if(our_guy.buckled) - var/obj/machinery/stasis/stasis_bed = our_guy.buckled - if(istype(stasis_bed)) - return - - death_explode(our_guy) - var/mob/living/carbon/player = our_guy - player.spread_bodyparts() - player.spawn_gibs() - - return - /** * The bible omen. * While it lasts, parent gets a cursed aura filter. diff --git a/code/datums/elements/rust.dm b/code/datums/elements/rust.dm index 135f45b7c2f3..e94e3703ad77 100644 --- a/code/datums/elements/rust.dm +++ b/code/datums/elements/rust.dm @@ -51,12 +51,10 @@ /datum/element/rust/proc/handle_tool_use(atom/source, mob/user, obj/item/item) switch(item.tool_behaviour) if(TOOL_WELDER) - if(!item.tool_start_check(user, amount=1)) + if(!item.tool_start_check(user, amount = 1)) return - user.balloon_alert(user, "burning off rust...") - - if(!item.use_tool(source, user, 5 SECONDS)) + if(!item.use_tool(source, user, 5 SECONDS, amount = 1, volume = 50)) return user.balloon_alert(user, "burned off rust") Detach(source) @@ -67,7 +65,7 @@ if(!item.tool_start_check(user)) return user.balloon_alert(user, "scraping off rust...") - if(!item.use_tool(source, user, 2 SECONDS)) + if(!item.use_tool(source, user, 2 SECONDS, volume = 50)) return user.balloon_alert(user, "scraped off rust") Detach(source) diff --git a/code/datums/mood.dm b/code/datums/mood.dm index 890b5bf022ce..206b25a7ab0d 100644 --- a/code/datums/mood.dm +++ b/code/datums/mood.dm @@ -610,6 +610,9 @@ else msg += "• [span_grey("I don't have much of a reaction to anything right now.")]
" + if(LAZYLEN(mob_parent.personalities)) + msg += span_notice("You know yourself to be [mob_parent.get_parsonality_string()].
") + if(LAZYLEN(mob_parent.quirks)) msg += span_notice("You have these quirks: [mob_parent.get_quirk_string(FALSE, CAT_QUIRK_ALL)].") @@ -798,20 +801,23 @@ switch(esanity) if (0 to 10) new_screen = mob_parent.overlay_fullscreen("sanity", /atom/movable/screen/fullscreen/sanity, 4) - mob_parent.add_client_colour(/datum/client_colour/sanity/tier4, "sanity") + mob_parent.add_client_colour(/datum/client_colour/sanity/tier4) if (10 to 20) new_screen = mob_parent.overlay_fullscreen("sanity", /atom/movable/screen/fullscreen/sanity, 3) - mob_parent.add_client_colour(/datum/client_colour/sanity/tier3, "sanity") + mob_parent.add_client_colour(/datum/client_colour/sanity/tier3) if (20 to 30) new_screen = mob_parent.overlay_fullscreen("sanity", /atom/movable/screen/fullscreen/sanity, 2) - mob_parent.add_client_colour(/datum/client_colour/sanity/tier2, "sanity") + mob_parent.add_client_colour(/datum/client_colour/sanity/tier2) if (30 to 40) new_screen = mob_parent.overlay_fullscreen("sanity", /atom/movable/screen/fullscreen/sanity, 1) - mob_parent.add_client_colour(/datum/client_colour/sanity/tier1, "sanity") + mob_parent.add_client_colour(/datum/client_colour/sanity/tier1) else mob_parent.clear_fullscreen("sanity") mob_parent.clear_fullscreen("sanity_static") - mob_parent.remove_client_colour("sanity") + mob_parent.remove_client_colour(/datum/client_colour/sanity/tier4) + mob_parent.remove_client_colour(/datum/client_colour/sanity/tier3) + mob_parent.remove_client_colour(/datum/client_colour/sanity/tier2) + mob_parent.remove_client_colour(/datum/client_colour/sanity/tier1) if(new_screen && old_state != new_screen.icon_state) // updating static effect for new sanity level diff --git a/code/datums/quirks/_quirk.dm b/code/datums/quirks/_quirk.dm index 36363d46ab1e..2098400b217c 100644 --- a/code/datums/quirks/_quirk.dm +++ b/code/datums/quirks/_quirk.dm @@ -198,45 +198,3 @@ to_chat(quirk_holder, chat_string) where_items_spawned = null - -/** - * get_quirk_string() is used to get a printable string of all the quirk traits someone has for certain criteria - * - * Arguments: - * * Medical- If we want the long, fancy descriptions that show up in medical records, or if not, just the name - * * Category- Which types of quirks we want to print out. Defaults to everything - * * from_scan- If the source of this call is like a health analyzer or HUD, in which case QUIRK_HIDE_FROM_MEDICAL hides the quirk. - */ -/mob/living/proc/get_quirk_string(medical = FALSE, category = CAT_QUIRK_ALL, from_scan = FALSE, none_text) - var/list/dat = list() - for(var/datum/quirk/candidate as anything in quirks) - if(from_scan && (candidate.quirk_flags & QUIRK_HIDE_FROM_SCAN)) - continue - if(medical && !candidate.medical_record_text) - continue - switch(category) - if(CAT_QUIRK_MAJOR_DISABILITY) - if(candidate.value >= -4) - continue - if(CAT_QUIRK_MINOR_DISABILITY) - if(!ISINRANGE(candidate.value, -4, -1)) - continue - if(CAT_QUIRK_NOTES) - if(candidate.value < 0) - continue - dat += medical ? candidate.medical_record_text : candidate.name - - if(!dat.len) - return isnull(none_text) ? (medical ? "No issues have been declared." : "None") : none_text - return medical ? dat.Join("
") : dat.Join(", ") - -/mob/living/proc/cleanse_quirk_datums() //removes all trait datums - QDEL_LAZYLIST(quirks) - -/mob/living/proc/transfer_quirk_datums(mob/living/to_mob) - // We could be done before the client was moved or after the client was moved - var/datum/preferences/to_pass = client || to_mob.client - - for(var/datum/quirk/quirk as anything in quirks) - quirk.remove_from_current_holder(quirk_transfer = TRUE) - quirk.add_to_holder(to_mob, quirk_transfer = TRUE, client_source = to_pass) diff --git a/code/datums/quirks/negative_quirks/cursed.dm b/code/datums/quirks/negative_quirks/cursed.dm index f58d31be28e4..6063d15dccb9 100644 --- a/code/datums/quirks/negative_quirks/cursed.dm +++ b/code/datums/quirks/negative_quirks/cursed.dm @@ -10,4 +10,25 @@ hardcore_value = 8 /datum/quirk/cursed/add(client/client_source) - quirk_holder.AddComponent(/datum/component/omen/quirk) + quirk_holder.AddComponent( \ + /datum/component/omen, \ + incidents_left = INFINITY, \ + luck_mod = 0.3, \ + damage_mod = 0.25, \ + bless_fixable = FALSE, \ + on_death = CALLBACK(src, PROC_REF(on_death)), \ + ) + +/datum/quirk/cursed/proc/on_death(datum/component/omen/omen) + var/mob/living/carbon/cursed = omen.parent + if(!iscarbon(cursed)) + cursed.gib(DROP_ALL_REMAINS) + return + + // Don't explode if buckled to a stasis bed + if(istype(cursed.buckled, /obj/machinery/stasis)) + return + + omen.death_explode(cursed) + cursed.spread_bodyparts() + cursed.spawn_gibs() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index e8584049e681..a83454b681e4 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1310,6 +1310,11 @@ if(!dangerous_close) for(var/turf/checked_turf in locs) for(var/atom/movable/blocking in checked_turf) + var/sigreturn = SEND_SIGNAL(blocking, COMSIG_MOVABLE_BLOCKING_AIRLOCK, src, forced, force_crush) + if(sigreturn & AIRLOCK_BLOCK_FORCE_CRUSH) + dangerous_close = TRUE + continue + if(blocking.density && blocking != src) autoclose_in(DOOR_CLOSE_WAIT) return FALSE diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 3da43c1294f3..f4c7010fc97b 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -179,16 +179,33 @@ GLOBAL_LIST_INIT(dye_registry, list( icon_state = "wm_1_0" density = TRUE state_open = TRUE + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass = SHEET_MATERIAL_AMOUNT) + circuit = /obj/item/circuitboard/machine/washing_machine var/busy = FALSE var/bloody_mess = FALSE var/obj/item/color_source - var/max_wash_capacity = 5 + /// The max amount of items that can be washed per load + var/max_wash_capacity + /// The time it takes to wash a load of laundry + var/time_to_wash + /// The current number of items inserted + var/total_load = 0 /obj/machinery/washing_machine/examine(mob/user) . = ..() if(!busy) . += span_notice("Right-click with an empty hand to start a wash cycle.") +/obj/machinery/washing_machine/RefreshParts() + . = ..() + var/total_volume = 0 + for(var/obj/item/reagent_containers/cup/beaker/beaker in component_parts) + total_volume += beaker.reagents.maximum_volume + max_wash_capacity = floor(total_volume/20) + + for(var/datum/stock_part/servo/servo in component_parts) + time_to_wash = 20 SECONDS / servo.tier + /obj/machinery/washing_machine/process(seconds_per_tick) if(!busy) animate(src, transform=matrix(), time=2) @@ -320,7 +337,7 @@ GLOBAL_LIST_INIT(dye_registry, list( icon_state = "wm_[state_open]_blood" return ..() - var/full = contents.len ? 1 : 0 + var/full = total_load ? 1 : 0 icon_state = "wm_[state_open]_[full]" return ..() @@ -352,7 +369,7 @@ GLOBAL_LIST_INIT(dye_registry, list( if(bloody_mess) to_chat(user, span_warning("[src] must be cleaned up first!")) return ITEM_INTERACT_BLOCKING - if(contents.len >= max_wash_capacity) + if(total_load >= max_wash_capacity) to_chat(user, span_warning("The washing machine is full!")) return ITEM_INTERACT_BLOCKING if(!user.transferItemToLoc(item, src)) @@ -360,6 +377,7 @@ GLOBAL_LIST_INIT(dye_registry, list( return ITEM_INTERACT_BLOCKING if(item.dye_color) color_source = item + total_load++ update_appearance() return ITEM_INTERACT_SUCCESS @@ -408,7 +426,7 @@ GLOBAL_LIST_INIT(dye_registry, list( if(HAS_TRAIT(user, TRAIT_BRAINWASHING)) ADD_TRAIT(src, TRAIT_BRAINWASHING, SKILLCHIP_TRAIT) update_appearance() - addtimer(CALLBACK(src, PROC_REF(wash_cycle)), 20 SECONDS) + addtimer(CALLBACK(src, PROC_REF(wash_cycle), user), time_to_wash) START_PROCESSING(SSfastprocess, src) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN @@ -422,3 +440,4 @@ GLOBAL_LIST_INIT(dye_registry, list( . = ..() set_density(TRUE) //because machinery/open_machine() sets it to FALSE color_source = null + total_load = 0 diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 8e168b25f082..9985f87dacf3 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -16,6 +16,8 @@ var/can_dry = TRUE /// Is this blood dried out? var/dried = FALSE + /// Do we delete ourselves when we dry out? + var/qdel_on_dry = FALSE /// How much our blood glows, up to 255 (it's the alpha of the EM overlay). 0 = no glow var/emissive_alpha = 0 @@ -43,6 +45,9 @@ if(mapload || starting_dna) init_dna(starting_dna) if(dried) + if(qdel_on_dry) + stack_trace("Blood decal set to dry on init but qdel on dry, you probably don't want that?") + qdel_on_dry = FALSE dry() else if(can_dry) START_PROCESSING(SSblood_drying, src) @@ -159,6 +164,8 @@ update_atom_colour() STOP_PROCESSING(SSblood_drying, src) clear_smells() + if(qdel_on_dry) + qdel(src) return TRUE /obj/effect/decal/cleanable/blood/adjust_bloodiness(by_amount) diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index 260e1e87a592..7f290b93178d 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -725,6 +725,16 @@ /datum/stock_part/scanning_module = 1, ) +/obj/item/circuitboard/machine/photocopier + name = "Photocopier" + greyscale_colors = CIRCUIT_COLOR_GENERIC + build_path = /obj/machinery/photocopier + req_components = list( + /datum/stock_part/scanning_module = 1, + /datum/stock_part/micro_laser = 1, + /datum/stock_part/matter_bin = 1 + ) + //Medical /obj/item/circuitboard/machine/chem_dispenser @@ -1651,3 +1661,23 @@ /datum/stock_part/capacitor = 2, /datum/stock_part/micro_laser = 2, /obj/item/stack/sheet/glass = 1) + +// /obj/item/circuitboard/machine/atmos_shield_gen +// name = /obj/machinery/atmos_shield_gen::name +// greyscale_colors = CIRCUIT_COLOR_ENGINEERING +// build_path = /obj/machinery/atmos_shield_gen +// req_components = list( +// /datum/stock_part/micro_laser = 1, +// /datum/stock_part/capacitor = 1, +// ) + +/obj/item/circuitboard/machine/washing_machine + name = "Washing Machine" + greyscale_colors = CIRCUIT_COLOR_SERVICE + build_path = /obj/machinery/washing_machine + req_components = list( + /obj/item/stack/sheet/glass = 1, + /obj/item/reagent_containers/cup/beaker = 2, + /datum/stock_part/water_recycler = 1, + /datum/stock_part/servo = 1, + ) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index c0ea987aaca4..fa2d8ada6435 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -17,7 +17,10 @@ w_class = WEIGHT_CLASS_SMALL obj_flags = CONDUCTS_ELECTRICITY slot_flags = ITEM_SLOT_BELT - custom_materials = list(/datum/material/iron= SMALL_MATERIAL_AMOUNT * 0.5, /datum/material/glass= SMALL_MATERIAL_AMOUNT * 0.2) + custom_materials = list( + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.5, + /datum/material/glass = SMALL_MATERIAL_AMOUNT * 0.2, + ) actions_types = list(/datum/action/item_action/toggle_light) action_slots = ALL light_system = OVERLAY_LIGHT_DIRECTIONAL @@ -435,7 +438,11 @@ var/trash_type = /obj/item/trash/flare /// If the light source can be extinguished var/can_be_extinguished = FALSE - custom_materials = list(/datum/material/plastic= SMALL_MATERIAL_AMOUNT * 0.5) + custom_materials = list( + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.5, + /datum/material/plasma = SMALL_MATERIAL_AMOUNT * 0.5, + /datum/material/plastic = SMALL_MATERIAL_AMOUNT * 0.5, + ) /obj/item/flashlight/flare/Initialize(mapload) . = ..() @@ -693,6 +700,26 @@ slot_flags = null trash_type = /obj/effect/decal/cleanable/ash can_be_extinguished = TRUE + custom_materials = list(/datum/material/wood = SMALL_MATERIAL_AMOUNT*0.5) + +/obj/item/flashlight/flare/torch/on + start_on = TRUE + +/obj/item/flashlight/flare/torch/everburning + name = "everburning torch" + desc = "A torch which burns continuously, even in the vacuum of space" + can_be_extinguished = FALSE + fuel = INFINITY + randomize_fuel = FALSE + start_on = TRUE + custom_materials = null + +/obj/item/flashlight/flare/torch/red + color = "#ff0000" + light_range = 2 + +/obj/item/flashlight/flare/torch/red/on + start_on = TRUE /obj/item/flashlight/lantern name = "lantern" @@ -817,6 +844,7 @@ /// How many seconds of fuel we have left var/fuel = 0 ignore_base_color = TRUE + custom_materials = null /obj/item/flashlight/glowstick/Initialize(mapload) fuel = rand(50 MINUTES, 60 MINUTES) diff --git a/code/game/objects/items/food/burgers.dm b/code/game/objects/items/food/burgers.dm index 95b40f03d32a..ec00d39899bc 100644 --- a/code/game/objects/items/food/burgers.dm +++ b/code/game/objects/items/food/burgers.dm @@ -659,6 +659,12 @@ tastes = list("bun" = 2, "beef patty" = 4, "cheese" = 2, "beef soaked in chili" = 3, "a smoking flare" = 2) foodtypes = GRAIN | MEAT | DAIRY | VEGETABLES crafting_complexity = FOOD_COMPLEXITY_4 + // custom_materials = list( + // /datum/material/meat = MEATDISH_MATERIAL_AMOUNT * 2, + // /datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.5, + // /datum/material/plasma = SMALL_MATERIAL_AMOUNT * 0.5, + // /datum/material/plastic = SMALL_MATERIAL_AMOUNT * 0.5, + // ) /obj/item/food/burger/crazy/Initialize(mapload) . = ..() diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 7a137cde9a4b..cf78ac563bab 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -437,6 +437,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( GLOBAL_LIST_INIT(abductor_recipes, list ( \ new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 2, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ + new/datum/stack_recipe("strange closet", /obj/structure/closet/acloset, 2, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_CONTAINERS), \ new/datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 2 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ new/datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_DOORS), \ null, \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 908cc0d4f7b8..d507c41e6652 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -272,6 +272,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 5 SECONDS, crafting_flags = NONE, category = CAT_CHEMISTRY), new/datum/stack_recipe("Large Gas Tank", /obj/structure/tank_frame, 4, time=1 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF, category = CAT_ATMOSPHERIC), new/datum/stack_recipe("shutter assembly", /obj/machinery/door/poddoor/shutters/preopen/deconstructed, 5, time = 5 SECONDS, crafting_flags = CRAFT_ONE_PER_TURF, category = CAT_DOORS), + new/datum/stack_recipe("large metal box", /obj/structure/closet/cardboard/metal, 4, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_CONTAINERS), null, new /datum/stack_recipe_list("airlock assemblies", list( \ new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_DOORS), @@ -336,6 +337,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ new/datum/stack_recipe("wooden barrel", /obj/structure/fermenting_barrel, 8, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_CONTAINERS), \ new/datum/stack_recipe("dog bed", /obj/structure/bed/dogbed, 10, time = 1 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ new/datum/stack_recipe("dresser", /obj/structure/dresser, 10, time = 1.5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ + new/datum/stack_recipe("cabinet", /obj/structure/closet/cabinet, 2, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_CONTAINERS), \ new/datum/stack_recipe("picture frame", /obj/item/wallframe/picture, 1, time = 1 SECONDS, crafting_flags = NONE, category = CAT_ENTERTAINMENT),\ new/datum/stack_recipe("painting frame", /obj/item/wallframe/painting, 1, time = 1 SECONDS, crafting_flags = NONE, category = CAT_ENTERTAINMENT),\ new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 523d8f6d79b0..b50753449122 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -20,7 +20,7 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets) /// How insulated the thing is, for the purposes of calculating body temperature. Must be between 0 and 1! contents_thermal_insulation = 0 pass_flags_self = PASSSTRUCTURE | LETPASSCLICKS - + custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 2) /// The overlay for the closet's door var/obj/effect/overlay/closet_door/door_obj /// Whether or not this door is being animated diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index b398731e7d8a..b532fa9b2d89 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -9,6 +9,8 @@ can_weld_shut = 0 cutting_tool = /obj/item/wirecutters material_drop = /obj/item/stack/sheet/cardboard + material_drop_amount = 4 + custom_materials = list(/datum/material/cardboard = SHEET_MATERIAL_AMOUNT * 4) delivery_icon = "deliverybox" anchorable = FALSE open_sound = 'sound/machines/cardboard_box.ogg' @@ -117,4 +119,5 @@ close_sound = 'sound/machines/crate_close.ogg' open_sound_volume = 35 close_sound_volume = 50 + custom_materials = list(/datum/material/alloy/plasteel = SHEET_MATERIAL_AMOUNT * 4) material_drop = /obj/item/stack/sheet/plasteel diff --git a/code/game/objects/structures/crates_lockers/closets/gimmick.dm b/code/game/objects/structures/crates_lockers/closets/gimmick.dm index 2ee4f780ff3c..73c2eee5321b 100644 --- a/code/game/objects/structures/crates_lockers/closets/gimmick.dm +++ b/code/game/objects/structures/crates_lockers/closets/gimmick.dm @@ -9,12 +9,15 @@ close_sound_volume = 50 max_integrity = 70 door_anim_time = 0 // no animation + material_drop = /obj/item/stack/sheet/mineral/wood + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 2) /obj/structure/closet/acloset name = "strange closet" desc = "It looks alien!" icon_state = "alien" material_drop = /obj/item/stack/sheet/mineral/abductor + custom_materials = list(/datum/material/alloy/alien = SHEET_MATERIAL_AMOUNT * 2) /obj/structure/closet/gimmick name = "administrative supply closet" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index d0487198d4c7..5b5676c26e47 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -45,6 +45,8 @@ open_sound_volume = 25 close_sound_volume = 50 door_anim_time = 0 // no animation + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 2) + material_drop = /obj/item/stack/sheet/mineral/wood /obj/structure/closet/secure_closet/personal/cabinet/PopulateContents() new /obj/item/storage/backpack/satchel/leather/withwallet( src ) diff --git a/code/game/objects/structures/crates_lockers/crates/wooden.dm b/code/game/objects/structures/crates_lockers/crates/wooden.dm index a5e0b78cadb6..b98ee5c1601c 100644 --- a/code/game/objects/structures/crates_lockers/crates/wooden.dm +++ b/code/game/objects/structures/crates_lockers/crates/wooden.dm @@ -1,6 +1,7 @@ /obj/structure/closet/crate/wooden name = "wooden crate" desc = "Works just as well as a metal one." + custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 6) material_drop = /obj/item/stack/sheet/mineral/wood material_drop_amount = 6 icon_state = "wooden" diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 93040121f0fd..c4176048e4dc 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -2,7 +2,7 @@ name = "extinguisher cabinet" desc = "A small wall mounted cabinet designed to hold a fire extinguisher." icon = 'icons/obj/wallmounts.dmi' - icon_state = "extinguisher_closed" + icon_state = "extinguisher" anchored = TRUE density = FALSE max_integrity = 200 @@ -153,11 +153,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29) else if(istype(stored_extinguisher, /obj/item/extinguisher)) icon_state += "_default" - if(!opened) - icon_state += "_closed" - return ..() +/obj/structure/extinguisher_cabinet/update_overlays() + . = ..() + . += mutable_appearance(icon, opened ? "door_open" : "door") + /obj/structure/extinguisher_cabinet/atom_break(damage_flag) . = ..() if(!broken) @@ -182,6 +183,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29) name = "extinguisher cabinet frame" desc = "Used for building wall-mounted extinguisher cabinets." icon = 'icons/obj/wallmounts.dmi' - icon_state = "extinguisher_assembly" + icon_state = "extinguisher" //Reuses wallmount icon, but no door overlay result_path = /obj/structure/extinguisher_cabinet pixel_shift = 29 diff --git a/code/game/objects/structures/janitor.dm b/code/game/objects/structures/janitor.dm index 4f5bdf281273..0413bcac5398 100644 --- a/code/game/objects/structures/janitor.dm +++ b/code/game/objects/structures/janitor.dm @@ -73,6 +73,7 @@ /obj/structure/mop_bucket/janitorialcart/Initialize(mapload) . = ..() + reagents.maximum_volume *= 2.5 GLOB.janitor_devices += src /obj/structure/mop_bucket/janitorialcart/Destroy() diff --git a/code/modules/admin/smites/bad_luck.dm b/code/modules/admin/smites/bad_luck.dm index 34592dd200d4..82551955a534 100644 --- a/code/modules/admin/smites/bad_luck.dm +++ b/code/modules/admin/smites/bad_luck.dm @@ -18,11 +18,23 @@ . = ..() //if permanent, replace any existing omen if(incidents == INFINITY) - var/existing_component = target.GetComponent(/datum/component/omen) - qdel(existing_component) - target.AddComponent(/datum/component/omen/smite, incidents_left = incidents) + qdel(target.GetComponent(/datum/component/omen)) + target.AddComponent( \ + /datum/component/omen, \ + incidents_left = incidents, \ + on_death = CALLBACK(src, PROC_REF(on_death)), \ + bless_fixable = incidents != INFINITY, \ + ) if(silent) return to_chat(target, span_warning("You get a bad feeling...")) if(incidents == INFINITY) to_chat(target, span_warning("A very bad feeling... As if malevolent forces are watching you...")) + +/datum/smite/bad_luck/proc/on_death(datum/component/omen/omen) + if(omen.incidents_left == INFINITY) + return + + var/mob/living/our_guy = omen.parent + omen.death_explode(our_guy) + our_guy.gib(DROP_ALL_REMAINS) diff --git a/code/modules/clothing/masks/bandana.dm b/code/modules/clothing/masks/bandana.dm index b5f7b7bf3710..758cb1ddb9a1 100644 --- a/code/modules/clothing/masks/bandana.dm +++ b/code/modules/clothing/masks/bandana.dm @@ -72,12 +72,17 @@ widen.Scale(1.25, 1) transform = widen user.visible_message(span_notice("[user] ties [src] up like a neckerchief."), span_notice("You tie [src] up like a neckerchief.")) - else - undyeable = initial(undyeable) - slot_flags = initial(slot_flags) - worn_y_offset = initial(worn_y_offset) - transform = initial(transform) - user.visible_message(span_notice("[user] unties the neckercheif."), span_notice("You untie the neckercheif.")) + flags_inv = NONE + flags_cover = NONE + return CLICK_ACTION_SUCCESS + + undyeable = initial(undyeable) + slot_flags = initial(slot_flags) + worn_y_offset = initial(worn_y_offset) + transform = initial(transform) + user.visible_message(span_notice("[user] unties the neckercheif."), span_notice("You untie the neckercheif.")) + flags_inv = initial(flags_inv) + flags_cover = initial(flags_cover) return CLICK_ACTION_SUCCESS /obj/item/clothing/mask/bandana/red diff --git a/code/modules/forensics/forensics_helpers.dm b/code/modules/forensics/forensics_helpers.dm index f02d9e2450a2..f5e704b668fb 100644 --- a/code/modules/forensics/forensics_helpers.dm +++ b/code/modules/forensics/forensics_helpers.dm @@ -135,7 +135,7 @@ if(unique_blood[blood_type]) continue var/datum/blood_type/blood = find_blood_type(blood_type) - blood.set_up_blood(src, first_dna == 0) + blood.set_up_blood(src, first_dna == 0, only_type = length(blood_DNA_to_add) == 1) unique_blood[blood_type] = TRUE // handle smells refresh_smells() diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm index d43fdfa85800..48c0b24d6179 100644 --- a/code/modules/library/bibles.dm +++ b/code/modules/library/bibles.dm @@ -212,7 +212,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list( if(GLOB.religious_sect) return GLOB.religious_sect.sect_bless(blessed,user) if(!ishuman(blessed)) - return + return FALSE var/mob/living/carbon/human/built_in_his_image = blessed for(var/obj/item/bodypart/bodypart as anything in built_in_his_image.get_bodyparts()) if(!IS_ORGANIC_LIMB(bodypart)) @@ -265,6 +265,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list( smack_chance = GLOB.religious_sect.smack_chance var/success = !prob(smack_chance) && bless(target_mob, user) if(success) + SEND_SIGNAL(target_mob, COMSIG_LIVING_BLESSED, user, src, success) return if(iscarbon(target_mob)) var/mob/living/carbon/carbon_target = target_mob diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index bdb7ff67c520..f373c21fa07a 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -495,6 +495,49 @@ return quirk return null +/** + * get_quirk_string() is used to get a printable string of all the quirk traits someone has for certain criteria + * + * Arguments: + * * Medical- If we want the long, fancy descriptions that show up in medical records, or if not, just the name + * * Category- Which types of quirks we want to print out. Defaults to everything + * * from_scan- If the source of this call is like a health analyzer or HUD, in which case QUIRK_HIDE_FROM_MEDICAL hides the quirk. + */ +/mob/living/proc/get_quirk_string(medical = FALSE, category = CAT_QUIRK_ALL, from_scan = FALSE, none_text) + var/list/dat = list() + for(var/datum/quirk/candidate as anything in quirks) + if(from_scan && (candidate.quirk_flags & QUIRK_HIDE_FROM_SCAN)) + continue + if(medical && !candidate.medical_record_text) + continue + switch(category) + if(CAT_QUIRK_MAJOR_DISABILITY) + if(candidate.value >= -4) + continue + if(CAT_QUIRK_MINOR_DISABILITY) + if(!ISINRANGE(candidate.value, -4, -1)) + continue + if(CAT_QUIRK_NOTES) + if(candidate.value < 0) + continue + dat += medical ? candidate.medical_record_text : candidate.name + + if(!dat.len) + return isnull(none_text) ? (medical ? "No issues have been declared." : "None") : none_text + return medical ? dat.Join("
") : dat.Join(", ") + +/mob/living/proc/cleanse_quirk_datums() //removes all trait datums + QDEL_LAZYLIST(quirks) + +/mob/living/proc/transfer_quirk_datums(mob/living/to_mob) + // We could be done before the client was moved or after the client was moved + var/datum/preferences/to_pass = client || to_mob.client + + for(var/datum/quirk/quirk as anything in quirks) + quirk.remove_from_current_holder(quirk_transfer = TRUE) + quirk.add_to_holder(to_mob, quirk_transfer = TRUE, client_source = to_pass) + + /// Helper to easily add a personality by a typepath /mob/living/proc/add_personality(personality_type) var/datum/personality/personality = SSpersonalities.personalities_by_type[personality_type] @@ -515,6 +558,14 @@ for(var/personality_type in personalities) remove_personality(personality_type) +/// Returns a string with the names of the personalities of this mob, and their description as tooltip +/mob/living/proc/get_parsonality_string() + var/list/return_list = list() + for(var/personality_type in personalities) + var/datum/personality/personality = SSpersonalities.personalities_by_type[personality_type] + return_list += span_tooltip(personality.desc, personality.name) + return english_list(return_list) + /mob/living/proc/cure_husk(source) REMOVE_TRAIT(src, TRAIT_HUSK, source) if(HAS_TRAIT(src, TRAIT_HUSK)) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 62f4b8581089..9828633fc2e5 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -910,12 +910,17 @@ ) /obj/item/paper/construction + name = "construction paper" + icon = 'icons/effects/random_spawners.dmi' /obj/item/paper/construction/Initialize(mapload) . = ..() + icon = 'icons/obj/service/bureaucracy.dmi' color = pick(COLOR_RED, COLOR_LIME, COLOR_LIGHT_ORANGE, COLOR_DARK_PURPLE, COLOR_FADED_PINK, COLOR_BLUE_LIGHT) + update_appearance() /obj/item/paper/natural + name = "natural paper" color = COLOR_OFF_WHITE /obj/item/paper/crumpled diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 56f302acbdc1..88e2c27e13f9 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -32,8 +32,8 @@ /// How much paper is used for making a copy of paperwork. #define PAPERWORK_PAPER_USE 10 -/// Maximum capacity of a photocopier -#define MAX_PAPER_CAPACITY 60 +/// Paper capacity of a matter bin +#define MATTER_BIN_PAPER_CAPACITY 30 /// The maximum amount of copies you can make with one press of the copy button. #define MAX_COPIES_AT_ONCE 10 @@ -62,41 +62,94 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) desc = "Used to copy important documents and anatomy studies." icon = 'icons/obj/service/library.dmi' icon_state = "photocopier" + base_icon_state = "photocopier" density = TRUE power_channel = AREA_USAGE_EQUIP max_integrity = 300 integrity_failure = 0.33 interaction_flags_mouse_drop = NEED_DEXTERITY | ALLOW_RESTING - + circuit = /obj/item/circuitboard/machine/photocopier + + /// The max paper capacity this photocopier can store + var/max_paper_capacity + /// How long it takes to print something in seconds + var/time_to_print + /// How efficent our toner is when printing + var/toner_efficiency /// A reference to a mob on top of the photocopier trying to copy their ass. Null if there is no mob. var/mob/living/ass /// A reference to the toner cartridge that's inserted into the copier. Null if there is no cartridge. var/obj/item/toner/toner_cartridge + /// Type path of toner this photocopier should starts with. Null if he should start without it. + var/obj/item/toner/starting_toner /// How many copies will be printed with one click of the "copy" button. var/num_copies = 1 /// Used with photos. Determines if the copied photo will be in greyscale or color. var/color_mode = PHOTO_COLOR /// Indicates whether the printer is currently busy copying or not. var/busy = FALSE + /// How much does it cost to use this photocopier. + var/usage_cost = PHOTOCOPIER_FEE /// Variable that holds a reference to any object supported for photocopying inside the photocopier var/obj/object_copy /// Variable for the UI telling us how many copies are in the queue. var/copies_left = 0 /// The amount of paper this photocoper starts with. - var/starting_paper = 30 - /// A stack for all the empty paper we have newly inserted (LIFO) + var/starting_paper = 0 + /// The paper loaded into the machine var/list/paper_stack = list() - + /// Type path to the paper that's created when we're initalized + var/created_paper = /obj/item/paper + /// Typecache of objects that can be inserted and scanned into the photocopier for copying + var/static/list/whitelist_scannable_objects = typecacheof(list( + /obj/item/paper, + /obj/item/photo, + /obj/item/documents, + /obj/item/paperwork + )) + /// List of paper types that can be inserted as blank paper + var/static/list/valid_paper_types = list( + /obj/item/paper, + /obj/item/paper/carbon, + /obj/item/paper/construction, + /obj/item/paper/natural, + ) + +/obj/machinery/photocopier/prebuilt + starting_toner = /obj/item/toner + starting_paper = 30 + +/obj/machinery/photocopier/get_save_vars() + . = ..() + . += NAMEOF(src, paper_stack) + return . /obj/machinery/photocopier/Initialize(mapload) . = ..() - toner_cartridge = new(src) setup_components() AddElement(/datum/element/elevation, pixel_shift = 8) //enough to look like your bums are on the machine. + if(starting_paper) + paper_stack[created_paper] = starting_paper + if(starting_toner) + toner_cartridge = new starting_toner(src) /// Simply adds the necessary components for this to function. /obj/machinery/photocopier/proc/setup_components() - AddComponent(/datum/component/payment, PHOTOCOPIER_FEE, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL) + AddComponent(/datum/component/payment, usage_cost, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL) + +/obj/machinery/photocopier/RefreshParts() + . = ..() + max_paper_capacity = 0 + for(var/datum/stock_part/matter_bin/matter_bin in component_parts) + max_paper_capacity += MATTER_BIN_PAPER_CAPACITY * matter_bin.tier + + toner_efficiency = 1 + for(var/datum/stock_part/micro_laser/micro_laser in component_parts) + toner_efficiency += micro_laser.tier + + time_to_print = 5 SECONDS + for(var/datum/stock_part/scanning_module/scanning_module in component_parts) + time_to_print -= (scanning_module.tier SECONDS) /obj/machinery/photocopier/Exited(atom/movable/gone, direction) . = ..() @@ -104,20 +157,45 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) object_copy = null if(gone == toner_cartridge) toner_cartridge = null - if(gone in paper_stack) - paper_stack -= gone + +/obj/machinery/photocopier/dump_contents() + var/dump_location = drop_location() + + // object_copy can be a traitor objective, don't qdel + object_copy?.forceMove(dump_location) + toner_cartridge?.forceMove(dump_location) + + for(var/paper_path in paper_stack) + var/paper_amount = paper_stack[paper_path] + if(paper_amount <= 0) + stack_trace("Detected zero or negative [paper_path] amount inside photocopier. There should be at least 1 or more of paper amount inside the list") + continue + + for(var/i in 1 to paper_amount) + var/obj/item/paper/new_paper = new paper_path(dump_location) + if(!new_paper.pixel_y) + new_paper.pixel_y = rand(-3,3) + if(!new_paper.pixel_x) + new_paper.pixel_x = rand(-3,3) + + paper_stack.Remove(paper_path) + + update_appearance() /obj/machinery/photocopier/Destroy() // object_copy can be a traitor objective, don't qdel - if(object_copy) - object_copy.forceMove(drop_location()) + object_copy?.forceMove(drop_location()) QDEL_NULL(toner_cartridge) - QDEL_LIST(paper_stack) - + paper_stack = null ass = null //the mob isn't actually contained and just referenced, no need to delete it. return ..() +/obj/machinery/photocopier/on_deconstruction(disassembled) + if(disassembled) + dump_contents() + return ..() + /obj/machinery/photocopier/examine(mob/user) . = ..() if(object_copy) @@ -147,7 +225,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) static_data["blanks"] = blank_infos static_data["categories"] = category_names - static_data["max_paper_count"] = MAX_PAPER_CAPACITY + static_data["max_paper_count"] = max_paper_capacity static_data["max_copies"] = MAX_COPIES_AT_ONCE return static_data @@ -162,9 +240,9 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) data["is_photo"] = TRUE data["color_mode"] = color_mode - if(isAI(user)) + if(isAI(user) || isAdminGhostAI(user)) data["isAI"] = TRUE - data["can_AI_print"] = toner_cartridge && (toner_cartridge.charges >= PHOTO_TONER_USE) && (get_paper_count() >= PHOTO_PAPER_USE) + data["can_AI_print"] = toner_cartridge && (toner_cartridge.charges >= PHOTO_TONER_USE) && (get_paper_count(created_paper) >= PHOTO_PAPER_USE) else data["isAI"] = FALSE @@ -175,11 +253,24 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) else data["has_toner"] = FALSE + data["created_paper"] = created_paper + data["paper_stack"] = paper_stack data["paper_count"] = get_paper_count() + var/list/paper_types = list() + for(var/obj/item/paper/paper as anything in valid_paper_types) + paper_types += list(list( + name = paper::name, + icon = paper::icon, + icon_state = paper::icon_state, + amount = paper_stack[paper::type] || 0, + type = paper::type, + )) + data["paper_types"] = paper_types + return data -/obj/machinery/photocopier/ui_act(action, list/params) +/obj/machinery/photocopier/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) return @@ -224,7 +315,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) // Remove the paper/photo/document from the photocopier. if("remove") if(object_copy) - remove_photocopy(object_copy, usr) + remove_photocopy(usr, object_copy) object_copy = null else if(check_ass()) to_chat(ass, span_notice("You feel a slight pressure on your ass.")) @@ -272,6 +363,20 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) var/list/blank = GLOB.paper_blanks[params["code"]] do_copies(CALLBACK(src, PROC_REF(make_blank_print), blank), usr, PAPER_PAPER_USE, PAPER_TONER_USE, num_copies) return TRUE + if("select_paper_type") + if(check_busy(usr)) + return FALSE + + var/paper_path = text2path(params["created_paper"]) + + if(!ispath(paper_path, /obj/item/paper)) + return FALSE + + if(!paper_stack[paper_path]) + return FALSE + + created_paper = paper_path + return TRUE /// Returns the color used for the printing operation. If the color is below TONER_LOW_PERCENTAGE, it returns a gray color. /obj/machinery/photocopier/proc/get_toner_color() @@ -286,28 +391,38 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) busy = TRUE update_use_power(ACTIVE_POWER_USE) // fucking god proc - INVOKE_ASYNC(src, PROC_REF(do_copy_loop), copy_cb, user, paper_use, toner_use, copies_amount) + INVOKE_ASYNC(src, PROC_REF(do_copy_loop), user, copy_cb, paper_use, toner_use, copies_amount) + +/obj/machinery/photocopier/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + obj_flags |= EMAGGED + + playsound(src, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + visible_message(span_warning("Sparks fly out of [src]!")) + balloon_alert(user, "payment system shorted") + return TRUE /** * Will invoke the passed in `copy_cb` callback in 4 second intervals, and charge the user 5 credits for each copy made. * * Arguments: - * * copy_cb - a callback for which proc to call. Should only be one of the `make_x_copy()` procs, such as `make_paper_copy()`. * * user - the mob who clicked copy. + * * copy_cb - a callback for which proc to call. Should only be one of the `make_x_copy()` procs, such as `make_paper_copy()`. * * paper_use - the amount of paper used in this operation * * toner_use - the amount of toner used in this operation * * copies_amount - the amount of copies we should make */ -/obj/machinery/photocopier/proc/do_copy_loop(datum/callback/copy_cb, mob/user, paper_use, toner_use, copies_amount) +/obj/machinery/photocopier/proc/do_copy_loop(mob/user, datum/callback/copy_cb, paper_use, toner_use, copies_amount) var/error_message = null if(!toner_cartridge) copies_amount = 0 error_message = span_warning("An error message flashes across \the [src]'s screen: \"No toner cartridge found. Aborting.\"") - else if(toner_cartridge.charges < toner_use * copies_amount) - copies_amount = FLOOR(toner_cartridge.charges / toner_use, 1) + else if(toner_cartridge.charges < (toner_use / toner_efficiency) * copies_amount) + copies_amount = FLOOR(toner_cartridge.charges / (toner_use / toner_efficiency), 1) error_message = span_warning("An error message flashes across \the [src]'s screen: \"Not enough toner to perform [copies_amount >= 1 ? "full " : ""]operation.\"") - if(get_paper_count() < paper_use * copies_amount) - copies_amount = FLOOR(get_paper_count() / paper_use, 1) + if(get_paper_count(created_paper) < paper_use * copies_amount) + copies_amount = FLOOR(get_paper_count(created_paper) / paper_use, 1) error_message = span_warning("An error message flashes across \the [src]'s screen: \"Not enough paper to perform [copies_amount >= 1 ? "full " : ""]operation.\"") copies_left = copies_amount @@ -317,14 +432,11 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) reset_busy() return - if(attempt_charge(src, user, (copies_amount - 1) * PHOTOCOPIER_FEE) & COMPONENT_OBJ_CANCEL_CHARGE) - reset_busy() - return - if(error_message) to_chat(user, error_message) // if you managed to cancel the copy operation, tough luck. you aren't getting your money back. + var/list/copies_made = list() for(var/i in 1 to copies_amount) if(machine_stat & (BROKEN|NOPOWER)) break @@ -338,13 +450,25 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) break playsound(src, 'sound/machines/printer.ogg', 50, vary = FALSE) - sleep(4 SECONDS) + sleep(time_to_print) // reveal our copied item - copied_obj.forceMove(drop_location()) - give_pixel_offset(copied_obj) + if(!QDELETED(copied_obj)) + copied_obj.forceMove(drop_location()) + give_pixel_offset(copied_obj) + copies_made += copied_obj copies_left-- + if(copies_made.len) + if(!(obj_flags & EMAGGED) && attempt_charge(src, user, (copies_made.len - 1) * usage_cost) & COMPONENT_OBJ_CANCEL_CHARGE) + visible_message( + span_warning("An error message flashes across \the [src]'s screen."), \ + span_warning("Failed to charge bank account. Scrapping copies.") \ + ) + QDEL_LIST(copies_made) + else + to_chat(user, span_warning("Failed to copy object!")) + copies_left = 0 reset_busy() @@ -372,19 +496,36 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) copied_item.pixel_x = copied_item.base_pixel_x + rand(-10, 10) copied_item.pixel_y = copied_item.base_pixel_y + rand(-10, 10) -/// Gets the total amount of paper this printer has stored. -/obj/machinery/photocopier/proc/get_paper_count() - return length(paper_stack) + starting_paper +/** + * Gets the total amount of paper this printer has stored + * + * Returns the amount of paper stored in the photocopier if passed with no args + * If paper_type is supplied will only return the amount of that paper type + * + * Arguments: + * * paper_type - The paper type to check to see quantity stored + */ +/obj/machinery/photocopier/proc/get_paper_count(paper_type) + if(paper_type) + return paper_stack[paper_type] || 0 + + var/total_amount = 0 + for(var/paper_path in paper_stack) + var/paper_amount = paper_stack[paper_path] + if(paper_amount <= 0) + stack_trace("Detected zero or negative [paper_path] amount inside photocopier. There should be at least 1 or more of paper amount inside the list") + continue + + total_amount += paper_amount + + return total_amount /** * Returns an empty paper, used for blanks and paper copies. * Prioritizes `paper_stack`, creates new paper in case `paper_stack` is empty. */ -/obj/machinery/photocopier/proc/get_empty_paper() - var/obj/item/paper/new_paper = pop(paper_stack) - if(new_paper == null && starting_paper > 0) - new_paper = new /obj/item/paper - starting_paper-- +/obj/machinery/photocopier/proc/get_empty_paper(paper_type) + var/obj/item/paper/new_paper = new paper_type() return new_paper /** @@ -392,14 +533,12 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) * This lets us pretend we actually consumed paper when we were actually printing something that wasn't paper. */ /obj/machinery/photocopier/proc/delete_paper(number) - if(number > get_paper_count()) + if(!paper_stack[created_paper] || (number > paper_stack[created_paper])) CRASH("Trying to delete more paper than is stored in the photocopier") - for(var/i in 1 to number) - var/to_delete = pop(paper_stack) - if(to_delete) - qdel(to_delete) - else - starting_paper-- + + paper_stack[created_paper] -= number + if(paper_stack[created_paper] <= 0) + paper_stack.Remove(created_paper) /** * Handles the copying of paper. Transfers all the text, stamps and so on from the old paper, to the copy. @@ -410,8 +549,9 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) if(isnull(paper_copy)) return null - var/obj/item/paper/empty_paper = get_empty_paper() - toner_cartridge.charges -= PAPER_TONER_USE + var/obj/item/paper/empty_paper = get_empty_paper(created_paper) + delete_paper(PAPER_PAPER_USE) + use_toner(PAPER_TONER_USE) var/copy_colour = get_toner_color() @@ -429,7 +569,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) return null var/obj/item/photo/copied_pic = new(src, photo.Copy(photo_color == PHOTO_GREYSCALE ? TRUE : FALSE)) delete_paper(PHOTO_PAPER_USE) - toner_cartridge.charges -= PHOTO_TONER_USE + use_toner(PHOTO_TONER_USE) return copied_pic /** @@ -442,7 +582,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) return null var/obj/item/documents/photocopy/copied_doc = new(src, document_copy) delete_paper(DOCUMENT_PAPER_USE) - toner_cartridge.charges -= DOCUMENT_TONER_USE + use_toner(DOCUMENT_TONER_USE) return copied_doc /** @@ -460,13 +600,13 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) copied_paperwork.stamp_icon = "paper_stamp-pc" //Override with the photocopy overlay sprite copied_paperwork.add_stamp() delete_paper(PAPERWORK_PAPER_USE) - toner_cartridge.charges -= PAPERWORK_TONER_USE + use_toner(PAPERWORK_TONER_USE) return copied_paperwork /// Handles the copying of blanks. No mutating state, so this should not fail. /obj/machinery/photocopier/proc/make_blank_print(list/blank) var/copy_colour = get_toner_color() - var/obj/item/paper/printblank = get_empty_paper() + var/obj/item/paper/printblank = get_empty_paper(created_paper) var/printname = blank["name"] var/list/printinfo @@ -476,8 +616,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) printblank.name = "paper - '[printname]'" printblank.add_raw_text(printinfo, color = copy_colour) printblank.update_appearance() - - toner_cartridge.charges -= PAPER_TONER_USE + use_toner(PAPER_TONER_USE) return printblank /** @@ -489,17 +628,16 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) /obj/machinery/photocopier/proc/make_ass_copy() if(!check_ass()) return null - var/butt_icon_state = ass.get_butt_sprite() - if(isnull(butt_icon_state)) + var/icon/temp_img = ass.get_butt_sprite() + if(isnull(temp_img)) return null - var/icon/temp_img = icon('icons/mob/butts.dmi', butt_icon_state) var/obj/item/photo/copied_ass = new /obj/item/photo(src) var/datum/picture/toEmbed = new(name = "[ass]'s Ass", desc = "You see [ass]'s ass on the photo.", image = temp_img) toEmbed.psize_x = 128 toEmbed.psize_y = 128 copied_ass.set_picture(toEmbed, TRUE, TRUE) delete_paper(ASS_PAPER_USE) - toner_cartridge.charges -= ASS_TONER_USE + use_toner(ASS_TONER_USE) return copied_ass /** @@ -512,60 +650,133 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) * * object - the item we're trying to remove. * * user - the user removing the item. */ -/obj/machinery/photocopier/proc/remove_photocopy(obj/item/object, mob/user) +/obj/machinery/photocopier/proc/remove_photocopy(mob/user, obj/item/object) if(issilicon(user)) object.forceMove(drop_location()) return - try_put_in_hand(object, user) + object.forceMove(user.loc) + user.put_in_hands(object) to_chat(user, span_notice("You take [object] out of [src]. [busy ? "The [src] comes to a halt." : ""]")) +/obj/machinery/photocopier/update_icon_state() + . = ..() + icon_state = panel_open ? "[base_icon_state]2" : base_icon_state + +/obj/machinery/photocopier/screwdriver_act(mob/living/user, obj/item/tool) + return default_deconstruction_screwdriver(user, tool) + +/obj/machinery/photocopier/crowbar_act(mob/living/user, obj/item/tool) + return default_deconstruction_crowbar(user, tool) + /obj/machinery/photocopier/wrench_act(mob/living/user, obj/item/tool) . = ..() default_unfasten_wrench(user, tool) return ITEM_INTERACT_SUCCESS -/obj/machinery/photocopier/attackby(obj/item/object, mob/user, params) - if(istype(object, /obj/item/paper) || istype(object, /obj/item/photo) || istype(object, /obj/item/documents)) - if(istype(object, /obj/item/paper)) - var/obj/item/paper/paper = object - if(paper.is_empty()) - insert_empty_paper(paper, user) - return - insert_copy_object(object, user) +/obj/machinery/photocopier/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + // No infinite paper chain. You need the original paperwork to make more copies. + if(istype(tool, /obj/item/paperwork/photocopy)) + balloon_alert(user, "too blurry!") + to_chat(user, span_warning("The [tool] is far too messy to produce a good copy!")) + return ITEM_INTERACT_FAILURE + + if(istype(tool, /obj/item/paper/paperslip)) + balloon_alert(user, "too small!") + return ITEM_INTERACT_FAILURE + + if(istype(tool, /obj/item/blueprints)) + balloon_alert(user, "too large!") + to_chat(user, span_warning("\The [tool] is too large to put into the copier. You need to find something else to record the document.")) + return ITEM_INTERACT_FAILURE - else if(istype(object, /obj/item/toner)) + if(istype(tool, /obj/item/toner)) if(toner_cartridge) balloon_alert(user, "another cartridge inside!") - return - object.forceMove(src) - toner_cartridge = object - balloon_alert(user, "cartridge inserted") + return ITEM_INTERACT_FAILURE - else if(istype(object, /obj/item/blueprints)) - to_chat(user, span_warning("\The [object] is too large to put into the copier. You need to find something else to record the document.")) - - else if(istype(object, /obj/item/paperwork)) - if(istype(object, /obj/item/paperwork/photocopy)) //No infinite paper chain. You need the original paperwork to make more copies. - to_chat(user, span_warning("The [object] is far too messy to produce a good copy!")) - else - insert_copy_object(object, user) + tool.forceMove(src) + toner_cartridge = tool + balloon_alert(user, "cartridge inserted") + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/paperplane)) + balloon_alert(user, "flatten paper first!") + return ITEM_INTERACT_FAILURE + + if(istype(tool, /obj/item/paper)) + var/obj/item/paper/paper = tool + + if(paper.resistance_flags & ON_FIRE) + balloon_alert(user, "paper on fire!") + return ITEM_INTERACT_FAILURE + + if(paper.is_empty()) // if not empty it gets inserted as an object to be copied + if(!has_room_for_paper()) + balloon_alert(user, "cannot hold more paper!") + return ITEM_INTERACT_FAILURE + + insert_empty_paper(user, paper.type) + qdel(paper) + return ITEM_INTERACT_SUCCESS + + if(istype(tool, /obj/item/paper_bin)) + var/obj/item/paper_bin/paper_bin = tool + + if(!paper_bin.total_paper) + balloon_alert(user, "paper bin empty!") + return ITEM_INTERACT_FAILURE + + var/paper_inserted = 0 + for(var/obj/item/paper/stacked_paper in paper_bin.paper_stack) // insert all paper that is already initialized + var/is_empty = stacked_paper.is_empty() + var/is_room = has_room_for_paper() + if(!is_empty || !is_room) + continue + + insert_empty_paper(user, stacked_paper.type, silent=TRUE) + paper_bin.paper_stack -= stacked_paper + paper_bin.total_paper -= 1 + paper_inserted++ + qdel(stacked_paper) + + if(paper_bin.total_paper) // then insert non-initialized paper that is always considered empty paper + var/noninitialized_paper_total = paper_bin.total_paper - length(paper_bin.paper_stack) + var/paper_to_take = min(max_paper_capacity - get_paper_count(), noninitialized_paper_total) + if(paper_to_take) + insert_empty_paper(user, paper_bin.papertype, paper_to_take, silent=TRUE) + paper_inserted += paper_to_take + paper_bin.total_paper -= (paper_to_take) + + if(!paper_inserted && !has_room_for_paper()) // no paper was inserted because it was full + balloon_alert(user, "cannot hold more paper!") + return ITEM_INTERACT_FAILURE + + paper_bin.update_appearance() + // we use silent for insert_empty_paper() so that we don't spam balloon_alerts and instead condense them into one alert here + balloon_alert(user, "[paper_inserted] paper inserted") + return ITEM_INTERACT_SUCCESS + + if(is_type_in_typecache(tool, whitelist_scannable_objects)) + insert_copy_object(user, tool) + return ITEM_INTERACT_SUCCESS + + return NONE + +/// Check if there is enough room to insert paper +/obj/machinery/photocopier/proc/has_room_for_paper(mob/user, amount = 1) + return get_paper_count() < max_paper_capacity /// Proc that handles insertion of empty paper, useful for copying later. -/obj/machinery/photocopier/proc/insert_empty_paper(obj/item/paper/paper, mob/user) - if(istype(paper, /obj/item/paper/paperslip)) - return - if(get_paper_count() >= MAX_PAPER_CAPACITY) - balloon_alert(user, "cannot hold more paper!") - return - if(!user.temporarilyRemoveItemFromInventory(paper)) - return - paper_stack += paper - paper.forceMove(src) - balloon_alert(user, "paper inserted") - -/obj/machinery/photocopier/proc/insert_copy_object(obj/item/object, mob/user) +/obj/machinery/photocopier/proc/insert_empty_paper(mob/user, paper_type, amount = 1, silent = FALSE) + if(!paper_stack[paper_type]) + paper_stack[paper_type] = 0 + paper_stack[paper_type] += amount + if(!silent) + balloon_alert(user, "paper inserted") + +/obj/machinery/photocopier/proc/insert_copy_object(mob/user, obj/item/object) if(!copier_empty()) balloon_alert(user, "scanner tray occupied!") return @@ -578,7 +789,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) /obj/machinery/photocopier/atom_break(damage_flag) . = ..() - if(. && toner_cartridge.charges) + if(. && toner_cartridge?.charges) new /obj/effect/decal/cleanable/oil(get_turf(src)) toner_cartridge.charges = 0 @@ -636,6 +847,12 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) return TRUE return FALSE +/** + * Removes a certain amount of toner that is affected by the efficiency of stock parts + */ +/obj/machinery/photocopier/proc/use_toner(amount) + toner_cartridge.charges -= (amount / toner_efficiency) + /** * Checks if there is an item inserted into the copier or a mob sitting on top of it. * @@ -650,10 +867,11 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) /// Subtype of photocopier that is free to use. /obj/machinery/photocopier/gratis desc = "Does the same important paperwork, but it's free to use! The best type of free." + usage_cost = 0 // it's free! no charge! very cool and gratis-pilled. -/obj/machinery/photocopier/gratis/setup_components() - // it's free! no charge! very cool and gratis-pilled. - AddComponent(/datum/component/payment, 0, SSeconomy.get_dep_account(ACCOUNT_CIV), PAYMENT_CLINICAL) +/obj/machinery/photocopier/gratis/prebuilt + starting_toner = /obj/item/toner + starting_paper = 30 /* * Toner cartridge @@ -663,6 +881,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) desc = "A small, lightweight cartridge of Nanotrasen ValueBrand toner. Fits photocopiers and autopainters alike." icon = 'icons/obj/service/bureaucracy.dmi' icon_state = "tonercartridge" + w_class = WEIGHT_CLASS_SMALL grind_results = list(/datum/reagent/iodine = 40, /datum/reagent/iron = 10) var/charges = 5 var/max_charges = 5 @@ -674,9 +893,9 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) /obj/item/toner/large name = "large toner cartridge" desc = "A hefty cartridge of Nanotrasen ValueBrand toner. Fits photocopiers and autopainters alike." - grind_results = list(/datum/reagent/iodine = 90, /datum/reagent/iron = 10) charges = 25 max_charges = 25 + grind_results = list(/datum/reagent/iodine = 90, /datum/reagent/iron = 10) /obj/item/toner/extreme name = "extremely large toner cartridge" @@ -684,6 +903,12 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) charges = 200 max_charges = 200 +/obj/item/toner/infinite + name = "infinite toner cartridge" + desc = "...are you satisfied now?" + charges = INFINITY + max_charges = INFINITY + #undef PHOTOCOPIER_FEE #undef BLANKS_FILE_NAME #undef PAPER_PAPER_USE @@ -691,7 +916,7 @@ GLOBAL_LIST_INIT(paper_blanks, init_paper_blanks()) #undef DOCUMENT_PAPER_USE #undef ASS_PAPER_USE #undef PAPERWORK_PAPER_USE -#undef MAX_PAPER_CAPACITY +#undef MATTER_BIN_PAPER_CAPACITY #undef TONER_CHARGE_LOW_AMOUNT #undef PHOTO_GREYSCALE #undef PHOTO_COLOR diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index ad398c2b599e..bf624e02c360 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -313,7 +313,11 @@ // attempt to set the light's on/off status // will not switch on if broken/burned/empty /obj/machinery/light/proc/set_on(turn_on) + var/was_on = on on = (turn_on && status == LIGHT_OK) + if(on == was_on) + return + SEND_SIGNAL(src, COMSIG_LIGHT_FIXTURE_TOGGLED, on) update() /obj/machinery/light/get_cell() @@ -629,12 +633,15 @@ if(status == LIGHT_EMPTY || status == LIGHT_BROKEN) return + var/was_ok = (status == LIGHT_OK || status == LIGHT_BURNED) + status = LIGHT_BROKEN + + SEND_SIGNAL(src, COMSIG_LIGHT_FIXTURE_BROKEN, was_ok) if(!skip_sound_and_sparks) - if(status == LIGHT_OK || status == LIGHT_BURNED) + if(was_ok) playsound(loc, 'sound/effects/glasshit.ogg', 75, TRUE) if(on) do_sparks(3, TRUE, src) - status = LIGHT_BROKEN update() /obj/machinery/light/proc/fix() diff --git a/code/modules/research/designs/autolathe/multi-department_designs.dm b/code/modules/research/designs/autolathe/multi-department_designs.dm index b6cc72951134..8e88f505b603 100644 --- a/code/modules/research/designs/autolathe/multi-department_designs.dm +++ b/code/modules/research/designs/autolathe/multi-department_designs.dm @@ -9,6 +9,21 @@ RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_MISC, ) +/datum/design/flare + name = "Flare" + id = "flare" + build_type = AUTOLATHE | PROTOLATHE | AWAY_LATHE + materials = list( + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 0.5, + /datum/material/plasma = SMALL_MATERIAL_AMOUNT * 0.5, + /datum/material/plastic = SMALL_MATERIAL_AMOUNT * 0.5, + ) + build_path = /obj/item/flashlight/flare + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_MISC, + ) + /datum/design/crowbar name = "Pocket Crowbar" id = "crowbar" diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 74df51e520c2..4c206c4be3f1 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -1202,3 +1202,33 @@ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_CARGO ) departmental_flags = DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design/board/photopcopier + name = "Photocopier" + desc = "The circuit for a photocopier." + id = "photocopier" + build_path = /obj/item/circuitboard/machine/photocopier + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_SERVICE + ) + departmental_flags = DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SERVICE + +// /datum/design/board/atmosshieldgen +// name = "Atmospherics Shield Generator Board" +// desc = "The circuit board for an atmospherics shield generator." +// id = "atmosshieldgen" +// build_path = /obj/item/circuitboard/machine/atmos_shield_gen +// category = list( +// RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ATMOS +// ) +// departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design/board/washing_machine + name = "Washing Machine" + desc = "The circuit board to build a washing machine." + id = "washing_machine" + build_path = /obj/item/circuitboard/machine/washing_machine + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_SERVICE + ) + departmental_flags = DEPARTMENT_BITFLAG_SERVICE diff --git a/code/modules/research/techweb/nodes/service_nodes.dm b/code/modules/research/techweb/nodes/service_nodes.dm index 125b3fef0563..6d5f5a434970 100644 --- a/code/modules/research/techweb/nodes/service_nodes.dm +++ b/code/modules/research/techweb/nodes/service_nodes.dm @@ -33,10 +33,12 @@ "normtrash", "wirebrush", "flashlight", + "flare", "water_balloon", "ticket_machine", "radio_entertainment", "barber_scissors", + "photocopier", ) /datum/techweb_node/sanitation @@ -52,6 +54,7 @@ "beartrap", "buffer", "vacuum", + "washing_machine", ) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = TECHWEB_TIER_2_POINTS) discount_experiments = list(/datum/experiment/scanning/random/janitor_trash = TECHWEB_TIER_2_POINTS) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index e7093ece0393..d4ca5ce02a5d 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -1451,7 +1451,8 @@ GLOBAL_LIST_EMPTY(vending_machines_to_restock) if(greyscale_colors) vended_item.set_greyscale(colors=greyscale_colors) item_record.amount-- - if(usr.CanReach(src) && try_put_in_hand(vended_item, usr)) + var/sigreturn = SEND_SIGNAL(usr, COMSIG_MOB_VENDING_PURCHASE, src, vended_item) + if(!(sigreturn & VENDING_NO_PICKUP) && usr.CanReach(src) && try_put_in_hand(vended_item, usr)) to_chat(usr, span_notice("You take [item_record.name] out of the slot.")) else to_chat(usr, span_warning("[capitalize(format_text(item_record.name))] falls onto the floor!")) diff --git a/icons/obj/wallmounts.dmi b/icons/obj/wallmounts.dmi index e70024a9edb2..2e7cb6b0f623 100644 Binary files a/icons/obj/wallmounts.dmi and b/icons/obj/wallmounts.dmi differ diff --git a/maplestation_modules/code/modules/mob/living/blood.dm b/maplestation_modules/code/modules/mob/living/blood.dm index 866b6ccfcfe9..7aeab63d3c62 100644 --- a/maplestation_modules/code/modules/mob/living/blood.dm +++ b/maplestation_modules/code/modules/mob/living/blood.dm @@ -118,8 +118,9 @@ PROCESSING_SUBSYSTEM_DEF(blood_drying) * Arguments * * blood - the blood being set up * * new_splat - whether this is a newly instantiated blood decal, or an existing one this blood is being added to + * * only_type - whether this blood decal is only of this blood type, or if it has other blood types mixed in */ -/datum/blood_type/proc/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat = FALSE) +/datum/blood_type/proc/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat = FALSE, only_type = TRUE) return /** @@ -301,7 +302,7 @@ PROCESSING_SUBSYSTEM_DEF(blood_drying) restoration_chem = /datum/reagent/silver scent_text = null -/datum/blood_type/silver/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat) +/datum/blood_type/silver/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat, only_type) blood.can_dry = FALSE blood.emissive_alpha = max(blood.emissive_alpha, new_splat ? 125 : 63) @@ -323,7 +324,7 @@ PROCESSING_SUBSYSTEM_DEF(blood_drying) salgu_compatible = TRUE scent_text = null -/datum/blood_type/crew/ethereal/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat) +/datum/blood_type/crew/ethereal/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat, only_type) blood.emissive_alpha = max(blood.emissive_alpha, new_splat ? 188 : 125) if(!new_splat) return @@ -357,7 +358,7 @@ PROCESSING_SUBSYSTEM_DEF(blood_drying) restoration_chem = /datum/reagent/fuel/oil scent_text = /datum/smell/oil -/datum/blood_type/oil/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat) +/datum/blood_type/oil/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat, only_type) if(!new_splat) return // Oil blood will never dry and can be ignited with fire @@ -402,6 +403,11 @@ PROCESSING_SUBSYSTEM_DEF(blood_drying) salgu_compatible = TRUE scent_text = null +/datum/blood_type/water/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat, only_type) + if(!new_splat || !only_type) + return + blood.qdel_on_dry = TRUE + /// Snails have Lube for blood, for some reason? /datum/blood_type/snail name = "Lube" @@ -410,7 +416,7 @@ PROCESSING_SUBSYSTEM_DEF(blood_drying) scent_text = /obj/effect/abstract/smell/reagent/lube::name scent_category = /obj/effect/abstract/smell/reagent/lube::category -/datum/blood_type/snail/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat) +/datum/blood_type/snail/set_up_blood(obj/effect/decal/cleanable/blood/blood, new_splat, only_type) if(blood.bloodiness < BLOOD_AMOUNT_PER_DECAL) return var/slip_amt = new_splat ? 4 SECONDS : 1 SECONDS diff --git a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/synth/android.dm b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/synth/android.dm index b7bfaf46fd3b..e8a9bc8feb3c 100644 --- a/maplestation_modules/code/modules/mob/living/carbon/human/species_types/synth/android.dm +++ b/maplestation_modules/code/modules/mob/living/carbon/human/species_types/synth/android.dm @@ -432,7 +432,7 @@ /datum/species/android/proc/update_heat_modifiers(mob/living/carbon/human/source) var/obj/item/organ/lungs = source.get_organ_slot(ORGAN_SLOT_LUNGS) if(HAS_TRAIT_NOT_FROM_LUNGS(source, TRAIT_RESISTHEAT, lungs)) - remove_heat_modifiers() + remove_heat_modifiers(source) return if(source.body_temperature > source.bodytemp_heat_damage_limit * 2) @@ -461,12 +461,12 @@ else // ?? if(is_overheating != 0) - remove_heat_modifiers() + remove_heat_modifiers(source) /datum/species/android/proc/update_cold_modifiers(mob/living/carbon/human/source) var/obj/item/organ/lungs = source.get_organ_slot(ORGAN_SLOT_LUNGS) if(HAS_TRAIT_NOT_FROM_LUNGS(source, TRAIT_RESISTCOLD, lungs)) - remove_cold_modifiers() + remove_cold_modifiers(source) return if(source.body_temperature < source.bodytemp_cold_damage_limit * 2) @@ -495,7 +495,7 @@ else // ?? if(is_overcooled != 0) - remove_cold_modifiers() + remove_cold_modifiers(source) #undef HAS_TRAIT_NOT_FROM_LUNGS diff --git a/tgui/packages/tgui/interfaces/Photocopier.tsx b/tgui/packages/tgui/interfaces/Photocopier.tsx index 40ae11f5dba7..d4f4ebe98bd3 100644 --- a/tgui/packages/tgui/interfaces/Photocopier.tsx +++ b/tgui/packages/tgui/interfaces/Photocopier.tsx @@ -1,6 +1,7 @@ import { useState } from 'react'; import { Button, + ImageButton, Input, LabeledList, ProgressBar, @@ -30,6 +31,16 @@ type Data = { paper_count: number; max_paper_count: number; blanks: Blank[]; + paper_types: Paper[]; + created_paper: string; +}; + +type Paper = { + name: string; + icon: string; + icon_state: string; + amount: number; + type: string; }; type Blank = { @@ -45,7 +56,7 @@ export const Photocopier = (props) => { return ( @@ -100,6 +111,8 @@ const Status = (props: StatusProps) => { max_toner, paper_count, max_paper_count, + paper_types, + created_paper, } = data; const average_toner = max_toner * 0.66; @@ -166,6 +179,29 @@ const Status = (props: StatusProps) => { {selectedBlank ? selectedBlank : 'Not Selected'} + + + + {paper_types.map((paper) => ( + + + act('select_paper_type', { + created_paper: paper.type, + }) + } + /> + + ))} + + ); diff --git a/tools/UpdatePaths/Scripts/90685_buildable_photocopiers.txt b/tools/UpdatePaths/Scripts/90685_buildable_photocopiers.txt new file mode 100644 index 000000000000..da25320533f7 --- /dev/null +++ b/tools/UpdatePaths/Scripts/90685_buildable_photocopiers.txt @@ -0,0 +1 @@ +/obj/machinery/photocopier : /obj/machinery/photocopier/prebuilt{@OLD} \ No newline at end of file