diff --git a/_maps/RandomRuins/SpaceRuins/cloning_facility.dmm b/_maps/RandomRuins/SpaceRuins/cloning_facility.dmm index 1fb4e60aff..d440e2d15b 100644 --- a/_maps/RandomRuins/SpaceRuins/cloning_facility.dmm +++ b/_maps/RandomRuins/SpaceRuins/cloning_facility.dmm @@ -69,7 +69,7 @@ /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/powered/ancient_shuttle) "j" = ( -/obj/machinery/computer/prototype_cloning, +/obj/machinery/computer/cloning/prototype, /obj/machinery/light{ dir = 1 }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index eda78e4206..588b55679c 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -263,15 +263,484 @@ }, /turf/open/floor/plasteel, /area/maintenance/department/engine) +"aaD" = ( +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/closet/crate{ + icon_state = "crateopen" + }, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/obj/item/clothing/mask/balaclava, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"aaE" = ( +/obj/machinery/light/small, +/obj/machinery/space_heater, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"aaF" = ( +/turf/closed/wall, +/area/crew_quarters/fitness/pool) +"aaG" = ( +/obj/structure/closet, +/obj/item/weldingtool, +/obj/item/crowbar, +/obj/effect/spawner/lootdrop/maintenance, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"aaH" = ( +/obj/machinery/door/airlock/maintenance{ + req_access_txt = "12" + }, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"aaI" = ( +/obj/structure/closet/secure_closet/personal, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/fitness/pool) +"aaJ" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/crew_quarters/fitness/pool) +"aaK" = ( +/obj/machinery/light{ + dir = 1; + light_color = "#706891" + }, +/obj/structure/closet/secure_closet/personal, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/fitness/pool) +"aaL" = ( +/turf/open/floor/plasteel/yellowsiding, +/area/crew_quarters/fitness/pool) +"aaM" = ( +/turf/open/floor/plasteel/yellowsiding/corner{ + icon_state = "yellowcornersiding"; + dir = 8 + }, +/area/crew_quarters/fitness/pool) +"aaN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaO" = ( +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"aaP" = ( +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 8 + }, +/area/crew_quarters/fitness/pool) +"aaQ" = ( +/obj/structure/table, +/obj/effect/spawner/lootdrop/maintenance, +/obj/item/storage/box/lights/mixed, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"aaR" = ( +/obj/machinery/airalarm{ + pixel_y = 22 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaS" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaT" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Pool" + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/sign/poster/official/walk{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaV" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/structure/extinguisher_cabinet{ + pixel_y = 30 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaW" = ( +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"aaX" = ( +/obj/structure/bed, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/fitness/pool) +"aaY" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/crew_quarters/fitness/pool) +"aaZ" = ( +/obj/structure/bed, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/crew_quarters/fitness/pool) +"aba" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/recreation) +"abb" = ( +/obj/machinery/camera{ + c_tag = "Fitness Room" + }, +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = 32 + }, +/obj/machinery/light{ + dir = 1 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/recreation) +"abc" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/yellowsiding/corner, +/area/crew_quarters/fitness/pool) +"abd" = ( +/obj/structure/closet/lasertag/red, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abe" = ( +/obj/machinery/vending/kink, +/obj/machinery/status_display/evac{ + pixel_x = 32; + pixel_y = 32 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) "abf" = ( /obj/structure/bed, /turf/open/floor/plating, /area/maintenance/department/science) +"abg" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abh" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/closet/lasertag/blue, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abi" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abj" = ( +/obj/machinery/pool/controller, +/turf/open/floor/plasteel/yellowsiding, +/area/crew_quarters/fitness/pool) +"abk" = ( +/obj/machinery/light{ + dir = 4; + light_color = "#e8eaff" + }, +/obj/structure/bed, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/crew_quarters/fitness/pool) +"abl" = ( +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/recreation) +"abm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) +"abn" = ( +/obj/machinery/pool/filter{ + pixel_y = 24 + }, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abo" = ( +/obj/structure/pool/ladder{ + dir = 2; + pixel_y = 24 + }, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abp" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/crew_quarters/fitness/pool) +"abq" = ( +/obj/machinery/light{ + dir = 8; + light_color = "#e8eaff" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) +"abr" = ( +/obj/machinery/pool/drain, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abs" = ( +/obj/structure/pool/Lboard, +/turf/open/pool, +/area/crew_quarters/fitness/pool) +"abt" = ( +/obj/structure/pool/Rboard, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 8 + }, +/area/crew_quarters/fitness/pool) +"abu" = ( +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = 28 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/crew_quarters/fitness/pool) +"abv" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/cigbutt, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"abw" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/table/glass, +/obj/item/storage/firstaid/regular, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/pool) +"abx" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/closet/athletic_mixed, +/obj/item/toy/poolnoodle/blue, +/obj/item/toy/poolnoodle/red, +/obj/item/toy/poolnoodle/yellow, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/crew_quarters/fitness/pool) "aby" = ( /obj/structure/lattice, /obj/structure/grille, /turf/open/space, /area/space/nearstation) +"abz" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -24 + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/fitness/pool) +"abA" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/yellowsiding/corner{ + icon_state = "yellowcornersiding"; + dir = 4 + }, +/area/crew_quarters/fitness/pool) +"abB" = ( +/obj/machinery/firealarm{ + dir = 1; + pixel_x = -2; + pixel_y = -27 + }, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"abC" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/yellowsiding{ + icon_state = "yellowsiding"; + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"abD" = ( +/turf/open/floor/plasteel/yellowsiding/corner{ + icon_state = "yellowcornersiding"; + dir = 1 + }, +/area/crew_quarters/fitness/pool) +"abE" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/power/apc{ + areastring = "/area/crew_quarters/fitness/pool"; + name = "Pool APC"; + pixel_y = -24 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/turf/open/floor/plasteel/white/corner, +/area/crew_quarters/fitness/pool) +"abF" = ( +/obj/machinery/door/airlock/maintenance{ + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, +/area/crew_quarters/fitness/pool) +"abG" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"abH" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/door/airlock/public/glass{ + name = "Pool" + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/fitness/pool) "abI" = ( /obj/structure/lattice, /turf/open/space, @@ -285,6 +754,26 @@ }, /turf/open/space, /area/space/nearstation) +"abK" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/crew_quarters/fitness/recreation) +"abL" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) "abN" = ( /obj/effect/landmark/carpspawn, /turf/open/space, @@ -292,6 +781,42 @@ "abO" = ( /turf/closed/wall/r_wall, /area/ai_monitored/turret_protected/ai) +"abP" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abQ" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abR" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abS" = ( +/obj/structure/weightmachine/stacklifter, +/turf/open/floor/plasteel, +/area/crew_quarters/fitness/recreation) +"abT" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/airlock/public/glass{ + name = "Pool" + }, +/turf/open/floor/plasteel/cafeteria, +/area/crew_quarters/fitness/pool) "abV" = ( /obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel/white, @@ -3820,18 +4345,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) -"akq" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/machinery/light/small{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "akr" = ( /obj/machinery/washing_machine, /obj/item/radio/intercom{ @@ -5230,16 +5743,6 @@ }, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) -"anp" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/effect/decal/cleanable/robot_debris{ - icon_state = "gib6" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "anq" = ( /obj/structure/grille/broken, /turf/open/floor/plating, @@ -6932,10 +7435,6 @@ }, /turf/open/space/basic, /area/space) -"aqZ" = ( -/obj/machinery/space_heater, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "ara" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -7525,35 +8024,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/crew_quarters/dorms) -"asl" = ( -/obj/structure/grille/broken, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) -"asm" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/light{ - dir = 1 - }, -/obj/item/cigbutt, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) -"asn" = ( -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/obj/effect/decal/cleanable/cobweb{ - icon_state = "cobweb2" - }, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "aso" = ( /obj/structure/cable{ icon_state = "1-2" @@ -8021,26 +8491,9 @@ /obj/structure/closet/emcloset/anchored, /turf/open/floor/plating, /area/crew_quarters/dorms) -"atm" = ( -/obj/structure/closet, -/obj/item/weldingtool, -/obj/item/crowbar, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "atn" = ( /turf/closed/wall, /area/crew_quarters/fitness/recreation) -"ato" = ( -/obj/structure/closet/crate{ - icon_state = "crateopen" - }, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 2; - name = "2maintenance loot spawner" - }, -/obj/item/clothing/mask/balaclava, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "atp" = ( /obj/structure/cable{ icon_state = "1-2" @@ -8506,41 +8959,6 @@ }, /turf/open/floor/plating, /area/crew_quarters/dorms) -"aun" = ( -/obj/structure/table, -/obj/effect/spawner/lootdrop/maintenance, -/obj/item/storage/box/lights/mixed, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) -"auo" = ( -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) -"aup" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/grille/broken, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) -"auq" = ( -/obj/effect/spawner/lootdrop/maintenance, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) "aur" = ( /turf/open/floor/engine{ name = "Holodeck Projector Floor" @@ -9564,57 +9982,6 @@ }, /turf/open/floor/plating, /area/crew_quarters/fitness/recreation) -"awy" = ( -/obj/structure/closet/lasertag/blue, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/airalarm{ - pixel_y = 22 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white/corner{ - dir = 1 - }, -/area/crew_quarters/fitness/recreation) -"awz" = ( -/obj/structure/closet/lasertag/red, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/status_display/evac{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white/corner{ - dir = 1 - }, -/area/crew_quarters/fitness/recreation) -"awA" = ( -/obj/machinery/disposal/bin, -/obj/machinery/light{ - dir = 1 - }, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, -/obj/machinery/camera{ - c_tag = "Fitness Room" - }, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white/corner{ - dir = 1 - }, -/area/crew_quarters/fitness/recreation) "awB" = ( /obj/machinery/vending/clothing, /obj/effect/turf_decal/tile/blue{ @@ -10025,10 +10392,6 @@ "axw" = ( /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) -"axx" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel, -/area/crew_quarters/fitness/recreation) "axy" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -10406,13 +10769,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) -"ayv" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/obj/structure/weightmachine/stacklifter, -/turf/open/floor/plasteel, -/area/crew_quarters/fitness/recreation) "ayw" = ( /obj/machinery/computer/holodeck{ dir = 4 @@ -54124,15 +54480,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/kitchen) -"gcj" = ( -/obj/machinery/vending/kink, -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/plasteel/white/corner{ - dir = 1 - }, -/area/crew_quarters/fitness/recreation) "gdJ" = ( /obj/structure/table/glass, /obj/item/folder/blue, @@ -102547,11 +102894,11 @@ aaa aaa aaa aaa -apX -apX -apX -apX -apX +aaF +aaF +aaF +aaF +atn atn aww axv @@ -102798,19 +103145,19 @@ aaa aiS cBy aiS -aiS -aiS -aiT -aiT -aiT -aiS -aiS -aiS -aiS -atm -aun -atn -awz +aaF +aaF +aaJ +aaJ +aaJ +aaF +aaF +abw +abz +abH +abl +axw +abg axw ayu azC @@ -103053,23 +103400,23 @@ aaa aaa aaa aiT -akq -ale -ale -ale -anp -ale -ale -ale -ale -ale -ale -ale -auo -atn -awy -axw -ayu +akn +ajv +aaH +aaN +abc +abm +abm +abq +abm +abm +abA +abT +abK +abL +abM +abP +abR azC axw aBU @@ -103310,23 +103657,23 @@ aaa aaa aaa aiS -aiS -aiS -aiS -aiS -aiT -aiT -aiT -aiS -aiS -aiS -asl -aiS -aup -atn -awA -axx -ayv +akn +aaE +aaF +aaR +aaL +aaO +aaO +aaO +aaO +aaO +aaW +aaF +abb +abd +abh +abQ +abS azD aAS aat @@ -103566,22 +103913,22 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aiS -apu -ale -auq -atn -awB +akn +aaG +aaF +aaS +aaL +abn +aaO +aaO +aaO +aaO +aaW +aaY +aba +axw +abg axw axw axw @@ -103823,22 +104170,22 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aiS akn -ajv -aqZ -atn -gcj +aaF +aaF +aaS +abj +aaO +aaO +aaO +aaO +aaO +aaW +aaY +awB +abe +abi axw axw axw @@ -104080,18 +104427,18 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa aiS akn +aaF +aaI +aaS +aaL +abo +aaO +abr +aaO +aaO +abB atn atn avm @@ -104337,18 +104684,18 @@ rmC aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aiT +aiS akn +aaF +aaK +aaS +aaL +aaO +aaO +aaO +aaO +aaO +abC atn aur aur @@ -104591,22 +104938,22 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC aaa aaa aaa -aaa -aiT +aiS akn -atn +aaF +aaI +aaS +aaL +aaO +aaO +aaO +aaO +aaO +aaW +avm aur aur aur @@ -104848,22 +105195,22 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiS -asm -atn +akn +aaF +aaF +aaT +aaL +aaO +aaO +aaO +aaO +aaO +aaW +avm aur aur aur @@ -105105,22 +105452,22 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiT akn -atn +ajv +aaF +aaU +aaL +aaO +aaO +abs +aaO +aaO +aaW +avm aur aur aur @@ -105362,21 +105709,21 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiT akn +aaQ +aaF +aaV +aaM +aaP +aaP +abt +aaP +aaP +abD atn aur aur @@ -105619,21 +105966,21 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiS akn +sbk +aaF +aaX +aaZ +aaZ +abk +abp +abu +abx +abE atn atn avm @@ -105876,22 +106223,22 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiS akn -ato +ajv +aaF +aaF +aaF +aaF +aaF +aaF +aaF +aaF +abF +aaF aiS atn awC @@ -106133,21 +106480,21 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiS -asn +aaD +ale +ale +ale +ale +ale +ale +ale +abv +ale +abG ale ale avn @@ -106390,20 +106737,20 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -aaa aaa aaa aaa aiS +aiS +aiS +aiS +aiS +aiT +aiS +aiS +aiS +aiS +aiS aiT aiS aiS @@ -106647,15 +106994,15 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -106904,15 +107251,15 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -107161,15 +107508,15 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -107418,15 +107765,15 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -107675,15 +108022,15 @@ rmC rmC rmC rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC -rmC +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index fe06b7037e..0e8e34d20e 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -118,4 +118,4 @@ #define CLONEPOD_GET_MIND 1 #define CLONEPOD_POLL_MIND 2 -#define CLONEPOD_NO_MIND 3 +#define CLONEPOD_NO_MIND 3 \ No newline at end of file diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 3391458817..78a0365ac0 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -109,7 +109,7 @@ /obj/machinery/clonepod/attack_ai(mob/user) return examine(user) -//Start growing a clone in the pod! +//Start growing a human clone in the pod! /obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, blood_type, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance, list/traumas) if(panel_open) return FALSE diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 7834d6f2a2..400ce041c7 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -8,6 +8,7 @@ circuit = /obj/item/circuitboard/computer/cloning req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW. var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. + var/clonepod_type = /obj/machinery/clonepod var/list/pods //Linked cloning pods var/temp = "Inactive" var/scantemp_ckey @@ -17,6 +18,7 @@ var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. var/loading = 0 // Nice loading text var/autoprocess = 0 + var/use_records = TRUE // Old experimental cloner. var/list/records = list() light_color = LIGHT_COLOR_BLUE @@ -36,29 +38,32 @@ return ..() /obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.occupant && pod.clonemind == mind) - return null - if(pod.is_operational() && !(pod.occupant || pod.mess)) - return pod + if(!pods) + return + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.occupant && pod.get_clone_mind == CLONEPOD_GET_MIND && pod.clonemind == mind) + return null + if(pod.is_operational() && !(pod.occupant || pod.mess)) + return pod /obj/machinery/computer/cloning/proc/HasEfficientPod() - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.is_operational() && pod.efficiency > 5) - return TRUE + if(!pods) + return + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.is_operational() && pod.efficiency > 5) + return TRUE /obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.occupant && pod.clonemind == mind) - return pod - else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5) - . = pod + if(!pods) + return + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.occupant && pod.clonemind == mind) + return pod + else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5) + . = pod /obj/machinery/computer/cloning/process() if(!(scanner && LAZYLEN(pods) && autoprocess)) @@ -73,7 +78,7 @@ if(pod.occupant) continue //how though? - if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"])) + if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["blood_type"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"])) temp = "[R.fields["name"]] => Cloning cycle in progress..." records -= R @@ -103,12 +108,10 @@ return null /obj/machinery/computer/cloning/proc/findcloner() - var/obj/machinery/clonepod/podf = null - + var/obj/machinery/clonepod/podf for(var/direction in GLOB.cardinals) - - podf = locate(/obj/machinery/clonepod, get_step(src, direction)) - if (!isnull(podf) && podf.is_operational()) + podf = locate(clonepod_type, get_step(src, direction)) + if(podf?.is_operational()) AttachCloner(podf) /obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) @@ -132,7 +135,7 @@ else if(istype(W, /obj/item/multitool)) var/obj/item/multitool/P = W - if(istype(P.buffer, /obj/machinery/clonepod)) + if(istype(P.buffer, clonepod_type)) if(get_area(P.buffer) != get_area(src)) to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %-") P.buffer = null @@ -157,13 +160,14 @@ var/dat = "" dat += "Refresh" - if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL) - if(!autoprocess) - dat += "Autoclone" + if(use_records) + if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL) + if(!autoprocess) + dat += "Autoclone" + else + dat += "Stop autoclone" else - dat += "Stop autoclone" - else - dat += "Autoclone" + dat += "Autoclone" dat += "

Cloning Pod Status

" dat += "
[temp] 
" @@ -190,26 +194,29 @@ else if(loading) dat += "[scanner_occupant] => Scanning..." else - if(scanner_occupant.ckey != scantemp_ckey) - scantemp = "Ready to Scan" - scantemp_ckey = scanner_occupant.ckey + if(use_records) + if(scanner_occupant.ckey != scantemp_ckey) + scantemp = "Ready to Scan" + scantemp_ckey = scanner_occupant.ckey + else + scantemp = "Ready to Clone" dat += "[scanner_occupant] => [scantemp]" dat += "" if(scanner_occupant) - dat += "Start Scan" - dat += "
[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" + dat += "[use_records ? "Start Scan" : "Clone"]" + dat += "
[scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" else - dat += "Start Scan" - - // Database - dat += "

Database Functions

" - if (src.records.len && src.records.len > 0) - dat += "View Records ([src.records.len])
" - else - dat += "View Records (0)
" - if (src.diskette) - dat += "Eject Disk
" + dat += "[use_records ? "Start Scan" : "Clone"]" + if(use_records) + // Database + dat += "

Database Functions

" + if (src.records.len && src.records.len > 0) + dat += "View Records ([src.records.len])
" + else + dat += "View Records (0)
" + if (src.diskette) + dat += "Eject Disk
" @@ -290,24 +297,19 @@ autoprocess = FALSE STOP_PROCESSING(SSmachines, src) playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + . = TRUE else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational()) scantemp = "" - loading = 1 + loading = TRUE src.updateUsrDialog() playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) say("Initiating scan...") var/prev_locked = scanner.locked scanner.locked = TRUE - spawn(20) - src.scan_occupant(scanner.occupant) - - loading = 0 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - scanner.locked = prev_locked - + addtimer(CALLBACK(src, .proc/finish_scan, scanner.occupant, prev_locked), 2 SECONDS) + . = TRUE //No locking an open scanner. else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) @@ -317,8 +319,17 @@ else scanner.locked = FALSE playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + . = TRUE - else if(href_list["view_rec"]) + + else if (href_list["refresh"]) + src.updateUsrDialog() + playsound(src, "terminal_type", 25, 0) + . = TRUE + + if(. || !use_records) + return + if(href_list["view_rec"]) playsound(src, "terminal_type", 25, 0) src.active_record = find_record("id", href_list["view_rec"], records) if(active_record) @@ -330,6 +341,7 @@ src.menu = 3 else src.temp = "Record missing." + . = TRUE else if (href_list["del_rec"]) if ((!src.active_record) || (src.menu < 3)) @@ -353,8 +365,9 @@ else src.temp = "Access Denied." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + . = TRUE - else if (href_list["disk"]) //Load or eject. + else if (href_list["disk"] && use_records) //Load or eject. switch(href_list["disk"]) if("load") if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) @@ -392,10 +405,7 @@ diskette.name = "data disk - '[src.diskette.fields["name"]]'" src.temp = "Save successful." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if (href_list["refresh"]) - src.updateUsrDialog() - playsound(src, "terminal_type", 25, 0) + . = TRUE else if (href_list["clone"]) var/datum/data/record/C = find_record("id", href_list["clone"], records) @@ -415,7 +425,7 @@ else if(pod.occupant) temp = "Cloning cycle already in progress." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"], C.fields["bank_account"])) + else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["blood_type"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"], C.fields["bank_account"], C.fields["traumas"])) temp = "[C.fields["name"]] => Cloning cycle in progress..." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) records.Remove(C) @@ -429,14 +439,28 @@ else temp = "Data corruption." playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + . = TRUE - else if (href_list["menu"]) - src.menu = text2num(href_list["menu"]) + else if (href_list["menu"] && use_records) + menu = text2num(href_list["menu"]) playsound(src, "terminal_type", 25, 0) + . = TRUE +/obj/machinery/computer/cloning/proc/finish_scan(mob/living/L, prev_locked) + if(!scanner || !L) + return src.add_fingerprint(usr) src.updateUsrDialog() - return + + if(use_records) + scan_occupant(L) + else + clone_occupant(L) + + loading = FALSE + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + scanner.locked = prev_locked /obj/machinery/computer/cloning/proc/scan_occupant(occupant) var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) @@ -455,30 +479,9 @@ if(isbrain(mob_occupant)) dna = B.stored_dna - if(!istype(dna)) - scantemp = "Unable to locate valid genetic data." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if(mob_occupant.suiciding || mob_occupant.hellbound) - scantemp = "Subject's brain is not responding to scanning stimuli." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if((HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) - scantemp = "Subject no longer contains the fundamental materials required to create a living clone." - playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) - return - if ((!mob_occupant.ckey) || (!mob_occupant.client)) - scantemp = "Mental interface failure." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if (find_record("ckey", mob_occupant.ckey, records)) - scantemp = "Subject already in database." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if(SSeconomy.full_ancap && !has_bank_account) - scantemp = "Subject is either missing an ID card with a bank account on it, or does not have an account to begin with. Please ensure the ID card is on the body before attempting to scan." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + if(!can_scan(dna, mob_occupant, FALSE, has_bank_account)) return + var/datum/data/record/R = new() if(dna.species) // We store the instance rather than the path, because some @@ -529,3 +532,78 @@ board.records = records scantemp = "Subject successfully scanned." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + +//Used by the experimental cloning computer. +/obj/machinery/computer/cloning/proc/clone_occupant(occupant) + var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) + var/datum/dna/dna + if(ishuman(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + dna = C.has_dna() + if(isbrain(mob_occupant)) + var/mob/living/brain/B = mob_occupant + dna = B.stored_dna + + if(!can_scan(dna, mob_occupant, TRUE)) + return + + var/clone_species + if(dna.species) + clone_species = dna.species + else + var/datum/species/rando_race = pick(GLOB.roundstart_races) + clone_species = rando_race.type + + var/obj/machinery/clonepod/pod = GetAvailablePod() + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!LAZYLEN(pods)) + temp = "No Clonepods detected." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!pod) + temp = "No Clonepods available." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.occupant) + temp = "Cloning cycle already in progress." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else + pod.growclone(null, mob_occupant.real_name, dna.uni_identity, dna.mutation_index, null, dna.blood_type, clone_species, dna.features, mob_occupant.faction) + temp = "[mob_occupant.real_name] => Cloning data sent to pod." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + +/obj/machinery/computer/cloning/proc/can_scan(datum/dna/dna, mob/living/mob_occupant, experimental = FALSE, datum/bank_account/account) + if(!istype(dna)) + scantemp = "Unable to locate valid genetic data." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if(!experimental) + if(mob_occupant.suiciding || mob_occupant.hellbound) + scantemp = "Subject's brain is not responding to scanning stimuli." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if((HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) + scantemp = "Subject no longer contains the fundamental materials required to create a living clone." + playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) + return + if (!experimental) + if(!mob_occupant.ckey || !mob_occupant.client) + scantemp = "Mental interface failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (find_record("ckey", mob_occupant.ckey, records)) + scantemp = "Subject already in database." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if(SSeconomy.full_ancap && !account) + scantemp = "Subject is either missing an ID card with a bank account on it, or does not have an account to begin with. Please ensure the ID card is on the body before attempting to scan." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + return TRUE + +//Prototype cloning console, much more rudimental and lacks modern functions such as saving records, autocloning, or safety checks. +/obj/machinery/computer/cloning/prototype + name = "prototype cloning console" + desc = "Used to operate an experimental cloner." + icon_screen = "dna" + icon_keyboard = "med_key" + circuit = /obj/item/circuitboard/computer/cloning/prototype + clonepod_type = /obj/machinery/clonepod/experimental diff --git a/code/game/machinery/exp_cloner.dm b/code/game/machinery/exp_cloner.dm deleted file mode 100644 index 2c669aac80..0000000000 --- a/code/game/machinery/exp_cloner.dm +++ /dev/null @@ -1,298 +0,0 @@ -//Experimental cloner; clones a body regardless of the owner's status, letting a ghost control it instead -/obj/machinery/clonepod/experimental - name = "experimental cloning pod" - desc = "An ancient cloning pod. It seems to be an early prototype of the experimental cloners used in Nanotrasen Stations." - icon = 'icons/obj/machines/cloning.dmi' - icon_state = "pod_0" - req_access = null - circuit = /obj/item/circuitboard/machine/clonepod/experimental - internal_radio = FALSE - -//Start growing a human clone in the pod! -/obj/machinery/clonepod/experimental/growclone(clonename, ui, mutation_index, mindref, last_death, blood_type, datum/species/mrace, list/features, factions, list/quirks) - if(panel_open) - return FALSE - if(mess || attempting) - return FALSE - - attempting = TRUE //One at a time!! - countdown.start() - - var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) - - H.hardset_dna(ui, mutation_index, H.real_name, blood_type, mrace, features) - - if(efficiency > 2) - var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) - H.dna.remove_mutation_group(unclean_mutations) - if(efficiency > 5 && prob(20)) - H.easy_randmut(POSITIVE) - if(efficiency < 3 && prob(50)) - var/mob/M = H.easy_randmut(NEGATIVE+MINOR_NEGATIVE) - if(ismob(M)) - H = M - - H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment. - occupant = H - - if(!clonename) //to prevent null names - clonename = "clone ([rand(1,999)])" - H.real_name = clonename - - icon_state = "pod_1" - //Get the clone body ready - maim_clone(H) - ADD_TRAIT(H, TRAIT_STABLEHEART, "cloning") - ADD_TRAIT(H, TRAIT_EMOTEMUTE, "cloning") - ADD_TRAIT(H, TRAIT_MUTE, "cloning") - ADD_TRAIT(H, TRAIT_NOBREATH, "cloning") - ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning") - H.Unconscious(80) - - var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H) - if(LAZYLEN(candidates)) - var/mob/C = pick(candidates) - H.key = C.key - - if(grab_ghost_when == CLONER_FRESH_CLONE) - H.grab_ghost() - to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
") - - if(grab_ghost_when == CLONER_MATURE_CLONE) - H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost - to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.") - - if(H) - H.faction |= factions - - H.set_cloned_appearance() - - H.suiciding = FALSE - attempting = FALSE - return TRUE - - -//Prototype cloning console, much more rudimental and lacks modern functions such as saving records, autocloning, or safety checks. -/obj/machinery/computer/prototype_cloning - name = "prototype cloning console" - desc = "Used to operate an experimental cloner." - icon_screen = "dna" - icon_keyboard = "med_key" - circuit = /obj/item/circuitboard/computer/prototype_cloning - var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. - var/list/pods //Linked experimental cloning pods - var/temp = "Inactive" - var/scantemp = "Ready to Scan" - var/loading = FALSE // Nice loading text - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/prototype_cloning/Initialize() - . = ..() - updatemodules(TRUE) - -/obj/machinery/computer/prototype_cloning/Destroy() - if(pods) - for(var/P in pods) - DetachCloner(P) - pods = null - return ..() - -/obj/machinery/computer/prototype_cloning/proc/GetAvailablePod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/experimental/pod = P - if(pod.is_operational() && !(pod.occupant || pod.mess)) - return pod - -/obj/machinery/computer/prototype_cloning/proc/updatemodules(findfirstcloner) - scanner = findscanner() - if(findfirstcloner && !LAZYLEN(pods)) - findcloner() - -/obj/machinery/computer/prototype_cloning/proc/findscanner() - var/obj/machinery/dna_scannernew/scannerf = null - - // Loop through every direction - for(var/direction in GLOB.cardinals) - // Try to find a scanner in that direction - scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, direction)) - // If found and operational, return the scanner - if (!isnull(scannerf) && scannerf.is_operational()) - return scannerf - - // If no scanner was found, it will return null - return null - -/obj/machinery/computer/prototype_cloning/proc/findcloner() - var/obj/machinery/clonepod/experimental/podf = null - for(var/direction in GLOB.cardinals) - podf = locate(/obj/machinery/clonepod/experimental, get_step(src, direction)) - if (!isnull(podf) && podf.is_operational()) - AttachCloner(podf) - -/obj/machinery/computer/prototype_cloning/proc/AttachCloner(obj/machinery/clonepod/experimental/pod) - if(!pod.connected) - pod.connected = src - LAZYADD(pods, pod) - -/obj/machinery/computer/prototype_cloning/proc/DetachCloner(obj/machinery/clonepod/experimental/pod) - pod.connected = null - LAZYREMOVE(pods, pod) - -/obj/machinery/computer/prototype_cloning/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/multitool)) - var/obj/item/multitool/P = W - - if(istype(P.buffer, /obj/machinery/clonepod/experimental)) - if(get_area(P.buffer) != get_area(src)) - to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %-") - P.buffer = null - return - to_chat(user, "-% Successfully linked [P.buffer] with [src] %-") - var/obj/machinery/clonepod/experimental/pod = P.buffer - if(pod.connected) - pod.connected.DetachCloner(pod) - AttachCloner(pod) - else - P.buffer = src - to_chat(user, "-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-") - return - else - return ..() - -/obj/machinery/computer/prototype_cloning/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/prototype_cloning/interact(mob/user) - user.set_machine(src) - add_fingerprint(user) - - if(..()) - return - - updatemodules(TRUE) - - var/dat = "" - dat += "Refresh" - - dat += "

Cloning Pod Status

" - dat += "
[temp] 
" - - if (isnull(src.scanner) || !LAZYLEN(pods)) - dat += "

Modules

" - //dat += "Reload Modules" - if (isnull(src.scanner)) - dat += "ERROR: No Scanner detected!
" - if (!LAZYLEN(pods)) - dat += "ERROR: No Pod detected
" - - // Scan-n-Clone - if (!isnull(src.scanner)) - var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant) - - dat += "

Cloning

" - - dat += "
" - if(!scanner_occupant) - dat += "Scanner Unoccupied" - else if(loading) - dat += "[scanner_occupant] => Scanning..." - else - scantemp = "Ready to Clone" - dat += "[scanner_occupant] => [scantemp]" - dat += "
" - - if(scanner_occupant) - dat += "Clone" - dat += "
[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" - else - dat += "Clone" - - var/datum/browser/popup = new(user, "cloning", "Prototype Cloning System Control") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/computer/prototype_cloning/Topic(href, href_list) - if(..()) - return - - if(loading) - return - - else if ((href_list["clone"]) && !isnull(scanner) && scanner.is_operational()) - scantemp = "" - - loading = TRUE - updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - say("Initiating scan...") - - spawn(20) - clone_occupant(scanner.occupant) - loading = FALSE - updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - //No locking an open scanner. - else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) - if ((!scanner.locked) && (scanner.occupant)) - scanner.locked = TRUE - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else - scanner.locked = FALSE - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if (href_list["refresh"]) - updateUsrDialog() - playsound(src, "terminal_type", 25, 0) - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/prototype_cloning/proc/clone_occupant(occupant) - var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) - var/datum/dna/dna - if(ishuman(mob_occupant)) - var/mob/living/carbon/C = mob_occupant - dna = C.has_dna() - if(isbrain(mob_occupant)) - var/mob/living/brain/B = mob_occupant - dna = B.stored_dna - - if(!istype(dna)) - scantemp = "Unable to locate valid genetic data." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if((HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && (src.scanner.scan_level < 2)) - scantemp = "Subject no longer contains the fundamental materials required to create a living clone." - playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) - return - - var/clone_species - if(dna.species) - clone_species = dna.species - else - var/datum/species/rando_race = pick(GLOB.roundstart_races) - clone_species = rando_race.type - - var/obj/machinery/clonepod/pod = GetAvailablePod() - //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. - if(!LAZYLEN(pods)) - temp = "No Clonepods detected." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!pod) - temp = "No Clonepods available." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.occupant) - temp = "Cloning cycle already in progress." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else - pod.growclone(mob_occupant.real_name, dna.uni_identity, dna.mutation_index, null, null, dna.blood_type, clone_species, dna.features, mob_occupant.faction) - temp = "[mob_occupant.real_name] => Cloning data sent to pod." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm index c56731b3d3..faab0df6e9 100644 --- a/code/game/objects/effects/contraband.dm +++ b/code/game/objects/effects/contraband.dm @@ -212,6 +212,11 @@ desc = "A heretical poster depicting the titular star of an equally heretical book." icon_state = "poster4" +/obj/structure/sign/poster/contraband/post_ratvar + name = "Post This Ratvar" + desc = "Oh what in the hell? Those cultists have animated paper technology and they use it for a meme?" + icon_state = "postvar" + /obj/structure/sign/poster/contraband/syndicate_recruitment name = "Syndicate Recruitment" desc = "See the galaxy! Shatter corrupt megacorporations! Join today!" diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index f94c8f3513..2fa48582f7 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -116,9 +116,9 @@ build_path = /obj/machinery/computer/cloning var/list/records = list() -/obj/item/circuitboard/computer/prototype_cloning +/obj/item/circuitboard/computer/cloning/prototype name = "Prototype Cloning (Computer Board)" - build_path = /obj/machinery/computer/prototype_cloning + build_path = /obj/machinery/computer/cloning/prototype /obj/item/circuitboard/computer/arcade/battle name = "Arcade Battle (Computer Board)" diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index 9d9409acf0..4960474d94 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -22,6 +22,11 @@ var/occupant_weight = 0 var/max_occupants = 3 //Hard-cap so you can't have infinite mice or something in one carrier var/max_occupant_weight = MOB_SIZE_SMALL //This is calculated from the mob sizes of occupants + var/entrance_name = "door" //name of the entrance to the item + var/escape_time = 200 //how long it takes for mobs above small sizes to escape (for small sizes, its randomly 1.5 to 2x this) + var/load_time = 30 //how long it takes for mobs to be loaded into the pet carrier + var/has_lock_sprites = TRUE //whether to load the lock overlays or not + var/allows_hostiles = FALSE //does the pet carrier allow hostile entities to be held within it? /obj/item/pet_carrier/Destroy() if(occupants.len) @@ -51,20 +56,20 @@ else . += "It has nothing inside." if(user.canUseTopic(src)) - . += "Activate it in your hand to [open ? "close" : "open"] its door." + . += "Activate it in your hand to [open ? "close" : "open"] its [entrance_name]." if(!open) - . += "Alt-click to [locked ? "unlock" : "lock"] its door." + . += "Alt-click to [locked ? "unlock" : "lock"] its [entrance_name]." /obj/item/pet_carrier/attack_self(mob/living/user) if(open) - to_chat(user, "You close [src]'s door.") + to_chat(user, "You close [src]'s [entrance_name].") playsound(user, 'sound/effects/bin_close.ogg', 50, TRUE) open = FALSE else if(locked) to_chat(user, "[src] is locked!") return - to_chat(user, "You open [src]'s door.") + to_chat(user, "You open [src]'s [entrance_name].") playsound(user, 'sound/effects/bin_open.ogg', 50, TRUE) open = TRUE update_icon() @@ -86,7 +91,7 @@ if(user.a_intent == INTENT_HARM) return ..() if(!open) - to_chat(user, "You need to open [src]'s door!") + to_chat(user, "You need to open [src]'s [entrance_name]!") return if(target.mob_size > max_occupant_weight) if(ishuman(target)) @@ -94,13 +99,15 @@ if(iscatperson(H)) to_chat(user, "You'd need a lot of catnip and treats, plus maybe a laser pointer, for that to work.") else - to_chat(user, "Humans, generally, do not fit into pet carriers.") + to_chat(user, "Humans, generally, do not fit into [name]s.") else to_chat(user, "You get the feeling [target] isn't meant for a [name].") return if(user == target) to_chat(user, "Why would you ever do that?") return + if(ishostile(target) && !allows_hostiles && target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers + to_chat(user, "You have a feeling you shouldn't keep this as a pet.") load_occupant(user, target) /obj/item/pet_carrier/relaymove(mob/living/user, direction) @@ -110,8 +117,8 @@ remove_occupant(user) return else if(!locked) - loc.visible_message("[user] pushes open the door to [src]!", \ - "[user] pushes open the door of [src]!") + loc.visible_message("[user] pushes open the [entrance_name] to [src]!", \ + "[user] pushes open the [entrance_name] of [src]!") open = TRUE update_icon() return @@ -119,12 +126,19 @@ container_resist(user) /obj/item/pet_carrier/container_resist(mob/living/user) + //don't do the whole resist timer thing if it's open! + if(open) + loc.visible_message("[user] climbs out of [src]!", \ + "[user] jumps out of [src]!") + remove_occupant(user) + return + user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT if(user.mob_size <= MOB_SIZE_SMALL) - to_chat(user, "You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.)") - to_chat(loc, "You see [user] reach through the bars and fumble for the lock switch!") - if(!do_after(user, rand(300, 400), target = user) || open || !locked || !(user in occupants)) + to_chat(user, "You begin to try escaping the [src] and start fumbling for the lock switch... (This will take some time.)") + to_chat(loc, "You see [user] attempting to unlock the [src]!") + if(!do_after(user, rand(escape_time * 1.5, escape_time * 2), target = user) || open || !locked || !(user in occupants)) return loc.visible_message("[user] flips the lock switch on [src] by reaching through!", null, null, null, user) to_chat(user, "Bingo! The lock pops open!") @@ -132,12 +146,12 @@ playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE) update_icon() else - loc.visible_message("[src] starts rattling as something pushes against the door!", null, null, null, user) + loc.visible_message("[src] starts rattling as something pushes against the [entrance_name]!", null, null, null, user) to_chat(user, "You start pushing out of [src]... (This will take about 20 seconds.)") - if(!do_after(user, 200, target = user) || open || !locked || !(user in occupants)) + if(!do_after(user, escape_time, target = user) || open || !locked || !(user in occupants)) return loc.visible_message("[user] shoves out of [src]!", null, null, null, user) - to_chat(user, "You shove open [src]'s door against the lock's resistance and fall out!") + to_chat(user, "You shove open [src]'s [entrance_name] against the lock's resistance and fall out!") locked = FALSE open = TRUE update_icon() @@ -151,7 +165,7 @@ /obj/item/pet_carrier/update_overlays() . = ..() - if(!open) + if(!open && has_lock_sprites) . += "[locked ? "" : "un"]locked" /obj/item/pet_carrier/MouseDrop(atom/over_atom) @@ -170,7 +184,7 @@ user.visible_message("[user] starts loading [target] into [src].", \ "You start loading [target] into [src]...", null, null, target) to_chat(target, "[user] starts loading you into [user.p_their()] [name]!") - if(!do_mob(user, target, 30)) + if(!do_mob(user, target, load_time)) return if(target in occupants) return @@ -192,9 +206,74 @@ /obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf) if(!(occupant in occupants) || !istype(occupant)) return - occupant.forceMove(new_turf ? new_turf : drop_location()) + occupant.forceMove(new_turf ? new_turf : get_turf(src)) occupants -= occupant occupant_weight -= occupant.mob_size occupant.setDir(SOUTH) +//bluespace jar, a reskin of the pet carrier that can fit people and smashes when thrown +/obj/item/pet_carrier/bluespace + name = "bluespace jar" + desc = "A jar, that seems to be bigger on the inside, somehow allowing lifeforms to fit through its narrow entrance." + open = FALSE //starts closed so it looks better on menus + icon_state = "bluespace_jar" + item_state = "bluespace_jar" + lefthand_file = "" + righthand_file = "" + max_occupant_weight = MOB_SIZE_HUMAN //can fit people, like a bluespace bodybag! + load_time = 40 //loading things into a jar takes longer than a regular pet carrier + entrance_name = "lid" + w_class = WEIGHT_CLASS_SMALL //it's a jar + throw_speed = 3 + throw_range = 7 + max_occupants = 1 //far less than a regular carrier or bluespace bodybag, because it can be thrown to release the contents + allows_hostiles = TRUE //can fit hostile creatures, with the move resist restrictions in place, this means they still cannot take things like legions/goliaths/etc regardless + has_lock_sprites = FALSE //jar doesn't show the regular lock overlay + custom_materials = list(/datum/material/glass = 1000, /datum/material/bluespace = 600) + escape_time = 10 //half the time of a bluespace bodybag + var/datum/gas_mixture/occupant_gas_supply + +/obj/item/pet_carrier/bluespace/update_icon_state() + if(open) + icon_state = "bluespace_jar_open" + else + icon_state = "bluespace_jar" + +/obj/item/pet_carrier/bluespace/throw_impact() + . = ..() + //delete the item upon impact, releasing the creature inside (this is handled by its deletion) + if(occupants.len) + loc.visible_message("The bluespace jar smashes, releasing [occupants[1]]!") + playsound(src, "shatter", 70, 1) + qdel(src) + +/obj/item/pet_carrier/bluespace/add_occupant(mob/living/occupant) //update the gas supply as required, this acts like magical internals + . = ..() + if(!occupant_gas_supply) + occupant_gas_supply = new + if(isanimal(occupant)) + var/mob/living/simple_animal/animal = occupant + occupant_gas_supply.temperature = animal.minbodytemp //simple animals only care about temperature when their turf isnt a location + else + if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside + ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist") + ADD_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist") + ADD_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath") + ADD_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure") + ADD_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure") + +/obj/item/pet_carrier/bluespace/remove_occupant(mob/living/occupant) + . = ..() + if(ishuman(occupant)) + REMOVE_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist") + REMOVE_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist") + REMOVE_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath") + REMOVE_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure") + REMOVE_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure") + +/obj/item/pet_carrier/bluespace/return_air() + if(!occupant_gas_supply) + occupant_gas_supply = new + return occupant_gas_supply + #undef pet_carrier_full diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index aac642a05e..2831311eff 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -326,6 +326,7 @@ w_class = WEIGHT_CLASS_BULKY flags_1 = CONDUCT_1 custom_materials = list(/datum/material/iron=3000) + var/max_items = 7 /obj/item/storage/bag/tray/ComponentInitialize() . = ..() @@ -333,6 +334,7 @@ STR.max_w_class = WEIGHT_CLASS_NORMAL STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food, /obj/item/reagent_containers/glass, /datum/reagent/consumable, /obj/item/kitchen/knife, /obj/item/kitchen/rollingpin, /obj/item/kitchen/fork, /obj/item/storage/box)) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Kitchen Tools, and ingredient boxes. STR.insert_preposition = "on" + STR.max_items = max_items /obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user) . = ..() @@ -373,6 +375,14 @@ . = ..() update_icon() +//bluespace tray, holds more items +/obj/item/storage/bag/tray/bluespace + name = "bluespace tray" + icon_state = "bluespace_tray" + desc = "A tray created using bluespace technology to fit more food on it." + max_items = 30 // far more items + custom_materials = list(/datum/material/iron = 2000, /datum/material/bluespace = 500) + /* * Chemistry bag */ @@ -462,4 +472,4 @@ STR.max_combined_w_class = INFINITY STR.max_items = 2 STR.display_numerical_stacking = TRUE - STR.can_hold = typecacheof(list(/obj/item/rcd_ammo, /obj/item/stack/sheet)) \ No newline at end of file + STR.can_hold = typecacheof(list(/obj/item/rcd_ammo, /obj/item/stack/sheet)) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index f4f9bbbcfb..3d969e1a77 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -268,6 +268,7 @@ obj/machinery/portable_atmospherics/canister/welder_act(mob/living/user, obj/ite /obj/machinery/portable_atmospherics/canister/obj_break(damage_flag) if((stat & BROKEN) || (flags_1 & NODECONSTRUCT_1)) return + stat |= BROKEN canister_break() /obj/machinery/portable_atmospherics/canister/proc/canister_break() diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index 60f8cc179a..632d59187f 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -76,6 +76,7 @@ /obj/item/clothing/head/hooded var/obj/item/clothing/suit/hooded/suit + dynamic_hair_suffix = "" /obj/item/clothing/head/hooded/Destroy() suit = null diff --git a/code/modules/hydroponics/grown/peas.dm b/code/modules/hydroponics/grown/peas.dm index 6229d98b2c..79d506cf56 100644 --- a/code/modules/hydroponics/grown/peas.dm +++ b/code/modules/hydroponics/grown/peas.dm @@ -61,6 +61,7 @@ filling_color = "#ee7bee" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list (/datum/reagent/consumable/laughsyrup = 0) tastes = list ("a prancing rabbit" = 1) //Vib Ribbon sends her regards.. wherever she is. wine_power = 90 wine_flavor = "a vector-graphic rabbit dancing on your tongue" diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index ce4436a343..31f326fd53 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -23,6 +23,13 @@ heatmod = 0.5 // = 1/4x heat damage burnmod = 0.5 // = 1/2x generic burn damage species_language_holder = /datum/language_holder/jelly + mutant_brain = /obj/item/organ/brain/jelly + +/obj/item/organ/brain/jelly + name = "slime nucleus" + desc = "A slimey membranous mass from a slime person" + icon_state = "brain-slime" + /datum/species/jelly/on_species_loss(mob/living/carbon/C) if(regenerate_limbs) diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm index 0d11b8e887..336dc4ec8e 100644 --- a/code/modules/research/designs/bluespace_designs.dm +++ b/code/modules/research/designs/bluespace_designs.dm @@ -95,3 +95,23 @@ build_path = /obj/item/storage/bag/ore/holding category = list("Bluespace Designs") departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/bluespace_tray + name = "Bluespace Tray" + desc = "A tray created using bluespace technology to fit more food on it." + id = "bluespace_tray" + build_type = PROTOLATHE + build_path = /obj/item/storage/bag/tray/bluespace + materials = list(/datum/material/iron = 2000, /datum/material/bluespace = 500) + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/bluespace_carrier + name = "Bluespace Jar" + desc = "A jar used to contain creatures, using the power of bluespace." + id = "bluespace_carrier" + build_type = PROTOLATHE + build_path = /obj/item/pet_carrier/bluespace + materials = list(/datum/material/glass = 1000, /datum/material/bluespace = 600) + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE \ No newline at end of file diff --git a/code/modules/research/techweb/nodes/bluespace_nodes.dm b/code/modules/research/techweb/nodes/bluespace_nodes.dm index 3aacc9fec5..b0705a0b76 100644 --- a/code/modules/research/techweb/nodes/bluespace_nodes.dm +++ b/code/modules/research/techweb/nodes/bluespace_nodes.dm @@ -13,7 +13,7 @@ display_name = "Applied Bluespace Research" description = "Using bluespace to make things faster and better." prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic") + design_ids = list("bs_rped","biobag_holding","minerbag_holding", "bluespacebeaker", "bluespacesyringe", "phasic_scanning", "bluespacesmartdart", "xenobio_slimebasic", "bluespace_tray", "bluespace_carrier") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) /datum/techweb_node/adv_bluespace diff --git a/html/changelog.html b/html/changelog.html index f12ab97b29..1d6318811e 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -50,6 +50,36 @@ -->
+

09 July 2020

+

timothyteakettle updated:

+ + +

08 July 2020

+

DeltaFire15 updated:

+ +

EmeraldSundisk updated:

+ +

Owai-Seek updated:

+ +

07 July 2020

KasparoVy updated: