Removes cloning once and for all (#3808)

* goodbye hard work

* aaa

* Update station_ship.dmm

* Update whiteshipruin_box_skyrat.dmm

* a
This commit is contained in:
Gandalf
2021-03-04 15:09:48 +00:00
committed by GitHub
parent 4fdfacc73f
commit f23a1582e1
44 changed files with 121 additions and 1963 deletions
@@ -453,7 +453,6 @@
/obj/structure/closet/crate,
/obj/item/book/manual/wiki/chemistry,
/obj/item/book/manual/wiki/infections,
/obj/item/book/manual/wiki/medical_cloning,
/turf/open/floor/mineral/titanium/white,
/area/ruin/space/has_grav/whiteship/box)
"Vt" = (
@@ -77664,7 +77664,7 @@
dir = 4
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"dme" = (
/obj/machinery/door/firedoor,
/obj/structure/disposalpipe/segment,
@@ -78276,34 +78276,32 @@
/turf/open/floor/iron,
/area/medical/medbay/central)
"dnC" = (
/obj/machinery/clonepod,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"dnD" = (
/obj/structure/cable,
/obj/item/radio/intercom{
pixel_y = 26
},
/obj/machinery/computer/cloning,
/obj/machinery/light{
dir = 1
},
/obj/item/instrument/musicalmoth,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"dnE" = (
/obj/machinery/power/apc/auto_name/north,
/obj/structure/cable,
/obj/machinery/dna_scannernew,
/obj/machinery/airalarm{
pixel_x = 32;
pixel_y = 23
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"dnF" = (
/obj/structure/sign/departments/medbay/alt,
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"dnG" = (
/obj/machinery/newscaster{
pixel_x = -32
@@ -79113,10 +79111,10 @@
},
/obj/effect/turf_decal/trimline/blue/filled/warning,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dpC" = (
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"dpD" = (
/obj/effect/turf_decal/tile/neutral{
dir = 4
@@ -79769,7 +79767,7 @@
/obj/structure/cable,
/obj/machinery/holopad,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"dro" = (
/obj/structure/chair/stool,
/obj/machinery/light{
@@ -80356,14 +80354,14 @@
"dsI" = (
/obj/structure/sign/warning/nosmoking,
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"dsJ" = (
/obj/machinery/iv_drip,
/obj/effect/turf_decal/tile/blue{
dir = 1
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dsK" = (
/obj/effect/turf_decal/tile/blue{
dir = 1
@@ -80377,7 +80375,7 @@
/obj/effect/turf_decal/tile/blue,
/obj/structure/cable,
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dsL" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -80389,7 +80387,7 @@
/obj/structure/bed,
/obj/item/bedsheet/medical,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dsN" = (
/obj/structure/table/wood,
/obj/item/folder/white,
@@ -80766,7 +80764,7 @@
pixel_y = 26
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dtO" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -80781,7 +80779,7 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/obj/structure/cable,
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dtP" = (
/obj/structure/bed,
/obj/item/bedsheet/medical,
@@ -80795,7 +80793,7 @@
dir = 4
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dtQ" = (
/obj/structure/table/wood,
/obj/structure/sign/poster/official/help_others{
@@ -81414,15 +81412,15 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2{
dir = 8
},
/obj/machinery/door/airlock/medical/glass{
name = "Cloning Laboratory";
req_access_txt = "5"
},
/obj/effect/mapping_helpers/airlock/unres{
dir = 4
},
/obj/machinery/door/airlock/medical{
name = "Surgery B Access";
req_access_txt = "45"
},
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dvA" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/blue{
@@ -81438,7 +81436,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dvB" = (
/obj/effect/landmark/start/medical_doctor,
/obj/structure/cable,
@@ -81457,7 +81455,7 @@
},
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dvC" = (
/obj/structure/cable,
/obj/effect/turf_decal/tile/blue,
@@ -81471,7 +81469,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dvD" = (
/obj/machinery/door/firedoor,
/obj/structure/cable,
@@ -81492,7 +81490,7 @@
req_access_txt = "5"
},
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dvE" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -82136,7 +82134,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dxj" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -82152,7 +82150,7 @@
dir = 1
},
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dxk" = (
/obj/machinery/light{
dir = 4
@@ -82165,7 +82163,7 @@
pixel_x = 24
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dxl" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{
dir = 8
@@ -82577,7 +82575,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dyE" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/medical{
@@ -82589,7 +82587,7 @@
dir = 1
},
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"dyF" = (
/obj/structure/table,
/obj/item/clothing/suit/straight_jacket,
@@ -82603,7 +82601,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"dyG" = (
/obj/structure/toilet{
dir = 4
@@ -101419,7 +101417,7 @@
},
/obj/effect/turf_decal/trimline/blue/filled/warning,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"iQh" = (
/obj/structure/bodycontainer/morgue{
dir = 1
@@ -102276,7 +102274,7 @@
dir = 4
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"jQl" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -105584,7 +105582,7 @@
name = "privacy shutters"
},
/turf/open/floor/plating,
/area/medical/genetics/cloning)
/area/medical)
"oyo" = (
/obj/structure/cable,
/obj/effect/turf_decal/stripes/line{
@@ -107907,7 +107905,7 @@
dir = 8
},
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"rFt" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -11712,7 +11712,7 @@
name = "privacy shutters"
},
/turf/open/floor/plating,
/area/medical/genetics/cloning)
/area/medical)
"aPf" = (
/obj/machinery/computer/libraryconsole,
/obj/structure/table/wood,
@@ -21839,9 +21839,8 @@
},
/obj/machinery/power/apc/auto_name/east,
/obj/structure/cable,
/obj/machinery/dna_scannernew,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"brc" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
@@ -21866,11 +21865,11 @@
dir = 4
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"brh" = (
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"bri" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -21881,7 +21880,7 @@
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"brk" = (
/obj/machinery/light{
dir = 1
@@ -21993,7 +21992,7 @@
dir = 4
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"brx" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -22047,7 +22046,7 @@
dir = 6
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"brB" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -22075,7 +22074,7 @@
req_one_access_txt = "68;5"
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"brC" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -43557,9 +43556,8 @@
/turf/open/floor/iron/dark,
/area/commons/storage/mining)
"hcB" = (
/obj/machinery/clonepod,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"hdx" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4,
@@ -48576,15 +48574,15 @@
dir = 1
},
/obj/machinery/door/firedoor,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4,
/obj/machinery/door/airlock/medical{
name = "Surgery B";
req_access_txt = "5"
},
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2,
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4,
/turf/open/floor/iron,
/area/medical/genetics/cloning)
/area/medical)
"mIJ" = (
/obj/machinery/computer/secure_data,
/turf/open/floor/iron/dark,
@@ -54719,7 +54717,7 @@
/area/security/prison)
"tnw" = (
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"tqd" = (
/obj/machinery/light/small{
dir = 1
@@ -55599,7 +55597,6 @@
/turf/open/floor/iron,
/area/science/misc_lab)
"ulw" = (
/obj/structure/bookcase/manuals/medical,
/turf/open/floor/wood,
/area/security/prison)
"ulQ" = (
@@ -57703,10 +57700,10 @@
/obj/machinery/newscaster{
pixel_y = 32
},
/obj/machinery/computer/cloning,
/obj/structure/cable,
/obj/item/toy/plush/moth,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"wFd" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -14569,7 +14569,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aAa" = (
/obj/machinery/vending/engivend,
/obj/effect/turf_decal/tile/neutral{
@@ -15048,7 +15048,7 @@
dir = 9
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aAL" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -15093,7 +15093,7 @@
},
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aAP" = (
/obj/effect/turf_decal/stripes/corner{
dir = 4
@@ -15512,7 +15512,7 @@
},
/obj/structure/closet/wardrobe/pjs,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aBB" = (
/obj/structure/flora/grass/jungle,
/obj/structure/beebox,
@@ -16174,7 +16174,7 @@
req_access_txt = "5"
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aCJ" = (
/obj/effect/turf_decal/stripes/line,
/obj/effect/decal/cleanable/blood/old,
@@ -17559,7 +17559,7 @@
dir = 8
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aFu" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/medical/glass{
@@ -17590,7 +17590,7 @@
dir = 9
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aFz" = (
/obj/effect/turf_decal/tile/yellow{
dir = 4
@@ -20182,7 +20182,7 @@
dir = 1
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aJV" = (
/obj/effect/turf_decal/tile/purple{
dir = 4
@@ -21861,7 +21861,7 @@
},
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aMF" = (
/obj/machinery/button/ignition{
id = "Incinerator";
@@ -22417,7 +22417,7 @@
/obj/effect/turf_decal/bot,
/obj/structure/closet/wardrobe/pjs,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aNw" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -22535,7 +22535,7 @@
pixel_y = 32
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aNK" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -23090,7 +23090,7 @@
dir = 6
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aOC" = (
/obj/structure/flora/grass/jungle,
/obj/structure/flora/ausbushes/lavendergrass,
@@ -23141,7 +23141,7 @@
},
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden/layer2,
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aOH" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -23161,7 +23161,7 @@
},
/obj/effect/turf_decal/box,
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aOI" = (
/obj/effect/turf_decal/tile/blue{
dir = 4
@@ -23174,7 +23174,7 @@
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2,
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aOJ" = (
/obj/effect/turf_decal/tile/purple,
/obj/effect/turf_decal/tile/purple{
@@ -23205,7 +23205,7 @@
dir = 1
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aOM" = (
/obj/effect/turf_decal/tile/neutral{
dir = 4
@@ -23502,7 +23502,7 @@
dir = 6
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aPe" = (
/obj/effect/turf_decal/tile/blue{
dir = 8
@@ -23622,7 +23622,7 @@
dir = 8
},
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aPo" = (
/obj/effect/turf_decal/tile/neutral{
dir = 4
@@ -23672,7 +23672,7 @@
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aPs" = (
/obj/structure/table,
/obj/effect/turf_decal/tile/neutral,
@@ -23890,7 +23890,7 @@
},
/obj/structure/disposalpipe/segment,
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aPH" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -24008,7 +24008,7 @@
/obj/effect/turf_decal/tile/blue,
/obj/effect/turf_decal/delivery,
/turf/open/floor/iron/showroomfloor,
/area/medical/genetics/cloning)
/area/medical)
"aPP" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -24160,7 +24160,7 @@
req_access_txt = "50"
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aPY" = (
/obj/effect/turf_decal/tile/neutral{
dir = 1
@@ -27984,7 +27984,7 @@
},
/obj/structure/closet/secure_closet/personal/patient,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aVL" = (
/obj/effect/turf_decal/tile/red,
/obj/effect/turf_decal/tile/red{
@@ -28114,11 +28114,11 @@
dir = 8
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aVU" = (
/obj/structure/sign/departments/medbay/alt,
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"aVV" = (
/obj/effect/turf_decal/tile/red,
/obj/effect/turf_decal/tile/red{
@@ -28404,7 +28404,7 @@
/obj/machinery/vending/clothing,
/obj/effect/turf_decal/bot,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aWp" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/medical/glass{
@@ -84380,7 +84380,7 @@
/area/maintenance/port/aft)
"hVJ" = (
/turf/closed/wall/rust,
/area/medical/genetics/cloning)
/area/medical)
"hVK" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4{
dir = 4
@@ -84635,7 +84635,7 @@
"ixx" = (
/obj/machinery/status_display/evac,
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"ixL" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -85492,7 +85492,7 @@
"lfp" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/medical/genetics/cloning)
/area/medical)
"ljv" = (
/obj/effect/turf_decal/tile/neutral,
/obj/effect/turf_decal/tile/neutral{
@@ -85540,7 +85540,7 @@
/area/security/prison)
"lrG" = (
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"lsk" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable,
@@ -87254,7 +87254,7 @@
/area/command/heads_quarters/hop)
"qrk" = (
/turf/closed/wall/r_wall,
/area/medical/genetics/cloning)
/area/medical)
"qss" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2{
dir = 8
@@ -1235,7 +1235,7 @@
/area/security/warden)
"aec" = (
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"aee" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
@@ -12555,7 +12555,7 @@
dir = 4
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"bfV" = (
/obj/machinery/power/tracker,
/obj/structure/cable,
@@ -23343,7 +23343,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"cnm" = (
/obj/structure/table/glass,
/obj/machinery/door/window/eastleft{
@@ -26205,7 +26205,7 @@
/obj/structure/table/glass,
/obj/machinery/computer/med_data/laptop,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"cFS" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -32277,8 +32277,6 @@
},
/obj/effect/spawner/lootdrop/techstorage/medical,
/obj/item/circuitboard/machine/dnascanner,
/obj/item/circuitboard/computer/cloning,
/obj/item/circuitboard/machine/clonepod,
/turf/open/floor/iron/dark,
/area/engineering/storage/tech)
"eaa" = (
@@ -35133,10 +35131,6 @@
dir = 8
},
/obj/effect/turf_decal/tile/blue,
/obj/machinery/door/airlock/medical/glass{
name = "Cloning Laboratory";
req_access_txt = "5"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4{
dir = 4
},
@@ -35147,8 +35141,12 @@
/obj/effect/mapping_helpers/airlock/unres{
dir = 8
},
/obj/machinery/door/airlock/medical/glass{
name = "Primary Treatment Centre";
req_access_txt = "5"
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"ffm" = (
/obj/effect/turf_decal/delivery,
/obj/machinery/door/window/southleft{
@@ -35191,7 +35189,7 @@
name = "privacy shutters"
},
/turf/open/floor/plating,
/area/medical/genetics/cloning)
/area/medical)
"fgi" = (
/obj/structure/tank_dispenser,
/obj/machinery/light{
@@ -35756,7 +35754,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"fqD" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer4{
dir = 4
@@ -36501,7 +36499,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"fFJ" = (
/obj/structure/cable,
/obj/structure/disposalpipe/segment,
@@ -37579,7 +37577,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"gck" = (
/obj/structure/table/wood,
/obj/item/pen/red,
@@ -38074,14 +38072,13 @@
/turf/open/floor/iron,
/area/engineering/atmos)
"glT" = (
/obj/machinery/clonepod,
/obj/machinery/vending/wallmed{
name = "Emergency NanoMed";
pixel_x = -26;
use_power = 0
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"gma" = (
/obj/item/clothing/head/cone{
pixel_x = -4;
@@ -41392,7 +41389,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"hAR" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/command/glass{
@@ -46274,7 +46271,7 @@
pixel_y = -18
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"jDh" = (
/turf/open/floor/plating/airless,
/area/solars/starboard/aft)
@@ -47441,7 +47438,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"kaj" = (
/obj/structure/sign/warning/biohazard,
/turf/closed/wall,
@@ -47868,7 +47865,7 @@
pixel_x = -15
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"klF" = (
/obj/effect/turf_decal/tile/neutral{
dir = 8
@@ -49996,7 +49993,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"lbQ" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/landmark/event_spawn,
@@ -50368,7 +50365,7 @@
},
/obj/machinery/light,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"ljN" = (
/obj/structure/closet/crate,
/obj/structure/cable,
@@ -52051,7 +52048,7 @@
/obj/item/pen,
/obj/structure/table/glass,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"lTD" = (
/obj/effect/turf_decal/tile/purple{
dir = 8
@@ -56935,7 +56932,7 @@
dir = 1
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"nOE" = (
/obj/machinery/meter,
/obj/machinery/atmospherics/pipe/manifold/cyan/visible{
@@ -57240,7 +57237,7 @@
/obj/item/clothing/under/misc/pj/blue,
/obj/item/clothing/under/costume/maid,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"nUi" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{
dir = 4
@@ -61810,7 +61807,7 @@
dir = 1
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"pES" = (
/obj/structure/chair,
/obj/effect/turf_decal/trimline/darkblue/filled/warning,
@@ -62205,12 +62202,11 @@
/turf/open/floor/grass,
/area/service/hydroponics/garden)
"pPi" = (
/obj/machinery/dna_scannernew,
/obj/machinery/status_display/evac{
pixel_y = 32
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"pPt" = (
/obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxin_input{
dir = 8
@@ -62429,12 +62425,12 @@
/turf/open/floor/iron/white,
/area/science/lab)
"pVq" = (
/obj/machinery/computer/cloning,
/obj/machinery/light{
dir = 1
},
/obj/item/toy/plush/moth,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"pVy" = (
/obj/structure/window/reinforced{
dir = 4
@@ -63754,7 +63750,7 @@
dir = 8
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"quS" = (
/obj/machinery/door/morgue{
name = "Confession Booth"
@@ -68168,7 +68164,7 @@
/area/engineering/gravity_generator)
"seP" = (
/turf/closed/wall,
/area/medical/genetics/cloning)
/area/medical)
"seS" = (
/obj/structure/lattice,
/obj/item/broken_bottle,
@@ -72198,7 +72194,7 @@
pixel_y = -26
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"tNj" = (
/obj/structure/lattice/catwalk,
/obj/structure/transit_tube/horizontal,
@@ -74903,7 +74899,7 @@
pixel_x = -23
},
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"uSK" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer2{
dir = 10
@@ -78352,7 +78348,7 @@
},
/obj/structure/cable,
/turf/open/floor/iron/dark,
/area/medical/genetics/cloning)
/area/medical)
"whm" = (
/obj/machinery/door/firedoor,
/obj/machinery/door/airlock/public/glass{
@@ -80286,7 +80282,7 @@
pixel_y = 28
},
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"wWE" = (
/obj/machinery/smartfridge,
/turf/closed/wall,
@@ -81655,7 +81651,7 @@
/obj/item/roller,
/obj/item/roller,
/turf/open/floor/iron/white,
/area/medical/genetics/cloning)
/area/medical)
"xzi" = (
/obj/structure/cable,
/obj/machinery/computer/shuttle/mining/common,
+3 -18
View File
@@ -8567,12 +8567,6 @@
"xA" = (
/turf/closed/indestructible/wood,
/area/centcom/holding/cafedorms)
"xB" = (
/obj/machinery/computer/cloning{
dir = 1
},
/turf/open/floor/iron/dark,
/area/cruiser_dock/medical)
"xC" = (
/obj/structure/table/wood,
/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{
@@ -12546,10 +12540,6 @@
},
/turf/open/floor/plating/grass/planet,
/area/centcom/holding/cafepark)
"IW" = (
/obj/structure/bookcase/manuals/medical,
/turf/open/indestructible/hotelwood,
/area/centcom/holding/cafepark)
"IX" = (
/obj/structure/table/reinforced,
/obj/effect/turf_decal/trimline/red/filled/line{
@@ -14417,10 +14407,6 @@
/obj/machinery/computer/arcade/orion_trail,
/turf/open/indestructible/hotelwood,
/area/centcom/holding/cafe)
"Ox" = (
/obj/structure/bookcase/manuals/medical,
/turf/open/floor/wood,
/area/cruiser_dock/brig)
"Oy" = (
/obj/structure/table/wood,
/obj/item/storage/photo_album/syndicate,
@@ -17542,7 +17528,6 @@
/turf/open/floor/carpet/royalblack,
/area/cruiser_dock/commons)
"Xi" = (
/obj/machinery/clonepod,
/obj/effect/turf_decal/bot_white,
/turf/open/floor/iron/dark,
/area/cruiser_dock/medical)
@@ -30974,7 +30959,7 @@ Fo
af
Mm
dt
Ox
dt
tP
af
mt
@@ -38480,7 +38465,7 @@ XP
XP
jc
kT
xB
tL
xm
QG
YN
@@ -57065,7 +57050,7 @@ jj
Fy
ZF
HK
IW
iA
iA
qO
Fy
+1 -9
View File
@@ -654,13 +654,6 @@
},
/turf/open/floor/iron/dark,
/area/shuttle/shipstation)
"dN" = (
/obj/machinery/computer/cloning,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 1
},
/turf/open/floor/iron/dark,
/area/shuttle/shipstation)
"dO" = (
/obj/machinery/computer/cryopod{
dir = 1;
@@ -673,7 +666,6 @@
/obj/machinery/light{
dir = 4
},
/obj/machinery/clonepod,
/obj/effect/turf_decal/trimline/blue/filled/line{
dir = 5
},
@@ -4883,7 +4875,7 @@ ZH
"}
(23,1,1) = {"
ed
dN
Nq
CZ
CV
mc
-3
View File
@@ -43,9 +43,6 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list(
POLL_IGNORE_SPLITPERSONALITY = "Split Personality",
POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit",
POLL_IGNORE_ACADEMY_WIZARD = "Academy Wizard Defender",
//SKYRAT EDIT BEGIN ADDITION - CLONING
POLL_IGNORE_DEFECTIVECLONE = "Defective clone"
//SKYRAT EDIT END
))
GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore())
+1 -8
View File
@@ -15,9 +15,6 @@
var/default_mutation_genes[DNA_MUTATION_BLOCKS] //List of the default genes from this mutation to allow DNA Scanner highlighting
var/stability = 100
var/scrambled = FALSE //Did we take something like mutagen? In that case we cant get our genes scanned to instantly cheese all the powers.
//SKYRAT EDIT BEGIN - ADDITION - CLONING
var/delete_species = TRUE
//SKYRAT EDIT END
/datum/dna/New(mob/living/new_holder)
if(istype(new_holder))
@@ -30,11 +27,7 @@
cholder.dna = null
holder = null
//SKYRAT EDIT BEGIN - CHANGE - CLONING
//QDEL_NULL(species) - SKYRAT ORIGINAL
if(delete_species)
QDEL_NULL(species)
//SKYRAT EDIT END
QDEL_NULL(species)
mutations.Cut() //This only references mutations, just dereference.
temporary_mutations.Cut() //^
@@ -313,11 +313,6 @@
if(prob(50))
new /obj/effect/temp_visual/revenant(thing.loc)
thing.emag_act(null)
//SKYRAT EDIT ADDITION BEGIN - CLONING
else
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
thing.emp_act(EMP_HEAVY)
//SKYRAT EDIT END
for(var/mob/living/silicon/robot/S in T) //Only works on cyborgs, not AI
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, TRUE)
@@ -327,9 +327,6 @@
if(paranoia)
QDEL_NULL(paranoia)
paranoia = new()
//SKYRAT EDIT ADDITION BEGIN - CLONING
paranoia.clonable = FALSE
//SKYRAT EDIT END
user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC)
to_chat(user, "<span class='warning'>As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. </span>")
@@ -121,7 +121,6 @@ GLOBAL_LIST_INIT(trash_loot, list(//junk: useless, very easy to get, or ghetto c
/obj/item/clothing/mask/luchador/tecnicos = 25,
/obj/item/clothing/mask/surgical = 75,
/obj/item/cultivator/rake = 25,
/obj/item/disk/data/cloning = 25,
/obj/item/extinguisher = 100,
/obj/item/extinguisher/mini = 200,
/obj/item/flashlight/flare = 200,
@@ -1,2 +0,0 @@
#define CLONER_FRESH_CLONE "fresh"
#define CLONER_MATURE_CLONE "mature"
@@ -1,2 +0,0 @@
/// Cloning room and clone pod ejection
#define ACCESS_CLONING 68
@@ -1,3 +0,0 @@
//cloning defines. These are flags.
#define CLONING_SUCCESS (1<<0)
#define CLONING_DELETE_RECORD (1<<1)
@@ -1,2 +0,0 @@
//Cloning defines
#define POLL_IGNORE_DEFECTIVECLONE "defective_clone"
@@ -1,6 +0,0 @@
/datum/brain_trauma
var/clonable = TRUE // will this transfer if the brain is cloned?
/datum/brain_trauma/proc/on_clone()
if(clonable)
return new type
@@ -1,3 +0,0 @@
/datum/brain_trauma/mild/phobia/on_clone()
if(clonable)
return new type(phobia_type)
@@ -1,5 +0,0 @@
/datum/brain_trauma/special/psychotic_brawling/bath_salts
clonable = FALSE
/datum/brain_trauma/special/beepsky
clonable = FALSE
@@ -1,3 +0,0 @@
/datum/mood_event/cloned_corpse
description = "<span class='boldwarning'>I recently saw my own corpse...</span>\n"
mood_change = -6
@@ -1,5 +0,0 @@
/datum/map_template/ruin/space/cloning_facility
id = "cloning_facility"
suffix = "cloning_facility.dmm"
name = "Ancient Cloning Lab"
description = "An experimental cloning lab snapped off from an ancient ship. The cloner model inside lacks many modern functionalities and security measures."
@@ -1,2 +0,0 @@
/datum/quirk/proc/clone_data() //return additional data that should be remembered by cloning
/datum/quirk/proc/on_clone(data) //create the quirk from clone data
@@ -1,5 +0,0 @@
/datum/quirk/family_heirloom/clone_data()
return heirloom
/datum/quirk/family_heirloom/on_clone(data)
heirloom = data
@@ -1,3 +0,0 @@
/area/medical/genetics/cloning
name = "Cloning Lab"
icon_state = "cloning"
@@ -1,617 +0,0 @@
//Cloning revival method.
//The pod handles the actual cloning while the computer manages the clone profiles
//Potential replacement for genetics revives or something I dunno (?)
#define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical
#define MINIMUM_HEAL_LEVEL 40
#define SPEAK(message) radio.talk_into(src, message, radio_channel)
/obj/machinery/clonepod
name = "cloning pod"
desc = "An electronically-lockable pod for growing organic tissue."
density = TRUE
icon = 'modular_skyrat/modules/cloning/icons/obj/machines/cloning_pod.dmi'
icon_state = "pod_0"
req_access = list(ACCESS_CLONING) //FOR PREMATURE UNLOCKING.
verb_say = "states"
circuit = /obj/item/circuitboard/machine/clonepod
var/heal_level //The clone is released once its health reaches this level.
var/obj/machinery/computer/cloning/connected //So we remember the connected clone machine.
var/mess = FALSE //Need to clean out it if it's full of exploded clone.
var/attempting = FALSE //One clone attempt at a time thanks
var/speed_coeff
var/efficiency
var/datum/mind/clonemind
var/grab_ghost_when = CLONER_MATURE_CLONE
var/internal_radio = TRUE
var/obj/item/radio/radio
var/radio_key = /obj/item/encryptionkey/headset_med
var/radio_channel = RADIO_CHANNEL_MEDICAL
var/obj/effect/countdown/clonepod/countdown
var/list/unattached_flesh
var/flesh_number = 0
var/datum/bank_account/current_insurance
fair_market_price = 5 // He nodded, because he knew I was right. Then he swiped his credit card to pay me for arresting him.
payment_department = ACCOUNT_MED
/obj/machinery/clonepod/Initialize()
. = ..()
countdown = new(src)
if(internal_radio)
radio = new(src)
radio.keyslot = new radio_key
radio.subspace_transmission = TRUE
radio.canhear_range = 0
radio.recalculateChannels()
update_icon()
/obj/machinery/clonepod/Destroy()
var/mob/living/mob_occupant = occupant
go_out()
if(mob_occupant)
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to Destroy().")
QDEL_NULL(radio)
QDEL_NULL(countdown)
if(connected)
connected.DetachCloner(src)
QDEL_LIST(unattached_flesh)
. = ..()
/obj/machinery/clonepod/RefreshParts()
speed_coeff = 0
efficiency = 0
for(var/obj/item/stock_parts/scanning_module/S in component_parts)
efficiency += S.rating
for(var/obj/item/stock_parts/manipulator/P in component_parts)
speed_coeff += P.rating
heal_level = (efficiency * 15) + 10
if(heal_level < MINIMUM_HEAL_LEVEL)
heal_level = MINIMUM_HEAL_LEVEL
if(heal_level > 100)
heal_level = 100
/obj/machinery/clonepod/attack_hand(mob/user)
. = ..()
if(.)
return
user.examinate(src)
/obj/machinery/clonepod/attack_ai(mob/user)
return attack_hand(user)
/obj/machinery/clonepod/examine(mob/user)
. = ..()
. += "<span class='notice'>The <i>linking</i> device can be <i>scanned<i> with a multitool.</span>"
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Cloning speed at <b>[speed_coeff*50]%</b>.<br>Predicted amount of cellular damage: <b>[100-heal_level]%</b>.</span>"
if(efficiency > 5)
. += "<span class='notice'>Pod has been upgraded to support autoprocessing and apply beneficial mutations.</span>"
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
/obj/item/disk/data/cloning
name = "cloning data disk"
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
var/list/fields = list()
//Disk stuff.
/obj/item/disk/data/Initialize()
. = ..()
icon_state = "datadisk[rand(0,6)]"
add_overlay("datadisk_gene")
/obj/item/disk/data/attack_self(mob/user)
read_only = !read_only
to_chat(user, "<span class='notice'>You flip the write-protect tab to [read_only ? "protected" : "unprotected"].</span>")
/obj/item/disk/data/examine(mob/user)
. = ..()
. += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]."
//Clonepod
/obj/machinery/clonepod/examine(mob/user)
. = ..()
var/mob/living/mob_occupant = occupant
if(mess)
. += "It's filled with blood and viscera. You swear you can see it moving..."
if(is_operational && istype(mob_occupant))
if(mob_occupant.stat != DEAD)
. += "Current clone cycle is [round(get_completion())]% complete."
/obj/machinery/clonepod/return_air()
// We want to simulate the clone not being in contact with
// the atmosphere, so we'll put them in a constant pressure
// nitrogen. They don't need to breathe while cloning anyway.
var/static/datum/gas_mixture/immutable/cloner/GM //global so that there's only one instance made for all cloning pods
if(!GM)
GM = new
return GM
/obj/machinery/clonepod/proc/get_completion()
. = FALSE
var/mob/living/mob_occupant = occupant
if(mob_occupant)
. = (100 * ((mob_occupant.health + 100) / (heal_level + 100)))
/obj/machinery/clonepod/attack_ai(mob/user)
return examine(user)
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(clonename, ui, mutation_index, mindref, last_death, blood_type, datum/species/mrace, list/features, list/mutantparts, list/markings, factions, list/quirks, datum/bank_account/insurance, list/traumas, empty)
if(panel_open)
return NONE
if(mess || attempting)
return NONE
if(!empty) //Doesn't matter if we're just making a copy
clonemind = locate(mindref) in SSticker.minds
if(!istype(clonemind)) //not a mind
return NONE
if(clonemind.last_death != last_death) //The soul has advanced, the record has not.
return NONE
if(!QDELETED(clonemind.current))
if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body
return NONE
if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding.
return NONE
if(!clonemind.active)
// get_ghost() will fail if they're unable to reenter their body
var/mob/dead/observer/G = clonemind.get_ghost()
if(!G)
return NONE
if(G.suiciding) // The ghost came from a body that is suiciding.
return NONE
if(clonemind.damnation_type) //Can't clone the damned.
INVOKE_ASYNC(src, .proc/horrifyingsound)
mess = TRUE
update_icon()
return NONE
current_insurance = insurance
attempting = TRUE //One at a time!!
countdown.start()
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
if(!clonename) //to prevent null names
clonename = "clone ([rand(1,999)])"
H.real_name = clonename
H.hardset_dna(ui, mutation_index, H.dna.default_mutation_genes, H.real_name, blood_type, mrace, features, H.dna.mutations, FALSE)
H.set_species(mrace, TRUE, null, features.Copy(), mutantparts.Copy(), markings.Copy())
if(!HAS_TRAIT(H, TRAIT_RADIMMUNE))//dont apply mutations if the species is Mutation proof.
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
//Get the clone body ready
maim_clone(H)
ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
H.Unconscious(80)
if(!empty)
clonemind.transfer_to(H)
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
to_chat(H, "<span class='userdanger'>[CONFIG_GET(string/blackoutpolicy)]</span>")
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
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), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
if(H)
H.faction |= factions
for(var/V in quirks)
var/datum/quirk/Q = new V(H)
Q.on_clone(quirks[V])
for(var/t in traumas)
var/datum/brain_trauma/BT = t
var/datum/brain_trauma/cloned_trauma = BT.on_clone()
if(cloned_trauma)
H.gain_trauma(cloned_trauma, BT.resilience)
H.set_cloned_appearance()
H.set_suicide(FALSE)
attempting = FALSE
update_icon()
return CLONING_SUCCESS
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
var/mob/living/mob_occupant = occupant
if(!is_operational) //Autoeject if power is lost
if(mob_occupant)
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to power loss.")
connected_message("Clone Ejected: Loss of power.")
else if(mob_occupant && (mob_occupant.loc == src))
if(SSeconomy.full_ancap)
if(!current_insurance)
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to invalid bank account.")
connected_message("Clone Ejected: No bank account.")
if(internal_radio)
SPEAK("The cloning of [mob_occupant.real_name] has been terminated due to no bank account to draw payment from.")
else if(!current_insurance.adjust_money(-fair_market_price))
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to insufficient funds.")
connected_message("Clone Ejected: Out of Money.")
if(internal_radio)
SPEAK("The cloning of [mob_occupant.real_name] has been ended prematurely due to being unable to pay.")
else
var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department)
if(D)
D.adjust_money(fair_market_price)
if(mob_occupant && (mob_occupant.stat == DEAD) || (mob_occupant.suiciding)) //Autoeject corpses and suiciding dudes.
connected_message("Clone Rejected: Deceased.")
if(internal_radio)
SPEAK("The cloning of [mob_occupant.real_name] has been \
aborted due to unrecoverable tissue failure.")
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] after suiciding.")
else if(mob_occupant && mob_occupant.cloneloss > (100 - heal_level))
mob_occupant.Unconscious(80)
var/dmg_mult = CONFIG_GET(number/damage_multiplier)
//Slowly get that clone healed and finished.
mob_occupant.adjustCloneLoss(-((speed_coeff / 2) * dmg_mult))
var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss()
// To avoid the default cloner making incomplete clones
progress += (100 - MINIMUM_HEAL_LEVEL)
var/milestone = CLONE_INITIAL_DAMAGE / flesh_number
var/installed = flesh_number - unattached_flesh.len
if((progress / milestone) >= installed)
// attach some flesh
var/obj/item/I = pick_n_take(unattached_flesh)
if(isorgan(I))
var/obj/item/organ/O = I
O.organ_flags &= ~ORGAN_FROZEN
O.Insert(mob_occupant)
else if(isbodypart(I))
var/obj/item/bodypart/BP = I
BP.attach_limb(mob_occupant)
use_power(7500) //This might need tweaking.
else if(mob_occupant && (mob_occupant.cloneloss <= (100 - heal_level)))
connected_message("Cloning Process Complete.")
if(internal_radio)
SPEAK("The cloning cycle of [mob_occupant.real_name] is complete.")
// If the cloner is upgraded to debugging high levels, sometimes
// organs and limbs can be missing.
for(var/i in unattached_flesh)
if(isorgan(i))
var/obj/item/organ/O = i
O.organ_flags &= ~ORGAN_FROZEN
O.Insert(mob_occupant)
else if(isbodypart(i))
var/obj/item/bodypart/BP = i
BP.attach_limb(mob_occupant)
go_out()
log_cloning("[key_name(mob_occupant)] completed cloning cycle in [src] at [AREACOORD(src)].")
else if (!mob_occupant || mob_occupant.loc != src)
occupant = null
if (!mess && !panel_open)
update_icon()
use_power(200)
update_icon()
//Let's unlock this early I guess. Might be too early, needs tweaking.
/obj/machinery/clonepod/attackby(obj/item/W, mob/user, params)
if(!(occupant || mess))
if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]",W))
return
if(default_deconstruction_crowbar(W))
return
if(W.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, W))
return
var/obj/item/multitool/P = W
if(istype(P.buffer, /obj/machinery/computer/cloning))
if(get_area(P.buffer) != get_area(src))
to_chat(user, "<font color = #666633>-% Cannot link machines across power zones. Buffer cleared %-</font color>")
P.buffer = null
return
to_chat(user, "<font color = #666633>-% Successfully linked [P.buffer] with [src] %-</font color>")
var/obj/machinery/computer/cloning/comp = P.buffer
if(connected)
connected.DetachCloner(src)
comp.AttachCloner(src)
else
P.buffer = src
to_chat(user, "<font color = #666633>-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-</font color>")
return
var/mob/living/mob_occupant = occupant
if(W.GetID())
if(!check_access(W))
to_chat(user, "<span class='danger'>Access Denied.</span>")
return
if(!(mob_occupant || mess))
to_chat(user, "<span class='danger'>Error: Pod has no occupant.</span>")
return
else
add_fingerprint(user)
connected_message("Emergency Ejection")
SPEAK("An emergency ejection of [clonemind.name] has occurred. Survival not guaranteed.")
to_chat(user, "<span class='notice'>You force an emergency ejection. </span>")
go_out()
log_cloning("[key_name(user)] manually ejected [key_name(mob_occupant)] from [src] at [AREACOORD(src)].")
log_combat(user, mob_occupant, "ejected", W, "from [src]")
else
return ..()
/obj/machinery/clonepod/emag_act(mob/user)
if(!occupant)
return
to_chat(user, "<span class='warning'>You corrupt the genetic compiler.</span>")
malfunction()
add_fingerprint(user)
log_cloning("[key_name(user)] emagged [src] at [AREACOORD(src)], causing it to malfunction.")
if(user)
log_combat(user, src, "emagged", null, occupant ? "[occupant] inside, killing them via malfunction." : null)
//Put messages in the connected computer's temp var for display.
/obj/machinery/clonepod/proc/connected_message(message)
if ((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning)))
return FALSE
if (!message)
return FALSE
connected.temp = message
connected.updateUsrDialog()
return TRUE
/obj/machinery/clonepod/proc/go_out()
countdown.stop()
var/mob/living/mob_occupant = occupant
var/turf/T = get_turf(src)
if(mess) //Clean that mess and dump those gibs!
for(var/obj/fl in unattached_flesh)
fl.forceMove(T)
if(istype(fl, /obj/item/organ))
var/obj/item/organ/O = fl
O.organ_flags &= ~ORGAN_FROZEN
unattached_flesh.Cut()
mess = FALSE
new /obj/effect/gibspawner/generic(get_turf(src), mob_occupant)
audible_message("<span class='hear'>You hear a splat.</span>")
update_icon()
return
if(!mob_occupant)
return
current_insurance = null
REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
REMOVE_TRAIT(mob_occupant, TRAIT_NOBREATH, CLONING_POD_TRAIT)
if(grab_ghost_when == CLONER_MATURE_CLONE)
mob_occupant.grab_ghost()
to_chat(occupant, "<span class='notice'><b>There is a bright flash!</b><br><i>You feel like a new being.</i></span>")
mob_occupant.flash_act()
occupant.forceMove(T)
update_icon()
mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
for(var/fl in unattached_flesh)
qdel(fl)
unattached_flesh.Cut()
occupant = null
clonemind = null
/obj/machinery/clonepod/proc/malfunction()
var/mob/living/mob_occupant = occupant
if(mob_occupant)
connected_message("Critical Error!")
SPEAK("Critical error! Please contact a Thinktronic Systems \
technician, as your warranty may be affected.")
mess = TRUE
maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet
update_icon()
if(clonemind && mob_occupant.mind != clonemind)
clonemind.transfer_to(mob_occupant)
mob_occupant.grab_ghost() // We really just want to make you suffer.
flash_color(mob_occupant, flash_color="#960000", flash_time=100)
to_chat(mob_occupant, "<span class='warning'><b>Agony blazes across your consciousness as your body is torn apart.</b><br><i>Is this what dying is like? Yes it is.</i></span>")
playsound(src, 'sound/machines/warning-buzzer.ogg', 50)
SEND_SOUND(mob_occupant, sound('sound/hallucinations/veryfar_noise.ogg',0,1,50))
log_cloning("[key_name(mob_occupant)] destroyed within [src] at [AREACOORD(src)] due to malfunction.")
QDEL_IN(mob_occupant, 40)
/obj/machinery/clonepod/container_resist_act(mob/living/user)
if(user.stat == CONSCIOUS)
go_out()
/obj/machinery/clonepod/relaymove(mob/user)
container_resist_act(user)
/obj/machinery/clonepod/emp_act(severity)
. = ..()
if (!(. & EMP_PROTECT_SELF))
var/mob/living/mob_occupant = occupant
if(mob_occupant && prob(100/(severity*efficiency)))
connected_message(Gibberish("EMP-caused Accidental Ejection"))
SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [mob_occupant.real_name] prematurely."))
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to EMP pulse.")
/obj/machinery/clonepod/ex_act(severity, target)
..()
if(!QDELETED(src) && occupant)
var/mob/living/mob_occupant = occupant
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to explosion.")
/obj/machinery/clonepod/handle_atom_del(atom/A)
if(A == occupant)
occupant = null
countdown.stop()
/obj/machinery/clonepod/proc/horrifyingsound()
for(var/i in 1 to 5)
playsound(src,pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 100, (rand(95,105) * 0.01))
sleep(1)
sleep(10)
playsound(src,'sound/hallucinations/wail.ogg', 100, TRUE)
/obj/machinery/clonepod/deconstruct(disassembled = TRUE)
if(occupant)
var/mob/living/mob_occupant = occupant
go_out()
log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to deconstruction.")
..()
/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H)
if(!unattached_flesh)
unattached_flesh = list()
else
for(var/fl in unattached_flesh)
qdel(fl)
unattached_flesh.Cut()
H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
// In addition to being cellularly damaged, they also have no limbs or internal organs.
// Applying brainloss is done when the clone leaves the pod, so application of traumas can happen
// based on the level of damage sustained.
if(!HAS_TRAIT(H, TRAIT_NODISMEMBER))
var/static/list/zones = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)
for(var/zone in zones)
var/obj/item/bodypart/BP = H.get_bodypart(zone)
if(BP)
BP.drop_limb()
BP.forceMove(src)
unattached_flesh += BP
for(var/o in H.internal_organs)
var/obj/item/organ/organ = o
if(!istype(organ) || (organ.organ_flags & ORGAN_VITAL))
continue
organ.organ_flags |= ORGAN_FROZEN
organ.Remove(H, special=TRUE)
organ.forceMove(src)
unattached_flesh += organ
flesh_number = unattached_flesh.len
/obj/machinery/clonepod/update_icon_state()
. = ..()
if(mess)
icon_state = "pod_g"
else if(occupant)
icon_state = "pod_1"
else
icon_state = "pod_0"
if(panel_open)
icon_state = "pod_0_maintenance"
/obj/machinery/clonepod/update_overlays()
. = ..()
if(mess)
var/mutable_appearance/gib1 = mutable_appearance('modular_skyrat/modules/cloning/icons/obj/machines/cryo_mobs.dmi', "gibup")
var/mutable_appearance/gib2 = mutable_appearance('modular_skyrat/modules/cloning/icons/obj/machines/cryo_mobs.dmi', "gibdown")
gib1.pixel_y = 27 + round(sin(world.time) * 3)
gib1.pixel_x = round(sin(world.time * 3))
gib2.pixel_y = 27 + round(cos(world.time) * 3)
gib2.pixel_x = round(cos(world.time * 3))
. += gib2
. += gib1
else if(occupant)
var/mutable_appearance/occupant_overlay
var/unattached_fl_number = length(unattached_flesh) ? unattached_flesh.len : 0
var/completion = (flesh_number - unattached_fl_number) / flesh_number
if(completion > 0.7)
occupant_overlay = mutable_appearance(occupant.icon, occupant.icon_state)
occupant_overlay.copy_overlays(occupant)
else
occupant_overlay = mutable_appearance('modular_skyrat/modules/cloning/icons/obj/machines/cryo_mobs.dmi', "clone_meat")
var/matrix/tform = matrix()
tform.Scale(completion)
tform.Turn(cos(world.time * 2) * 3)
occupant_overlay.transform = tform
occupant_overlay.appearance_flags = NONE
occupant_overlay.dir = SOUTH
occupant_overlay.pixel_y = 27 + round(sin(world.time) * 3)
occupant_overlay.pixel_x = round(sin(world.time * 3))
. += occupant_overlay
. += "cover-on"
. += "panel"
/*
* Manual -- A big ol' manual.
*/
/obj/item/paper/guides/jobs/medical/cloning
name = "paper - 'H-87 Cloning Apparatus Manual"
info = {"<h4>Getting Started</h4>
Congratulations, your station has purchased the H-87 industrial cloning device!<br>
Using the H-87 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the scan option to create a new profile!<br>
<b>That's all there is to it!</b><br>
<i>Notice, cloning system cannot scan inorganic life or small primates. Scan may fail if subject has suffered extreme brain damage.</i><br>
<p>Clone profiles may be viewed through the profiles menu. Scanning implants a complementary HEALTH MONITOR IMPLANT into the subject, which may be viewed from each profile.
Profile Deletion has been restricted to \[Station Head\] level access.</p>
<h4>Cloning from a profile</h4>
Cloning is as simple as pressing the CLONE option at the bottom of the desired profile.<br>
Per your company's EMPLOYEE PRIVACY RIGHTS agreement, the H-87 has been blocked from cloning crewmembers while they are still alive.<br>
<br>
<p>The provided CLONEPOD SYSTEM will produce the desired clone. Standard clone maturation times (With SPEEDCLONE technology) are roughly 90 seconds.
The cloning pod may be unlocked early with any \[Medical Researcher\] ID after initial maturation is complete.</p><br>
<i>Please note that resulting clones may have a small DEVELOPMENTAL DEFECT as a result of genetic drift.</i><br>
<h4>Profile Management</h4>
<p>The H-87 (as well as your station's standard genetics machine) can accept STANDARD DATA DISKETTES.
These diskettes are used to transfer genetic information between machines and profiles.
A load/save dialog will become available in each profile if a disk is inserted.</p><br>
<i>A good diskette is a great way to counter aforementioned genetic drift!</i><br>
<br>
<font size=1>This technology produced under license from Thinktronic Systems, LTD.</font>"}
#undef CLONE_INITIAL_DAMAGE
#undef SPEAK
#undef MINIMUM_HEAL_LEVEL
@@ -1,630 +0,0 @@
#define AUTOCLONING_MINIMAL_LEVEL 3
/obj/machinery/computer/cloning
name = "cloning console"
desc = "Used to clone people and manage DNA."
icon_screen = "dna"
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/cloning
req_access = list(ACCESS_GENETICS) //for modifying records
var/obj/machinery/dna_scannernew/scanner //Linked scanner. For scanning.
var/list/pods //Linked cloning pods
var/temp = "Inactive"
var/scantemp_ckey
var/scantemp = "Ready to Scan"
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/data/record/active_record
var/obj/item/disk/data/cloning/diskette //Incompatible format to genetics machine
//select which parts of the diskette to load
var/include_se = FALSE //mutations
var/include_ui = FALSE //appearance
var/include_ue = FALSE //blood type, UE, and name
var/loading = FALSE // Nice loading text
var/autoprocess = FALSE
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/cloning/Initialize()
. = ..()
updatemodules(TRUE)
/obj/machinery/computer/cloning/Destroy()
if(pods)
for(var/P in pods)
DetachCloner(P)
pods = null
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 && 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
/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
/proc/grow_clone_from_record(obj/machinery/clonepod/pod, datum/data/record/R, empty)
return pod.growclone(R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mindref"], R.fields["last_death"], R.fields["blood_type"], R.fields["mrace"], R.fields["features"], R.fields["mutant_bodyparts"], R.fields["body_markings"], R.fields["factions"], R.fields["quirks"], R.fields["bank_account"], R.fields["traumas"], empty)
/obj/machinery/computer/cloning/process()
if(!(scanner && LAZYLEN(pods) && autoprocess))
return
if(scanner.occupant && scanner.scan_level > 2)
scan_occupant(scanner.occupant)
for(var/datum/data/record/R in records)
var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mindref"])
if(!pod)
return
if(pod.occupant)
break
var/result = grow_clone_from_record(pod, R)
if(result & CLONING_SUCCESS)
temp = "[R.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
log_cloning("Cloning of [key_name(R.fields["mindref"])] automatically started via autoprocess - [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
if(result & CLONING_DELETE_RECORD)
records -= R
/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
scanner = findscanner()
if(findfirstcloner && !LAZYLEN(pods))
findcloner()
if(!autoprocess)
STOP_PROCESSING(SSmachines, src)
else
START_PROCESSING(SSmachines, src)
/obj/machinery/computer/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/cloning/proc/findcloner()
var/obj/machinery/clonepod/podf = null
for(var/direction in GLOB.cardinals)
podf = locate(/obj/machinery/clonepod, get_step(src, direction))
if (!isnull(podf) && podf.is_operational)
AttachCloner(podf)
/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod)
if(!pod.connected)
pod.connected = src
LAZYADD(pods, pod)
/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod)
pod.connected = null
LAZYREMOVE(pods, pod)
/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES
if (!diskette)
if (!user.transferItemToLoc(W,src))
return
diskette = W
to_chat(user, "<span class='notice'>You insert [W].</span>")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
updateUsrDialog()
else if(W.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, W))
return
var/obj/item/multitool/P = W
if(istype(P.buffer, /obj/machinery/clonepod))
if(get_area(P.buffer) != get_area(src))
to_chat(user, "<font color = #666633>-% Cannot link machines across power zones. Buffer cleared %-</font color>")
P.buffer = null
return
to_chat(user, "<font color = #666633>-% Successfully linked [P.buffer] with [src] %-</font color>")
var/obj/machinery/clonepod/pod = P.buffer
if(pod.connected)
pod.connected.DetachCloner(pod)
AttachCloner(pod)
else
P.buffer = src
to_chat(user, "<font color = #666633>-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-</font color>")
return
else
return ..()
/obj/machinery/computer/cloning/ui_interact(mob/living/user)
. = ..()
updatemodules(TRUE)
var/dat = ""
dat += "<a href='byond://?src=[REF(src)];refresh=1'>Refresh</a>"
if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL)
if(!autoprocess)
dat += "<a href='byond://?src=[REF(src)];task=autoprocess'>Autoprocess</a>"
else
dat += "<a href='byond://?src=[REF(src)];task=stopautoprocess'>Stop autoprocess</a>"
else
dat += "<span class='linkOff'>Autoprocess</span>"
dat += "<h3>Cloning Pod Status</h3>"
dat += "<div class='statusDisplay'>[temp]&nbsp;</div>"
switch(menu)
if(1)
// Modules
if (isnull(scanner) || !LAZYLEN(pods))
dat += "<h3>Modules</h3>"
//dat += "<a href='byond://?src=[REF(src)];relmodules=1'>Reload Modules</a>"
if (isnull(scanner))
dat += "<font class='bad'>ERROR: No Scanner detected!</font><br>"
if (!LAZYLEN(pods))
dat += "<font class='bad'>ERROR: No Pod detected</font><br>"
// Scanner
if (!isnull(scanner))
var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
dat += "<h3>Scanner Functions</h3>"
dat += "<div class='statusDisplay'>"
if(!scanner_occupant)
dat += "Scanner Unoccupied"
else if(loading)
dat += "[scanner_occupant] => Scanning..."
else
if(scanner_occupant.ckey != scantemp_ckey)
scantemp = "Ready to Scan"
scantemp_ckey = scanner_occupant.ckey
dat += "[scanner_occupant] => [scantemp]"
dat += "</div>"
if(scanner_occupant)
dat += "<a href='byond://?src=[REF(src)];scan=1'>Start Scan</a>"
dat += "<a href='byond://?src=[REF(src)];scan=1;body_only=1'>Body-Only Scan</a>"
dat += "<br><a href='byond://?src=[REF(src)];lock=1'>[scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
else
dat += "<span class='linkOff'>Start Scan</span>"
// Database
dat += "<h3>Database Functions</h3>"
if (records.len && records.len > 0)
dat += "<a href='byond://?src=[REF(src)];menu=2'>View Records ([records.len])</a><br>"
else
dat += "<span class='linkOff'>View Records (0)</span><br>"
if (diskette)
dat += "<a href='byond://?src=[REF(src)];disk=eject'>Eject Disk</a><br>"
if(2)
dat += "<h3>Current records</h3>"
dat += "<a href='byond://?src=[REF(src)];menu=1'><< Back</a><br><br>"
for(var/datum/data/record/R in records)
dat += "<h4>[R.fields["name"]]</h4>Scan ID [R.fields["id"]] <a href='byond://?src=[REF(src)];view_rec=[R.fields["id"]]'>View Record</a>"
if(3)
dat += "<h3>Selected Record</h3>"
dat += "<a href='byond://?src=[REF(src)];menu=2'><< Back</a><br>"
if (!active_record)
dat += "<font class='bad'>Record not found.</font>"
else
var/body_only = active_record.fields["body_only"]
dat += "<h4>[active_record.fields["name"]][body_only ? " - BODY-ONLY" : ""]</h4>"
dat += "Scan ID [active_record.fields["id"]] \
[!body_only ? "<a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]]'>Clone</a>" : "" ]\
<a href='byond://?src=[REF(src)];clone=[active_record.fields["id"]];empty=TRUE'>Empty Clone</a><br>"
var/obj/item/implant/health/H = locate(active_record.fields["imp"])
if ((H) && (istype(H)))
dat += "<b>Health Implant Data:</b><br />[H.sensehealth()]<br><br />"
else
dat += "<font class='bad'>Unable to locate Health Implant.</font><br /><br />"
dat += "<b>Unique Identifier:</b><br /><span class='highlight'>[active_record.fields["UI"]]</span><br>"
dat += "<b>Structural Enzymes:</b><br /><span class='highlight'>"
for(var/key in active_record.fields["SE"])
if(key != RACEMUT)
var/val = active_record.fields["SE"][key]
var/alias = GLOB.all_mutations[key].alias
dat +="[alias]: [val]<br />"
dat += "</span><br />"
if(diskette && diskette.fields)
dat += "<div class='block'>"
dat += "<h4>Inserted Disk</h4>"
dat += "<b>Contents:</b> "
var/list/L = list()
if(diskette.fields["UI"])
L += "Unique Identifier"
if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"])
L += "Unique Enzymes"
if(diskette.fields["SE"])
L += "Structural Enzymes"
dat += english_list(L, "Empty", " + ", " + ")
var/can_load = FALSE
var/obj/item/card/id/C = user.get_idcard(TRUE)
if(C)
if(check_access(C))
can_load = TRUE
if(can_load)
dat += "<br /><a href='byond://?src=[REF(src)];disk=load'>Load From Disk</a>"
else
dat += "<span class='linkOff'>Cannot Load From Disk: Access Denied</span>"
if(diskette.fields["SE"])
if(!include_se)
dat += "<br /><a href='byond://?src=[REF(src)];task=include_se'>Currently Excluding SE</a>"
else
dat += "<br /><a href='byond://?src=[REF(src)];task=exclude_se'>Currently Including SE</a>"
if(diskette.fields["UI"])
if(!include_ui)
dat += "<br /><a href='byond://?src=[REF(src)];task=include_ui'>Currently Excluding UI</a>"
else
dat += "<br /><a href='byond://?src=[REF(src)];task=exclude_ui'>Currently Including UI</a>"
if(diskette.fields["UE"])
if(!include_ue)
dat += "<br /><a href='byond://?src=[REF(src)];task=include_ue'>Currently Excluding UE</a>"
else
dat += "<br /><a href='byond://?src=[REF(src)];task=exclude_ue'>Currently Including UE</a>"
dat += "<br /><a href='byond://?src=[REF(src)];disk=save'>Save to Disk</a>"
dat += "</div>"
dat += "<font size=1><a href='byond://?src=[REF(src)];del_rec=1'>Delete Record</a></font>"
if(4)
if (!active_record)
menu = 2
ui_interact(user)
return
dat += "<b><a href='byond://?src=[REF(src)];del_rec=1'>Please confirm.</a></b><br>"
dat += "<b><a href='byond://?src=[REF(src)];menu=3'>Cancel</a></b>"
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
popup.set_content(dat)
//popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open()
/obj/machinery/computer/cloning/Topic(href, href_list)
if(..())
return
if(loading)
return
if(href_list["task"])
switch(href_list["task"])
if("autoprocess")
if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL)
autoprocess = TRUE
START_PROCESSING(SSmachines, src)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if("stopautoprocess")
autoprocess = FALSE
STOP_PROCESSING(SSmachines, src)
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
if("include_se")
include_se = TRUE
if("exclude_se")
include_se = FALSE
if("include_ui")
include_ui = TRUE
if("exclude_ui")
include_ui = FALSE
if("include_ue")
include_ue = TRUE
if("exclude_ue")
include_ue = FALSE
else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational)
scantemp = ""
var/body_only = href_list["body_only"]
loading = TRUE
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
say("Initiating scan...")
addtimer(CALLBACK(src, .proc/do_scan, usr, body_only), 2 SECONDS)
//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, FALSE)
else
scanner.locked = FALSE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
else if(href_list["view_rec"])
playsound(src, "terminal_type", 25, FALSE)
active_record = find_record("id", href_list["view_rec"], records)
if(active_record)
menu = 3
else
temp = "Record missing."
else if (href_list["del_rec"])
if ((!active_record) || (menu < 3))
return
if (menu == 3) //If we are viewing a record, confirm deletion
var/has_access = FALSE
if(ishuman(usr))
var/mob/living/carbon/human/user = usr
var/obj/item/card/id/C = user.get_idcard(TRUE)
if(C)
if(check_access(C))
has_access = TRUE
if(active_record.fields["body_only"]) //Body-only scans are not as important and can be deleted freely
has_access = TRUE
if(has_access)
temp = "Delete record?"
menu = 4
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
else
temp = "Access Denied"
menu = 2
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else if (menu == 4)
log_cloning("[key_name(usr)] deleted [key_name(active_record.fields["mindref"])]'s cloning records from [src] at [AREACOORD(src)].")
temp = "[active_record.fields["name"]] => Record deleted."
records.Remove(active_record)
active_record = null
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
menu = 2
else if (href_list["disk"]) //Load or eject.
switch(href_list["disk"])
if("load")
if (!diskette || !istype(diskette.fields))
temp = "<font class='bad'>Load error.</font>"
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if (!active_record)
temp = "<font class='bad'>Record error.</font>"
menu = 1
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if(include_ue)
overwrite_field_if_available(active_record, diskette, "UE")
overwrite_field_if_available(active_record, diskette, "name")
overwrite_field_if_available(active_record, diskette, "blood_type")
if(include_ui)
overwrite_field_if_available(active_record, diskette, "UI")
if(include_se)
overwrite_field_if_available(active_record, diskette, "SE")
log_cloning("[key_name(usr)] uploaded [key_name(active_record.fields["mindref"])]'s cloning records to [src] at [AREACOORD(src)] via [diskette].")
temp = "Load successful."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if("eject")
if(diskette)
diskette.forceMove(drop_location())
diskette = null
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
if("save")
if(!diskette || diskette.read_only || !active_record || !active_record.fields)
temp = "<font class='bad'>Save error.</font>"
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
log_cloning("[key_name(usr)] added [key_name(active_record.fields["mindref"])]'s cloning records to [diskette] via [src] at [AREACOORD(src)].")
diskette.fields = active_record.fields.Copy()
diskette.name = "data disk - '[diskette.fields["name"]]'"
temp = "Save successful."
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
else if (href_list["refresh"])
updateUsrDialog()
playsound(src, "terminal_type", 25, FALSE)
else if (href_list["clone"])
var/datum/data/record/C = find_record("id", href_list["clone"], records)
var/empty = href_list["empty"]
//Look for that player! They better be dead!
if(C)
if(C.fields["body_only"] && !empty)
temp = "<font class='bad'>Cannot initiate regular cloning with body-only scans.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
var/obj/machinery/clonepod/pod = GetAvailablePod()
var/success = FALSE
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!LAZYLEN(pods))
temp = "<font class='bad'>No Clonepods detected.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else if(!pod)
temp = "<font class='bad'>No Clonepods available.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else
var/result = grow_clone_from_record(pod, C, empty)
if(result & CLONING_SUCCESS)
temp = "[C.fields["name"]] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if(active_record == C)
active_record = null
menu = 1
success = TRUE
if(!empty)
log_cloning("[key_name(usr)] initiated cloning of [key_name(C.fields["mindref"])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
else
log_cloning("[key_name(usr)] initiated EMPTY cloning of [key_name(C.fields["mindref"])] via [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
if(result & CLONING_DELETE_RECORD)
if(active_record == C)
active_record = null
menu = 1
records -= C
if(!success)
temp = "[C.fields["name"]] => <font class='bad'>Initialisation failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else
temp = "<font class='bad'>Data corruption.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else if (href_list["menu"])
menu = text2num(href_list["menu"])
playsound(src, "terminal_type", 25, FALSE)
add_fingerprint(usr)
updateUsrDialog()
return
/obj/machinery/computer/cloning/proc/do_scan(mob/user, body_only)
scan_occupant(scanner.occupant, user, body_only)
loading = FALSE
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
/obj/machinery/computer/cloning/proc/scan_occupant(occupant, mob/M, body_only)
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
var/datum/dna/dna
var/datum/bank_account/has_bank_account
// Do not use unless you know what they are.
var/mob/living/carbon/C = mob_occupant
var/mob/living/brain/B = mob_occupant
if(ishuman(mob_occupant))
dna = C.has_dna()
var/obj/item/card/id/I = C.get_idcard(TRUE)
if(I)
has_bank_account = I.registered_account
if(isbrain(mob_occupant))
dna = B.stored_dna
if(!istype(dna))
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if(!body_only && (mob_occupant.suiciding))
scantemp = "<font class='bad'>Subject's brain is not responding to scanning stimuli.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if((HAS_TRAIT(mob_occupant, TRAIT_HUSK)) && (src.scanner.scan_level < 2))
scantemp = "<font class='bad'>Subject's body is too damaged to scan properly.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE)
return
if(HAS_TRAIT(mob_occupant, TRAIT_BADDNA))
scantemp = "<font class='bad'>Subject's DNA is damaged beyond any hope of recovery.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE)
return
if (!body_only && isnull(mob_occupant.mind))
scantemp = "<font class='bad'>Mental interface failure.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if(HAS_TRAIT(mob_occupant, TRAIT_DNC) || HAS_TRAIT(mob_occupant, TRAIT_DNR) || mob_occupant.mob_biotypes & MOB_ROBOTIC)
scantemp = "<font class='bad'>Subject [HAS_TRAIT(mob_occupant, TRAIT_DNC) ? "is a DNC, and cannot be cloned. If possible, try other methods of revival." : HAS_TRAIT(mob_occupant, TRAIT_DNR) ? "is a DNR, and cannot be revived in any way." : "could not be revived due to biological reasons."]</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE)
return
if(!body_only && SSeconomy.full_ancap)
if(!has_bank_account)
scantemp = "<font class='average'>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.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
var/datum/data/record/R = new()
if(dna.species)
// We store the instance rather than the path, because some
// species (abductors, slimepeople) store state in their
// species datums
dna.delete_species = FALSE
R.fields["mrace"] = dna.species
else
var/datum/species/rando_race = pick(GLOB.roundstart_races)
R.fields["mrace"] = rando_race.type
R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext_char(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
R.fields["UI"] = dna.uni_identity
R.fields["SE"] = dna.mutation_index
R.fields["blood_type"] = dna.blood_type
R.fields["features"] = dna.features
R.fields["mutant_bodyparts"] = dna.mutant_bodyparts
R.fields["body_markings"] = dna.body_markings
R.fields["factions"] = mob_occupant.faction
R.fields["quirks"] = list()
for(var/V in mob_occupant.roundstart_quirks)
var/datum/quirk/T = V
R.fields["quirks"][T.type] = T.clone_data()
R.fields["traumas"] = list()
if(ishuman(mob_occupant))
R.fields["traumas"] = C.get_traumas()
if(isbrain(mob_occupant))
R.fields["traumas"] = B.get_traumas()
R.fields["bank_account"] = has_bank_account
R.fields["mindref"] = "[REF(mob_occupant.mind)]"
R.fields["last_death"] = mob_occupant.stat == DEAD && mob_occupant.mind ? mob_occupant.mind.last_death : -1
R.fields["body_only"] = body_only
if(!body_only)
//Add an implant if needed
var/obj/item/implant/health/imp
for(var/obj/item/implant/health/HI in mob_occupant.implants)
imp = HI
break
if(!imp)
imp = new /obj/item/implant/health(mob_occupant)
imp.implant(mob_occupant)
R.fields["imp"] = "[REF(imp)]"
var/datum/data/record/old_record = find_record("mindref", REF(mob_occupant.mind), records)
if(body_only)
old_record = find_record("UE", dna.unique_enzymes, records) //Body-only records cannot be identified by mind, so we use the DNA
if(old_record && ((old_record.fields["UI"] != dna.uni_identity) || (!old_record.fields["body_only"]))) //Never overwrite a mind-and-body record if it exists
old_record = null
if(old_record)
records -= old_record
scantemp = "Record updated."
else
scantemp = "Subject successfully scanned."
records += R
log_cloning("[M ? key_name(M) : "Autoprocess"] added the [body_only ? "body-only " : ""]record of [key_name(mob_occupant)] to [src] at [AREACOORD(src)].")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50)
@@ -1,306 +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 = 'modular_skyrat/modules/cloning/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, list/mutantparts, list/markings, factions, list/quirks, datum/bank_account/insurance, list/traumas, empty)
if(panel_open)
return NONE
if(mess || attempting)
return NONE
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.dna.default_mutation_genes, H.real_name, blood_type, mrace, features, H.dna.mutations, FALSE)
H.set_species(mrace, TRUE, null, features, mutantparts, markings)
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
//Get the clone body ready
maim_clone(H)
ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT)
ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
H.Unconscious(80)
var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H, POLL_IGNORE_DEFECTIVECLONE)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
H.key = C.key
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
to_chat(H, "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>")
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), "<span class='notice'>Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.</span>")
if(H)
H.faction |= factions
H.set_cloned_appearance()
H.set_suicide(FALSE)
attempting = FALSE
update_icon()
return CLONING_DELETE_RECORD | CLONING_SUCCESS //so that we don't spam clones with autoprocess unless we leave a body in the scanner
//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(W.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, W))
return
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, "<font color = #666633>-% Cannot link machines across power zones. Buffer cleared %-</font color>")
P.buffer = null
return
to_chat(user, "<font color = #666633>-% Successfully linked [P.buffer] with [src] %-</font color>")
var/obj/machinery/clonepod/experimental/pod = P.buffer
if(pod.connected)
pod.connected.DetachCloner(pod)
AttachCloner(pod)
else
P.buffer = src
to_chat(user, "<font color = #666633>-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-</font color>")
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 += "<a href='byond://?src=[REF(src)];refresh=1'>Refresh</a>"
dat += "<h3>Cloning Pod Status</h3>"
dat += "<div class='statusDisplay'>[temp]&nbsp;</div>"
if (isnull(src.scanner) || !LAZYLEN(pods))
dat += "<h3>Modules</h3>"
//dat += "<a href='byond://?src=[REF(src)];relmodules=1'>Reload Modules</a>"
if (isnull(src.scanner))
dat += "<font class='bad'>ERROR: No Scanner detected!</font><br>"
if (!LAZYLEN(pods))
dat += "<font class='bad'>ERROR: No Pod detected</font><br>"
// Scan-n-Clone
if (!isnull(src.scanner))
var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant)
dat += "<h3>Cloning</h3>"
dat += "<div class='statusDisplay'>"
if(!scanner_occupant)
dat += "Scanner Unoccupied"
else if(loading)
dat += "[scanner_occupant] => Scanning..."
else
scantemp = "Ready to Clone"
dat += "[scanner_occupant] => [scantemp]"
dat += "</div>"
if(scanner_occupant)
dat += "<a href='byond://?src=[REF(src)];clone=1'>Clone</a>"
dat += "<br><a href='byond://?src=[REF(src)];lock=1'>[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]</a>"
else
dat += "<span class='linkOff'>Clone</span>"
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, FALSE)
say("Initiating scan...")
addtimer(CALLBACK(src, .proc/do_clone), 2 SECONDS)
//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, FALSE)
else
scanner.locked = FALSE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
else if (href_list["refresh"])
updateUsrDialog()
playsound(src, "terminal_type", 25, FALSE)
add_fingerprint(usr)
updateUsrDialog()
return
/obj/machinery/computer/prototype_cloning/proc/do_clone()
clone_occupant(scanner.occupant)
loading = FALSE
updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
/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 = "<font class='bad'>Unable to locate valid genetic data.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
if((HAS_TRAIT(mob_occupant, TRAIT_HUSK)) && (src.scanner.scan_level < 2))
scantemp = "<font class='bad'>Subject's body is too damaged to scan properly.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE)
return
if(HAS_TRAIT(mob_occupant, TRAIT_BADDNA))
scantemp = "<font class='bad'>Subject's DNA is damaged beyond any hope of recovery.</font>"
playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE)
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 = "<font class='bad'>No Clonepods detected.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else if(!pod)
temp = "<font class='bad'>No Clonepods available.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
else
pod.growclone(mob_occupant.real_name, dna.uni_identity, dna.mutation_index, null, null, dna.blood_type, clone_species, dna.features, dna.mutant_bodyparts, dna.body_markings, mob_occupant.faction)
temp = "[mob_occupant.real_name] => <font class='good'>Cloning data sent to pod.</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
@@ -1,12 +0,0 @@
/obj/effect/countdown/clonepod
name = "cloning pod countdown"
color = "#18d100"
text_size = 1
/obj/effect/countdown/clonepod/get_value()
var/obj/machinery/clonepod/C = attached_to
if(!istype(C))
return
else if(C.occupant)
var/completion = round(C.get_completion())
return completion
@@ -1,6 +0,0 @@
/obj/effect/spawner/lootdrop/techstorage/medical/New()
. = ..()
loot += list(/obj/item/circuitboard/machine/dnascanner,
/obj/item/circuitboard/computer/cloning,
/obj/item/circuitboard/machine/clonepod
)
@@ -1,9 +0,0 @@
/obj/item/circuitboard/computer/cloning
name = "Cloning (Computer Board)"
icon_state = "medical"
build_path = /obj/machinery/computer/cloning
/obj/item/circuitboard/computer/prototype_cloning
name = "Prototype Cloning (Computer Board)"
icon_state = "medical"
build_path = /obj/machinery/computer/prototype_cloning
@@ -1,14 +0,0 @@
/obj/item/circuitboard/machine/clonepod
name = "Clone Pod (Machine Board)"
icon_state = "medical"
build_path = /obj/machinery/clonepod
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/scanning_module = 2,
/obj/item/stock_parts/manipulator = 2,
/obj/item/stack/sheet/glass = 1)
/obj/item/circuitboard/machine/clonepod/experimental
name = "Experimental Clone Pod (Machine Board)"
icon_state = "medical"
build_path = /obj/machinery/clonepod/experimental
@@ -1,6 +0,0 @@
/obj/item/book/manual/wiki/medical_cloning
name = "Cloning techniques of the 26th century"
icon_state ="bookCloning"
author = "Medical Journal, volume 3"
title = "Cloning techniques of the 26th century"
page_link = "Guide_to_genetics#Cloning"
@@ -1,11 +0,0 @@
//used by cloners
/datum/gas_mixture/immutable/cloner
initial_temperature = T20C
/datum/gas_mixture/immutable/cloner/garbage_collect()
..()
ADD_GAS(/datum/gas/nitrogen, gases)
gases[/datum/gas/nitrogen][MOLES] = MOLES_O2STANDARD + MOLES_N2STANDARD
/datum/gas_mixture/immutable/cloner/heat_capacity()
return (MOLES_O2STANDARD + MOLES_N2STANDARD)*20 //specific heat of nitrogen is 20
@@ -1,7 +0,0 @@
/obj/structure/bookcase/manuals/medical
name = "medical manuals bookcase"
/obj/structure/bookcase/manuals/medical/Initialize()
. = ..()
new /obj/item/book/manual/wiki/medical_cloning(src)
update_icon()
@@ -1,5 +0,0 @@
/obj/item/organ/brain/transfer_identity(mob/living/L)
. = ..()
var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
if(ZI)
brainmob.set_species(ZI.old_species) //For if the brain is cloned
@@ -1,7 +0,0 @@
/datum/design/board/clonecontrol
name = "Computer Design (Cloning Console)"
desc = "Allows for the construction of circuit boards used to build a new Cloning console."
id = "clonecontrol"
build_path = /obj/item/circuitboard/computer/cloning
category = list("Computer Boards")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
@@ -1,7 +0,0 @@
/datum/design/board/clonepod
name = "Machine Design (Cloning Pod)"
desc = "Allows for the construction of circuit boards used to build a new cloning pod."
id = "clonepod"
build_path = /obj/item/circuitboard/machine/clonepod
category = list("Machine Boards")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
@@ -1,7 +0,0 @@
/datum/techweb_node/cloning
id = "cloning"
display_name = "Organic Replication(cloning)"
description = "We have the technology to MAKE him."
prereq_ids = list("biotech", "adv_biotech", "genetics")
design_ids = list("clonecontrol", "clonepod")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
@@ -1,35 +0,0 @@
/obj/item/paper/fluff/ruins/exp_cloning/manual
name = "paper - 'H-11 Cloning Apparatus Manual"
info = {"<h4>Getting Started</h4>
Congratulations, you are testing the H-11 experimental cloning device!<br>
Using the H-11 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the clone option to initiate cloning!<br>
<b>That's all there is to it!</b><br>
<i>Notice, cloning system cannot scan inorganic life or small primates. Scan may fail if subject has suffered extreme brain damage.</i><br>
<p>The provided CLONEPOD SYSTEM will produce the desired clone. Standard clone maturation times are roughly 90 seconds.
The cloning pod may be unlocked early after initial maturation is complete.</p><br>
<i>Please note that resulting clones will have a DEVELOPMENTAL DEFECT as a result of genetic drift. We hope to reduce this through further testing.<br>
Clones may also experience memory loss and radical changes in personality as a result of the cloning process.</i><br>
<br>
<font size=1>This technology produced under license from Thinktronic Systems, LTD.</font>"}
/obj/item/paper/fluff/ruins/exp_cloning/log
name = "experiment log"
info = {"<h4>Day 1</h4>
We are very excited to be part of the first crew of the SC Irmanda!<br>
This ship is made to test an innovative FTL technology. I had some concerns at first, \
but the engineers assure me that it is safe and there is absolutely no risk of the external wings breaking off from the acceleration.<br>
We've been tasked with testing the latest model of the Thinktronic Cloning Pod. We'll stay in dock for a week before launching, but we're going to get started right away. \
If the engine is as fast as they say, we might not have the time to run all the routine tests on the cloned subject!<br>
<br>
<h4>Day 2</h4>
We cloned an unknown corpse that was given to us by the medical crew. The genetic replication is good enough to let the subject survive outside of the pod, \
but the cellular damage remains a concern for his long-term survival. For safety we will be keeping him in quarantine.<br>
We left him some books, but clearly we were too optimistic about his mental faculties. His brain seems to suffer from the same cloning decay that was caused by \
the previous models. We will run further tests to see if there are improvements.<br>
<h4>Day 4</h4>
It seems we'll be launching even sooner than expected! Apparently the press is starting to lose interest, so we have to cut short the pre-flight checks \
and give them something to talk about. Hopefully this will end up with increased funding...<br>
The crew has all been invited to the main hall, where we have seats for the initial FTL acceleration. Unfortunately the clone cannot leave the quarantine room \
without risking infection, so we will strap him into the bed and hope for the best. We can grow another clone if anything goes wrong, anyway.
<br>
<i>Professor Galen Linkovich</i>"}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1016 B

-43
View File
@@ -1,43 +0,0 @@
https://github.com/Skyrat-SS13/Skyrat-tg/pull/151
## Title: Cloning
MODULE ID: CLONING
### Description:
Enables the crew to clone dead bodies via the cloning scanner.
### TG Proc Changes:
- code/_globalvars/lists/poll_ignore.dm > GLOBAL_LIST_INIT(poll_ignore_desc)
- code/datums/dna.dm > /datum/dna/Destroy()
- code/datums/shuttles.dm > /datum/map_template/shuttle/emergency/zeta
- code/modules/antagonists/revenant/revenant_abilities.dm > /obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/proc/malfunction()
- code/modules/clothing/head/misc_special.dm > /obj/item/clothing/head/foilhat/equipped()
### Defines:
- #define ACCESS_CLONING 68
- #define CLONER_FRESH_CLONE "fresh"
- #define CLONER_MATURE_CLONE "mature"
- #define CLONING_SUCCESS (1<<0)
- #define CLONING_DELETE_RECORD (1<<1)
- #define POLL_IGNORE_DEFECTIVECLONE "defective_clone"
<!-- If you needed to add any defines, mention the files you added those defines in -->
### Master file additions
- N/A
<!-- Any master file changes you've made to existing master files or if you've added a new master file. Please mark either as #NEW or #CHANGE -->
### Included files that are not contained in this module:
- N/A
<!-- Likewise, be it a non-modular file or a modular one that's not contained within the folder belonging to this specific module, it should be mentioned here -->
### Credits:
<!-- Here go the credits to you, dear coder, and in case of collaborative work or ports, credits to the original source of the code -->
-27
View File
@@ -3626,33 +3626,6 @@
#include "modular_skyrat\modules\cargo\code\bloat.dm"
#include "modular_skyrat\modules\cargo\code\goodies.dm"
#include "modular_skyrat\modules\cargo\code\packs.dm"
#include "modular_skyrat\modules\cloning\code\_DEFINES\access.dm"
#include "modular_skyrat\modules\cloning\code\_DEFINES\DNA.dm"
#include "modular_skyrat\modules\cloning\code\_DEFINES\machines.dm"
#include "modular_skyrat\modules\cloning\code\_DEFINES\poll_ignore.dm"
#include "modular_skyrat\modules\cloning\code\datums\brain_damage\brain_trauma.dm"
#include "modular_skyrat\modules\cloning\code\datums\brain_damage\phobia.dm"
#include "modular_skyrat\modules\cloning\code\datums\brain_damage\special.dm"
#include "modular_skyrat\modules\cloning\code\datums\mood_events\generic_negative_events.dm"
#include "modular_skyrat\modules\cloning\code\datums\ruins\space.dm"
#include "modular_skyrat\modules\cloning\code\datums\traits\_quirk.dm"
#include "modular_skyrat\modules\cloning\code\datums\traits\negative.dm"
#include "modular_skyrat\modules\cloning\code\game\area\Space_Station_13_areas.dm"
#include "modular_skyrat\modules\cloning\code\game\machinery\cloning.dm"
#include "modular_skyrat\modules\cloning\code\game\machinery\exp_cloner.dm"
#include "modular_skyrat\modules\cloning\code\game\machinery\computer\cloning.dm"
#include "modular_skyrat\modules\cloning\code\game\objects\effects\countdown.dm"
#include "modular_skyrat\modules\cloning\code\game\objects\effects\spawners\lootdrop.dm"
#include "modular_skyrat\modules\cloning\code\game\objects\items\manuals.dm"
#include "modular_skyrat\modules\cloning\code\game\objects\items\circuitboards\computer_circuitboards.dm"
#include "modular_skyrat\modules\cloning\code\game\objects\items\circuitboards\machine_circuitboards.dm"
#include "modular_skyrat\modules\cloning\code\modules\atmospherics\gasmixtures\immutable_mixtures.dm"
#include "modular_skyrat\modules\cloning\code\modules\library\lib_items.dm"
#include "modular_skyrat\modules\cloning\code\modules\mob\living\brain\brain_item.dm"
#include "modular_skyrat\modules\cloning\code\modules\research\designs\comp_board_designs.dm"
#include "modular_skyrat\modules\cloning\code\modules\research\designs\machine_designs.dm"
#include "modular_skyrat\modules\cloning\code\modules\research\techweb\all_nodes.dm"
#include "modular_skyrat\modules\cloning\code\modules\ruins\spaceruin_code\cloning_lab.dm"
#include "modular_skyrat\modules\cme\code\_cme_defines.dm"
#include "modular_skyrat\modules\cme\code\cme.dm"
#include "modular_skyrat\modules\combat_indicator\code\combat_indicator.dm"