Merge branch 'master' into name-muh-glands

This commit is contained in:
Jack Edge
2018-12-12 00:23:50 +00:00
183 changed files with 14382 additions and 2517 deletions
+179 -209
View File
@@ -17,12 +17,6 @@
/obj/effect/landmark/event_spawn,
/turf/open/floor/plating,
/area/maintenance/starboard)
"aae" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating{
icon_state = "platingdmg3"
},
/area/maintenance/starboard)
"aaf" = (
/obj/structure/lattice,
/turf/open/space,
@@ -38191,6 +38185,7 @@
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/effect/landmark/blobstart,
/turf/open/floor/plating,
/area/maintenance/starboard)
"bve" = (
@@ -47393,22 +47388,6 @@
dir = 5
},
/area/crew_quarters/kitchen)
"bNz" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 8
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
/area/crew_quarters/kitchen)
"bNA" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 10
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
/area/crew_quarters/kitchen)
"bNB" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
@@ -47433,24 +47412,30 @@
pixel_x = -27
},
/obj/structure/closet/secure_closet/freezer/meat,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bNE" = (
/obj/structure/sink/kitchen{
desc = "A sink used for washing one's hands and face. It looks rusty and home-made";
name = "old sink";
pixel_y = 28
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
dir = 6
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bNF" = (
/obj/machinery/gibber,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
dir = 4
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bNG" = (
/obj/structure/kitchenspike,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bNI" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 5
@@ -48039,7 +48024,6 @@
},
/area/crew_quarters/kitchen)
"bOU" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/structure/table,
/obj/item/book/manual/wiki/cooking_to_serve_man,
/turf/open/floor/plasteel/cafeteria{
@@ -48066,8 +48050,8 @@
/area/crew_quarters/kitchen)
"bOX" = (
/obj/structure/closet/secure_closet/freezer/kitchen,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bOY" = (
/obj/structure/sign/warning/vacuum/external{
pixel_x = 32
@@ -48082,14 +48066,15 @@
name = "CondiMaster Neo";
pixel_x = -4
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bPa" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/mob/living/simple_animal/hostile/retaliate/goat{
name = "Pete"
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bPb" = (
/obj/structure/table/wood,
/obj/structure/mirror{
@@ -48811,20 +48796,17 @@
},
/area/crew_quarters/kitchen)
"bQC" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 5
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 2
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
/area/crew_quarters/kitchen)
"bQD" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 1
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
@@ -48882,22 +48864,12 @@
/area/crew_quarters/kitchen)
"bQI" = (
/obj/machinery/vending/wardrobe/chef_wardrobe,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bQJ" = (
/obj/effect/landmark/start/cook,
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
},
/obj/effect/landmark/xeno_spawn,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
"bQK" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bQN" = (
/obj/machinery/airalarm{
dir = 8;
@@ -49441,15 +49413,15 @@
},
/area/crew_quarters/kitchen)
"bRU" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/disposalpipe/segment{
dir = 5
},
/obj/structure/cable/yellow{
icon_state = "1-4"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
@@ -49458,12 +49430,12 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
@@ -49476,13 +49448,15 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/turf/open/floor/plasteel/showroomfloor,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
/area/crew_quarters/kitchen)
"bRX" = (
/obj/structure/disposalpipe/segment{
@@ -49491,25 +49465,18 @@
/obj/item/radio/intercom{
pixel_y = -29
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 8
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bRY" = (
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/airalarm{
dir = 1;
pixel_y = -22
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
@@ -49517,8 +49484,15 @@
c_tag = "Kitchen - Coldroom";
dir = 1
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/airalarm/kitchen_cold_room{
dir = 1;
pixel_y = -24
},
/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
dir = 5
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bRZ" = (
/obj/structure/disposalpipe/segment{
dir = 4
@@ -49527,26 +49501,24 @@
pixel_y = -26
},
/obj/machinery/light,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
dir = 8
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bSa" = (
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 10
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/pipe/manifold4w/dark/visible,
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bSc" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable/yellow{
@@ -49951,69 +49923,66 @@
/turf/closed/wall,
/area/hydroponics)
"bSX" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 8
},
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/turf/open/floor/plasteel,
/area/crew_quarters/kitchen)
"bSY" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 5
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
/obj/machinery/atmospherics/pipe/manifold/dark/visible{
icon_state = "manifold-2";
dir = 8
},
/turf/open/floor/plasteel/kitchen_coldroom,
/area/crew_quarters/kitchen/coldroom)
"bSY" = (
/obj/structure/disposalpipe/segment,
/obj/structure/cable/yellow{
icon_state = "1-4"
},
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/turf/open/floor/plasteel,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/components/binary/pump/on{
dir = 8
},
/turf/open/floor/plasteel/kitchen_coldroom,
/area/crew_quarters/kitchen/coldroom)
"bSZ" = (
/obj/machinery/door/airlock/maintenance{
name = "Kitchen Maintenance";
req_access_txt = "28"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"bTa" = (
/obj/structure/disposalpipe/segment{
dir = 6
},
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
dir = 1
},
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/effect/landmark/blobstart,
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"bTb" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
},
/obj/structure/cable/yellow{
icon_state = "2-8"
},
/obj/structure/disposalpipe/segment{
dir = 10
},
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
dir = 1
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"bTc" = (
@@ -50051,9 +50020,6 @@
/obj/structure/cable/yellow{
icon_state = "1-8"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"bTf" = (
@@ -50609,36 +50575,27 @@
/turf/open/floor/plasteel,
/area/hydroponics)
"bUp" = (
/obj/structure/closet{
name = "spare parts locker"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 5
},
/obj/item/rack_parts,
/obj/item/rack_parts,
/obj/item/wrench,
/obj/structure/window/reinforced{
dir = 4
},
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom{
dir = 1
},
/turf/open/floor/plasteel/kitchen_coldroom,
/area/crew_quarters/kitchen/coldroom)
"bUq" = (
/obj/structure/disposalpipe/segment{
dir = 5
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/machinery/door/window/eastright{
dir = 1;
name = "Kitchen Delivery";
req_access_txt = "28"
},
/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel,
/area/crew_quarters/kitchen)
/turf/open/floor/plasteel/kitchen_coldroom,
/area/crew_quarters/kitchen/coldroom)
"bUr" = (
/obj/machinery/navbeacon{
codes_txt = "delivery;dir=8";
@@ -50650,27 +50607,23 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/obj/effect/turf_decal/bot{
dir = 1
},
/turf/open/floor/plasteel{
dir = 1
},
/area/crew_quarters/kitchen)
/area/crew_quarters/kitchen/coldroom)
"bUs" = (
/obj/structure/disposalpipe/sorting/mail{
dir = 2;
sortType = 20
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 6
},
/turf/open/floor/plating,
/area/maintenance/starboard)
@@ -50684,8 +50637,8 @@
/obj/structure/cable/yellow{
icon_state = "2-4"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 9
},
/turf/open/floor/plating,
/area/maintenance/starboard)
@@ -50699,9 +50652,6 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"bUv" = (
@@ -50711,9 +50661,6 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 4
},
/turf/open/floor/plating{
icon_state = "panelscorched"
},
@@ -51260,7 +51207,7 @@
icon_state = "1-2"
},
/turf/open/floor/plating,
/area/hallway/secondary/service)
/area/maintenance/starboard)
"bVB" = (
/obj/structure/rack,
/obj/item/extinguisher,
@@ -53220,11 +53167,9 @@
/area/hydroponics)
"bZx" = (
/obj/machinery/icecream_vat,
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 10
},
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"bZy" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/machinery/door/airlock{
@@ -53233,7 +53178,7 @@
req_one_access_txt = "25;26;35;28"
},
/turf/open/floor/plating,
/area/hallway/secondary/service)
/area/maintenance/starboard)
"bZB" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 9
@@ -53254,7 +53199,7 @@
icon_state = "1-2"
},
/turf/open/floor/plating,
/area/maintenance/disposal/incinerator)
/area/maintenance/starboard)
"bZE" = (
/turf/closed/wall,
/area/maintenance/disposal/incinerator)
@@ -56293,7 +56238,7 @@
},
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/plasteel,
/area/janitor)
/area/maintenance/starboard)
"cfl" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
dir = 4
@@ -56969,7 +56914,6 @@
/obj/structure/disposalpipe/segment{
dir = 10
},
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/cable/yellow{
icon_state = "2-8"
},
@@ -56978,8 +56922,11 @@
pixel_x = 28
},
/obj/structure/reagent_dispensers/cooking_oil,
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/pipe/simple/dark/visible{
dir = 9
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"cgG" = (
/obj/structure/closet/emcloset/anchored,
/obj/effect/turf_decal/stripes/line{
@@ -78138,8 +78085,9 @@
/turf/open/floor/plasteel,
/area/ai_monitored/storage/eva)
"dbn" = (
/turf/open/floor/plasteel/showroomfloor,
/area/crew_quarters/kitchen)
/obj/machinery/atmospherics/pipe/heat_exchanging/simple,
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"dbo" = (
/obj/machinery/light/small{
dir = 8
@@ -83028,6 +82976,17 @@
/obj/structure/grille,
/turf/open/space/basic,
/area/space/nearstation)
"fwt" = (
/obj/structure/sink/kitchen{
desc = "A sink used for washing one's hands and face. It looks rusty and home-made";
name = "old sink";
pixel_y = 28
},
/obj/machinery/atmospherics/pipe/heat_exchanging/simple{
dir = 10
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"fDD" = (
/obj/machinery/light_switch{
pixel_y = -25
@@ -83122,6 +83081,14 @@
},
/turf/open/floor/plating,
/area/maintenance/starboard/secondary)
"grA" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 8
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
/area/crew_quarters/kitchen)
"gtr" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
@@ -83797,14 +83764,14 @@
/turf/closed/wall,
/area/engine/storage_shared)
"oxX" = (
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
dir = 4
},
/obj/structure/closet,
/obj/item/flashlight,
/obj/effect/spawner/lootdrop/maintenance,
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 10
},
/turf/open/floor/plating,
/area/maintenance/disposal/incinerator)
/area/maintenance/starboard)
"oJW" = (
/obj/machinery/camera{
c_tag = "Engineering - Foyer - Shared Storage";
@@ -83870,7 +83837,6 @@
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
/area/maintenance/starboard)
"pzj" = (
@@ -83938,6 +83904,17 @@
},
/turf/open/floor/plating,
/area/maintenance/aft/secondary)
"pVb" = (
/obj/structure/cable/yellow{
icon_state = "4-8"
},
/obj/machinery/atmospherics/components/unary/vent_scrubber/on{
dir = 4
},
/turf/open/floor/plasteel/cafeteria{
dir = 5
},
/area/crew_quarters/kitchen)
"pYC" = (
/obj/structure/cable/yellow{
icon_state = "4-8"
@@ -84096,6 +84073,12 @@
},
/turf/open/floor/plasteel,
/area/engine/break_room)
"rFZ" = (
/obj/machinery/atmospherics/pipe/heat_exchanging/junction{
dir = 1
},
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor,
/area/crew_quarters/kitchen/coldroom)
"rGl" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/structure/disposalpipe/segment,
@@ -84127,6 +84110,9 @@
/obj/machinery/vending/snack/random,
/turf/open/floor/plasteel,
/area/maintenance/department/science)
"rUK" = (
/turf/closed/wall,
/area/crew_quarters/kitchen/coldroom)
"rWg" = (
/obj/item/twohanded/required/kirbyplants/random,
/obj/machinery/airalarm{
@@ -84338,22 +84324,6 @@
},
/turf/open/floor/plasteel,
/area/maintenance/department/science)
"uHc" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
dir = 10
},
/turf/open/floor/plating,
/area/maintenance/starboard)
"uJU" = (
/obj/structure/cable/yellow{
icon_state = "1-2"
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plating,
/area/maintenance/starboard)
"uLY" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/stripes/line{
@@ -118220,7 +118190,7 @@ bKf
bLK
bNy
bOS
bQB
pVb
bRR
bST
bUg
@@ -118475,7 +118445,7 @@ bHb
bMP
bKg
bLL
bNz
bLL
bOT
bQC
bLK
@@ -118732,7 +118702,7 @@ bHc
bIw
bKh
bLM
bNA
bLK
bOU
bQD
bRS
@@ -119249,7 +119219,7 @@ bLN
bLK
ddE
bQF
bNz
grA
bSV
bUk
bVv
@@ -120273,7 +120243,7 @@ bFs
bHd
byC
bKl
bKe
rUK
bND
bOX
bQI
@@ -120530,7 +120500,7 @@ bwX
bHe
dCU
bKm
bKe
rUK
bNE
dbn
dbn
@@ -120787,14 +120757,14 @@ bFt
bHf
byC
bKn
bKe
rUK
bNF
bOZ
bQJ
bRZ
bKe
bKe
bKe
rUK
rUK
rUK
bST
bST
bST
@@ -121044,14 +121014,14 @@ bwX
bHe
byC
bKo
bKe
bNE
rUK
fwt
bPa
bQK
rFZ
bSa
bSX
bUp
bKe
rUK
bWV
bYm
bZw
@@ -121301,14 +121271,14 @@ bFu
bFr
byC
bKp
bKe
rUK
bNG
bNG
bZx
cgF
bSY
bUq
bKe
rUK
diw
bYn
diz
@@ -121558,14 +121528,14 @@ bFv
bHg
dii
byN
bKe
bKe
bKe
bKe
bKe
rUK
rUK
rUK
rUK
rUK
bSZ
bUr
bKe
rUK
bST
bST
bST
@@ -123106,11 +123076,11 @@ bPg
bHl
bSc
eoK
uHc
uJU
uJU
pCV
pCV
pCV
pvA
aae
apf
oxX
bcf
xdW
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
#define FORCE_MAP "_maps/multiz_debug.json"
+6
View File
@@ -0,0 +1,6 @@
{
"map_name": "MultiZ Debug",
"map_path": "map_files/debug",
"map_file": "multiz.dmm",
"traits": [{"Up": 1}, {"Up": 1, "Down": -1}, {"Down": -1}]
}
+41 -30
View File
@@ -2,32 +2,39 @@
#define CHECK_DNA_AND_SPECIES(C) if((!(C.dna)) || (!(C.dna.species))) return
//Defines copying names of mutations in all cases, make sure to change this if you change mutation's name
#define HULK "Hulk"
#define XRAY "X Ray Vision"
#define COLDRES "Cold Resistance"
#define TK "Telekinesis"
#define NERVOUS "Nervousness"
#define EPILEPSY "Epilepsy"
#define MUTATE "Unstable DNA"
#define COUGH "Cough"
#define DWARFISM "Dwarfism"
#define CLOWNMUT "Clumsiness"
#define TOURETTES "Tourettes Syndrome"
#define DEAFMUT "Deafness"
#define BLINDMUT "Blindness"
#define RACEMUT "Monkified"
#define BADSIGHT "Near Sightness"
#define LASEREYES "Laser Eyes"
#define CHAMELEON "Chameleon"
#define WACKY "Wacky"
#define MUT_MUTE "Mute"
#define SMILE "Smile"
#define STONER "Stoner"
#define UNINTELLIGIBLE "Unintelligible"
#define SWEDISH "Swedish"
#define CHAV "Chav"
#define ELVIS "Elvis"
//Defines copying names of mutations in all cases, make sure to change this if you change mutation's type
#define HULK /datum/mutation/human/hulk
#define XRAY /datum/mutation/human/x_ray
#define SPACEMUT /datum/mutation/human/space_adaptation
#define TK /datum/mutation/human/telekinesis
#define NERVOUS /datum/mutation/human/nervousness
#define EPILEPSY /datum/mutation/human/epilepsy
#define MUTATE /datum/mutation/human/bad_dna
#define COUGH /datum/mutation/human/cough
#define DWARFISM /datum/mutation/human/dwarfism
#define CLOWNMUT /datum/mutation/human/clumsy
#define TOURETTES /datum/mutation/human/tourettes
#define DEAFMUT /datum/mutation/human/deaf
#define BLINDMUT /datum/mutation/human/blind
#define RACEMUT /datum/mutation/human/race
#define BADSIGHT /datum/mutation/human/nearsight
#define LASEREYES /datum/mutation/human/laser_eyes
#define CHAMELEON /datum/mutation/human/chameleon
#define WACKY /datum/mutation/human/wacky
#define MUT_MUTE /datum/mutation/human/mute
#define SMILE /datum/mutation/human/smile
#define STONER /datum/mutation/human/stoner
#define UNINTELLIGIBLE /datum/mutation/human/unintelligible
#define SWEDISH /datum/mutation/human/swedish
#define CHAV /datum/mutation/human/chav
#define ELVIS /datum/mutation/human/elvis
#define RADIOACTIVE /datum/mutation/human/radioactive
#define GLOWY /datum/mutation/human/glow
#define TELEPATHY /datum/mutation/human/telepath
#define FIREBREATH /datum/mutation/human/firebreath
#define VOID /datum/mutation/human/void
#define STRONG /datum/mutation/human/strong
#define FIRESWEAT /datum/mutation/human/fire
#define UI_CHANGED "ui changed"
#define UE_CHANGED "ue changed"
@@ -39,10 +46,13 @@
//Types of usual mutations
#define POSITIVE 1
#define NEGATIVE 2
#define MINOR_NEGATIVE 3
#define MINOR_NEGATIVE 4
//Mutations that cant be taken from genetics and are not in SE
#define NON_SCANNABLE -1
//Mutation classes. Normal being on them, extra being additional mutations with instability and other being stuff you dont want people to fuck with like wizard mutate
#define MUT_NORMAL 1
#define MUT_EXTRA 2
#define MUT_OTHER 3
//DNA - Because fuck you and your magic numbers being all over the codebase.
#define DNA_BLOCK_SIZE 3
@@ -56,7 +66,8 @@
#define DNA_FACIAL_HAIR_STYLE_BLOCK 6
#define DNA_HAIR_STYLE_BLOCK 7
#define DNA_STRUC_ENZYMES_BLOCKS 18
#define DNA_SEQUENCE_LENGTH 4
#define DNA_MUTATION_BLOCKS 8
#define DNA_UNIQUE_ENZYMES_LEN 32
//Transformation proc stuff
+6 -1
View File
@@ -147,14 +147,16 @@
#define ATMOS_PASS_NO 0
#define ATMOS_PASS_PROC -1 //ask CanAtmosPass()
#define ATMOS_PASS_DENSITY -2 //just check density
#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) )
#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) )
//OPEN TURF ATMOS
#define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn
#define TCOMMS_ATMOS "n2=100;TEMP=80" //-193,15°C telecommunications. also used for xenobiology slime killrooms
#define AIRLESS_ATMOS "TEMP=2.7" //space
#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15°C snow and ice turfs
#define KITCHEN_COLDROOM_ATMOS "o2=22;n2=82;TEMP=223.15" //-50°C kitchen coldroom
#define KITCHEN_COLDROOM_ATMOS "o2=33;n2=124;TEMP=193.15" //-80°C kitchen coldroom; higher amount of mol to reach about 101.3 kpA
#define BURNMIX_ATMOS "o2=2500;plasma=5000;TEMP=370" //used in the holodeck burn test program
//ATMOSPHERICS DEPARTMENT GAS TANK TURFS
@@ -298,3 +300,6 @@ GLOBAL_LIST_INIT(pipe_paint_colors, list(
"violet" = rgb(64,0,128),
"yellow" = rgb(255,198,0)
))
#define MIASMA_CORPSE_MOLES 0.02
#define MIASMA_GIBS_MOLES 0.005
+2
View File
@@ -103,6 +103,8 @@
// /turf signals
#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
// /atom/movable signals
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
+9 -4
View File
@@ -9,6 +9,7 @@
#define FLOOR_PLANE -2
#define GAME_PLANE -1
#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals
#define SPACE_LAYER 1.8
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
#define MID_TURF_LAYER 2.02
@@ -82,11 +83,15 @@
#define ABOVE_LIGHTING_PLANE 16
#define ABOVE_LIGHTING_LAYER 16
#define BYOND_LIGHTING_PLANE 17
#define BYOND_LIGHTING_LAYER 17
#define FLOOR_OPENSPACE_PLANE 17
#define OPENSPACE_LAYER 17
#define BYOND_LIGHTING_PLANE 18
#define BYOND_LIGHTING_LAYER 18
#define CAMERA_STATIC_PLANE 19
#define CAMERA_STATIC_LAYER 19
#define CAMERA_STATIC_PLANE 18
#define CAMERA_STATIC_LAYER 18
//HUD layer defines
#define FULLSCREEN_PLANE 19
+1
View File
@@ -117,6 +117,7 @@
#define BIOWARE_GENERIC "generic"
#define BIOWARE_NERVES "nerves"
#define BIOWARE_CIRCULATION "circulation"
#define BIOWARE_LIGAMENTS "ligaments"
//Health hud screws for carbon mobs
#define SCREWYHUD_NONE 0
+4
View File
@@ -7,6 +7,8 @@
#define STATUS_EFFECT_REPLACE 2 //if it allows only one, but new instances replace
#define STATUS_EFFECT_REFRESH 3 // if it only allows one, and new instances just instead refresh the timer
///////////
// BUFFS //
///////////
@@ -32,6 +34,8 @@
#define STATUS_EFFECT_HIPPOCRATIC_OATH /datum/status_effect/hippocraticOath //Gives you an aura of healing as well as regrowing the Rod of Asclepius if lost
#define STATUS_EFFECT_GOOD_MUSIC /datum/status_effect/good_music
/////////////
// DEBUFFS //
/////////////
+6
View File
@@ -35,6 +35,8 @@
#define TRAIT_NOHUNGER "no_hunger"
#define TRAIT_EASYDISMEMBER "easy_dismember"
#define TRAIT_LIMBATTACHMENT "limb_attach"
#define TRAIT_NOLIMBDISABLE "no_limb_disable"
#define TRAIT_EASYLIMBDISABLE "easy_limb_disable"
#define TRAIT_TOXINLOVER "toxinlover"
#define TRAIT_NOBREATH "no_breath"
#define TRAIT_ANTIMAGIC "anti_magic"
@@ -55,6 +57,7 @@
#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
#define TRAIT_PARALYSIS_R_LEG "para-r-leg"
#define TRAIT_DISK_VERIFIER "disk-verifier"
#define TRAIT_NOMOBSWAP "no-mob-swap"
#define TRAIT_XRAY_VISION "xray_vision"
#define TRAIT_ABDUCTOR_TRAINING "abductor-training"
@@ -92,6 +95,7 @@
#define SPECIES_TRAIT "species"
#define ORGAN_TRAIT "organ"
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
#define JOB_TRAIT "job"
// unique trait sources, still defines
#define STATUE_MUTE "statue"
@@ -106,3 +110,5 @@
#define CULT_EYES "cult_eyes"
#define SCRYING_ORB "scrying-orb"
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
#define NUKEOP_TRAIT "nuke-op"
#define DEATHSQUAD_TRAIT "deathsquad"
+8
View File
@@ -0,0 +1,8 @@
//////////////////////////////////////////////////////////
//A bunch of helpers to make genetics less of a headache//
//////////////////////////////////////////////////////////
#define get_initialized_mutation(A) GLOB.all_mutations[A]
#define mutation_in_sequence(A, B) ((A) in B.mutation_index)
#define get_gene_string(A, B) (B.mutation_index[A])
#define get_sequence(A) (GLOB.full_sequences[A])
+5 -3
View File
@@ -21,8 +21,10 @@ GLOBAL_LIST(op_se_blocks)
GLOBAL_VAR(NULLED_SE)
GLOBAL_VAR(NULLED_UI)
GLOBAL_LIST_EMPTY(global_mutations) // list of hidden mutation things
GLOBAL_LIST_EMPTY(all_mutations)
GLOBAL_LIST_EMPTY(full_sequences)
GLOBAL_LIST_EMPTY(bad_mutations)
GLOBAL_LIST_EMPTY(good_mutations)
GLOBAL_LIST_EMPTY(not_good_mutations)
GLOBAL_LIST_EMPTY(not_good_mutations)
GLOBAL_LIST_EMPTY(mutation_recipes)
+18 -8
View File
@@ -1,27 +1,37 @@
GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(cardinals_multiz, list(NORTH, SOUTH, EAST, WEST, UP, DOWN))
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_INIT(corners_multiz, list(UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST))
GLOBAL_LIST_INIT(diagonals_multiz, list(
NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST,
UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST,
DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST))
GLOBAL_LIST_INIT(alldirs_multiz, list(
NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST,
UP, UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST,
DOWN, DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST))
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
GLOBAL_LIST_EMPTY(landmarks_list) //list of all landmarks created
GLOBAL_LIST_EMPTY(start_landmarks_list) //list of all spawn points created
GLOBAL_LIST_EMPTY(department_security_spawns) //list of all department security spawns
GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events
GLOBAL_LIST_EMPTY(jobspawn_overrides) //These will take precedence over normal spawnpoints if created.
GLOBAL_LIST_EMPTY(generic_event_spawns) //handles clockwork portal+eminence teleport destinations
GLOBAL_LIST_EMPTY(jobspawn_overrides) //These will take precedence over normal spawnpoints if created.
GLOBAL_LIST_EMPTY(wizardstart)
GLOBAL_LIST_EMPTY(nukeop_start)
GLOBAL_LIST_EMPTY(nukeop_leader_start)
GLOBAL_LIST_EMPTY(newplayer_start)
GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here
GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these.
GLOBAL_LIST_EMPTY(prisonwarp) //admin prisoners go to these
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here (ninja energy net)
GLOBAL_LIST_EMPTY(xeno_spawn)//aliens, morphs and nightmares spawn at these
GLOBAL_LIST_EMPTY(tdome1)
GLOBAL_LIST_EMPTY(tdome2)
GLOBAL_LIST_EMPTY(tdomeobserve)
GLOBAL_LIST_EMPTY(tdomeadmin)
GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped
GLOBAL_LIST_EMPTY(blobstart)
GLOBAL_LIST_EMPTY(secequipment)
GLOBAL_LIST_EMPTY(blobstart) //stationloving objects, blobs, santa, respawning devils
GLOBAL_LIST_EMPTY(secequipment) //sec equipment lockers that scale with the number of sec players
GLOBAL_LIST_EMPTY(deathsquadspawn)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
GLOBAL_LIST_EMPTY(servant_spawns) //Servants of Ratvar spawn here
+22
View File
@@ -16,6 +16,28 @@
//Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong.
/obj/screen/plane_master/proc/backdrop(mob/mymob)
/obj/screen/plane_master/openspace
name = "open space plane master"
plane = FLOOR_OPENSPACE_PLANE
appearance_flags = PLANE_MASTER
blend_mode = BLEND_MULTIPLY
alpha = 255
/obj/screen/plane_master/openspace/backdrop(mob/mymob)
filters = list()
filters += filter(type = "drop_shadow", color = "#04080FAA", border = 5, size = -10)
filters += filter(type = "drop_shadow", color = "#04080FAA", border = 5, size = -15)
filters += filter(type = "drop_shadow", color = "#04080FAA", border = 5, size = -20)
/obj/screen/plane_master/proc/outline(_size, _color)
filters += filter(type = "outline", size = _size, color = _color)
/obj/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA")
filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset, border = _border)
/obj/screen/plane_master/proc/clear_filters()
filters = list()
/obj/screen/plane_master/floor
name = "floor plane master"
plane = FLOOR_PLANE
+2
View File
@@ -17,10 +17,12 @@ GLOBAL_LIST_EMPTY(radial_menus)
/obj/screen/radial/slice/MouseEntered(location, control, params)
. = ..()
icon_state = "radial_slice_focus"
openToolTip(usr, src, params, title = name)
/obj/screen/radial/slice/MouseExited(location, control, params)
. = ..()
icon_state = "radial_slice"
closeToolTip(usr)
/obj/screen/radial/slice/Click(location, control, params)
if(usr.client == parent.current_user)
+2 -2
View File
@@ -20,7 +20,7 @@
var/override = 0
for(var/datum/mutation/human/HM in dna.mutations)
override += HM.on_attack_hand(src, A, proximity)
override += HM.on_attack_hand(A, proximity)
if(override)
return
@@ -93,7 +93,7 @@
return
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_ranged_attack(src, A, mouseparams)
HM.on_ranged_attack(A, mouseparams)
if(isturf(A) && get_dist(src,A) <= 1)
src.Move_Pulled(A)
+2 -2
View File
@@ -54,7 +54,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/static/restart_clear = 0
var/static/restart_timeout = 0
var/static/restart_count = 0
var/static/random_seed
//current tick limit, assigned before running a subsystem.
@@ -69,7 +69,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
if(!random_seed)
random_seed = (TEST_RUN_PARAMETER in world.params) ? 29051994 : rand(1, 1e9)
rand_seed(random_seed)
var/list/_subsystems = list()
subsystems = _subsystems
if (Master != src)
+13 -10
View File
@@ -16,7 +16,7 @@ SUBSYSTEM_DEF(atoms)
/datum/controller/subsystem/atoms/Initialize(timeofday)
GLOB.fire_overlay.appearance_flags = RESET_COLOR
setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
setupGenetics() //to set the mutations' sequence
initialized = INITIALIZATION_INNEW_MAPLOAD
InitializeAtoms()
return ..()
@@ -106,16 +106,19 @@ SUBSYSTEM_DEF(atoms)
BadInitializeCalls = SSatoms.BadInitializeCalls
/datum/controller/subsystem/atoms/proc/setupGenetics()
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
avnums[i] = i
CHECK_TICK
for(var/A in subtypesof(/datum/mutation/human))
var/datum/mutation/human/B = new A()
if(B.dna_block == NON_SCANNABLE)
var/list/mutations = subtypesof(/datum/mutation/human)
shuffle_inplace(mutations)
for(var/A in subtypesof(/datum/generecipe))
var/datum/generecipe/GR = A
GLOB.mutation_recipes[initial(GR.required)] = initial(GR.result)
for(var/i in 1 to LAZYLEN(mutations))
var/path = mutations[i] //byond gets pissy when we do it in one line
var/datum/mutation/human/B = new path ()
B.alias = "Mutation #[i]"
GLOB.all_mutations[B.type] = B
GLOB.full_sequences[B.type] = generate_gene_sequence(B.blocks)
if(B.locked)
continue
B.dna_block = pick_n_take(avnums)
if(B.quality == POSITIVE)
GLOB.good_mutations |= B
else if(B.quality == NEGATIVE)
@@ -16,7 +16,7 @@ PROCESSING_SUBSYSTEM_DEF(quirks)
/datum/controller/subsystem/processing/quirks/Initialize(timeofday)
if(!quirks.len)
SetupQuirks()
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic"),list("Ageusia","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"))
quirk_blacklist = list(list("Blind","Nearsighted"),list("Jolly","Depression","Apathetic"),list("Ageusia","Vegetarian","Deviant Tastes"),list("Ananas Affinity","Ananas Aversion"))
return ..()
/datum/controller/subsystem/processing/quirks/proc/SetupQuirks()
+2 -2
View File
@@ -55,8 +55,8 @@ SUBSYSTEM_DEF(server_maint)
co.ehjax_send(data = "roundrestart")
if(server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[server]")
var/tgsversion = world.TgsVersion()
var/datum/tgs_version/tgsversion = world.TgsVersion()
if(tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion)
SSblackbox.record_feedback("text", "server_tools", 1, tgsversion.raw_parameter)
#undef PING_BUFFER_TIME
+1 -1
View File
@@ -73,7 +73,7 @@
//no fiddling with genetics to get out of this one
/datum/brain_trauma/mild/speech_impediment/on_life()
if(!(GLOB.mutations_list[UNINTELLIGIBLE] in owner.dna.mutations))
if(!(owner.dna.check_mutation(UNINTELLIGIBLE)))
on_gain()
..()
+1 -1
View File
@@ -143,7 +143,7 @@
/datum/brain_trauma/severe/monophobia
name = "Monophobia"
desc = "Patient feels sick and distressed when not around other people, leading to potentially lethal levels of stress."
scan_desc = "severe monophobia"
scan_desc = "monophobia"
gain_text = ""
lose_text = "<span class='notice'>You feel like you could be safe on your own.</span>"
var/stress = 0
+16
View File
@@ -0,0 +1,16 @@
/datum/component/heirloom
var/datum/mind/owner
var/family_name
/datum/component/heirloom/Initialize(new_owner, new_family_name)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
owner = new_owner
family_name = new_family_name
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
/datum/component/heirloom/proc/examine(datum/source, mob/user)
if(user.mind == owner)
to_chat(user, "<span class='notice'>It is your precious [family_name] family heirloom. Keep it safe!</span>")
+60
View File
@@ -0,0 +1,60 @@
/datum/component/rot
var/amount = 1
/datum/component/rot/Initialize(new_amount)
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
if(new_amount)
amount = new_amount
START_PROCESSING(SSprocessing, src)
/datum/component/rot/process()
var/atom/A = parent
var/turf/open/T = get_turf(A)
if(!istype(T))
return
var/datum/gas_mixture/air = T.return_air()
var/list/cached_gases = air.gases
ASSERT_GAS(/datum/gas/miasma, air)
cached_gases[/datum/gas/miasma][MOLES] += amount
T.air_update_turf()
/datum/component/rot/corpse
amount = MIASMA_CORPSE_MOLES
/datum/component/rot/corpse/Initialize()
if(!ishuman(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
/datum/component/rot/corpse/process()
var/mob/living/carbon/human/H = parent
if(H.stat != DEAD)
qdel(src)
return
// Wait a bit before decaying
if(world.time - H.timeofdeath < 2 MINUTES)
return
// Properly stored corpses shouldn't create miasma
if(istype(H.loc, /obj/structure/closet/crate/coffin)|| istype(H.loc, /obj/structure/closet/body_bag) || istype(H.loc, /obj/structure/bodycontainer))
return
// No decay if formaldehyde in corpse or when the corpse is charred
if(H.reagents.has_reagent("formaldehyde", 15) || H.has_trait(TRAIT_HUSK))
return
// Also no decay if corpse chilled or not organic/undead
if(H.bodytemperature <= T0C-10 || (!(MOB_ORGANIC in H.mob_biotypes) && !(MOB_UNDEAD in H.mob_biotypes)))
return
..()
/datum/component/rot/gibs
amount = MIASMA_GIBS_MOLES
+1 -1
View File
@@ -53,4 +53,4 @@
if(droptext)
fool.visible_message(arglist(droptext))
if(dropsound)
playsound(master, pick(dropsound), 30)
playsound(master, pick(dropsound), 30)
-1
View File
@@ -277,7 +277,6 @@
L.fields["sex"] = H.gender
L.fields["blood_type"] = H.dna.blood_type
L.fields["b_dna"] = H.dna.unique_enzymes
L.fields["enzymes"] = H.dna.struc_enzymes
L.fields["identity"] = H.dna.uni_identity
L.fields["species"] = H.dna.species.type
L.fields["features"] = H.dna.features
@@ -58,12 +58,12 @@ Bonus
symptom_delay_max = 60
if(A.properties["resistance"] >= 8) //mutate twice
power = 2
possible_mutations = (GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]
possible_mutations = (GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.all_mutations[RACEMUT]
var/mob/living/carbon/M = A.affected_mob
if(M)
if(!M.has_dna())
return
archived_dna = M.dna.struc_enzymes
archived_dna = M.dna.mutation_index
// Give them back their old DNA when cured.
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
@@ -74,5 +74,5 @@ Bonus
if(M && archived_dna)
if(!M.has_dna())
return
M.dna.struc_enzymes = archived_dna
M.dna.mutation_index = archived_dna
M.domutcheck()
+214 -56
View File
@@ -2,17 +2,19 @@
/////////////////////////// DNA DATUM
/datum/dna
var/unique_enzymes
var/struc_enzymes
var/uni_identity
var/blood_type
var/datum/species/species = new /datum/species/human //The type of mutant race the player is if applicable (i.e. potato-man)
var/list/features = list("FFF") //first value is mutant color
var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
var/list/mutations = list() //All mutations are from now on here
var/list/temporary_mutations = list() //Timers for temporary mutations
var/list/temporary_mutations = list() //Temporary changes to the UE
var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
var/mob/living/holder
var/delete_species = TRUE //Set to FALSE when a body is scanned by a cloner to fix #38875
var/mutation_index[DNA_MUTATION_BLOCKS] //List of which mutations this carbon has and its assigned block
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.
/datum/dna/New(mob/living/new_holder)
if(istype(new_holder))
@@ -45,11 +47,11 @@
destination.dna.real_name = real_name
destination.dna.temporary_mutations = temporary_mutations.Copy()
if(transfer_SE)
destination.dna.struc_enzymes = struc_enzymes
destination.dna.mutation_index = mutation_index
/datum/dna/proc/copy_dna(datum/dna/new_dna)
new_dna.unique_enzymes = unique_enzymes
new_dna.struc_enzymes = struc_enzymes
new_dna.mutation_index = mutation_index
new_dna.uni_identity = uni_identity
new_dna.blood_type = blood_type
new_dna.features = features.Copy()
@@ -57,26 +59,28 @@
new_dna.real_name = real_name
new_dna.mutations = mutations.Copy()
/datum/dna/proc/add_mutation(mutation_name)
var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
HM.on_acquiring(holder)
//See mutation.dm for what 'class' does. 'time' is time till it removes itself in decimals. 0 for no timer
/datum/dna/proc/add_mutation(mutation_type, class = MUT_OTHER, time)
if(get_mutation(mutation_type))
return
force_give(new mutation_type (class, time))
/datum/dna/proc/remove_mutation(mutation_name)
var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
HM.on_losing(holder)
/datum/dna/proc/remove_mutation(mutation_type)
force_lose(get_mutation(mutation_type))
/datum/dna/proc/check_mutation(mutation_name)
var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name]
return mutations.Find(HM)
/datum/dna/proc/check_mutation(mutation_type)
return get_mutation(mutation_type)
/datum/dna/proc/remove_all_mutations()
remove_mutation_group(mutations)
/datum/dna/proc/remove_all_mutations(list/classes = list(MUT_NORMAL, MUT_EXTRA, MUT_OTHER))
remove_mutation_group(mutations, classes)
scrambled = FALSE
/datum/dna/proc/remove_mutation_group(list/group)
/datum/dna/proc/remove_mutation_group(list/group, list/classes = list(MUT_NORMAL, MUT_EXTRA, MUT_OTHER))
if(!group)
return
for(var/datum/mutation/human/HM in group)
HM.force_lose(holder)
if(HM.class in classes)
force_lose(HM)
/datum/dna/proc/generate_uni_identity()
. = ""
@@ -103,19 +107,49 @@
. += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
return .
/datum/dna/proc/generate_struc_enzymes()
var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS)
var/result = ""
for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations)
if(A.name == RACEMUT && ismonkey(holder))
sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE)
mutations |= A
else
sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6"))
/datum/dna/proc/generate_dna_blocks()
var/bonus
if(species && species.inert_mutation)
bonus = get_initialized_mutation(species.inert_mutation)
var/list/mutations_temp = GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations + bonus
if(!LAZYLEN(mutations_temp))
return
mutation_index.Cut()
shuffle_inplace(mutations_temp)
if(ismonkey(holder))
mutations |= new RACEMUT(MUT_NORMAL)
mutation_index[RACEMUT] = get_sequence(RACEMUT)
else
mutation_index[RACEMUT] = create_sequence(RACEMUT, FALSE)
for(var/i in 2 to DNA_MUTATION_BLOCKS)
var/datum/mutation/human/M = mutations_temp[i]
mutation_index[M.type] = create_sequence(M.type, FALSE,M.difficulty)
shuffle_inplace(mutation_index)
for(var/B in sorting)
result += B
return result
//Used to generate original gene sequences for every mutation
/proc/generate_gene_sequence(length=4)
var/static/list/active_sequences = list("AT","TA","GC","CG")
var/sequence
for(var/i in 1 to length*DNA_SEQUENCE_LENGTH)
sequence += pick(active_sequences)
return sequence
//Used to create a chipped gene sequence
/proc/create_sequence(mutation, active, difficulty)
if(!difficulty)
var/datum/mutation/human/A = get_initialized_mutation(mutation) //leaves the possibility to change difficulty mid-round
if(A)
return
difficulty = A.difficulty
difficulty += rand(-2,4)
var/sequence = get_sequence(mutation)
if(active)
return sequence
while(difficulty)
var/randnum = rand(1, length(sequence))
sequence = copytext(sequence, 1, randnum) + "X" + copytext(sequence, randnum+1, length(sequence)+1)
difficulty--
return sequence
/datum/dna/proc/generate_unique_enzymes()
. = ""
@@ -146,6 +180,21 @@
if(DNA_HAIR_STYLE_BLOCK)
setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len))
//Please use add_mutation or activate_mutation instead
/datum/dna/proc/force_give(datum/mutation/human/HM)
if(holder && HM)
if(HM.class == MUT_NORMAL)
set_se(1, HM)
. = HM.on_acquiring(holder)
if(.)
qdel(HM)
//Use remove_mutation instead
/datum/dna/proc/force_lose(datum/mutation/human/HM)
if(holder && (HM in mutations))
set_se(0, HM)
return HM.on_losing(holder)
/datum/dna/proc/mutations_say_mods(message)
if(message)
for(var/datum/mutation/human/M in mutations)
@@ -166,11 +215,76 @@
/datum/dna/proc/is_same_as(datum/dna/D)
if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name)
if(uni_identity == D.uni_identity && mutation_index == D.mutation_index && real_name == D.real_name)
if(species.type == D.species.type && features == D.features && blood_type == D.blood_type)
return 1
return 0
/datum/dna/proc/update_instability(alert=FALSE)
stability = 100
for(var/datum/mutation/human/M in mutations)
if(M.class == MUT_EXTRA)
stability -= M.instability
if(holder && alert)
var/message
switch(stability)
if(90 to 70)
message = "<span class='warning'>You shiver.</span>"
if(69 to 60)
message = "<span class='warning'>You feel cold.</span>"
if(59 to 40)
message = "<span class='warning'>You feel sick.</span>"
if(39 to 20)
message = "<span class='warning'>It feels like your skin is moving.</span>"
if(19 to 1)
message = "<span class='warning'>You can feel your cells burning.</span>"
if(0 to -INFINITY)
message = "<span class='boldwarning'>You can feel your DNA exploding, we need to do something fast!</span>"
addtimer(CALLBACK(src, .proc/something_horrible), 600) //you've got 60 seconds to get your shit togheter
if(message)
to_chat(holder,message)
/datum/dna/proc/something_horrible()
if(!holder || (stability > 0))
return
var/instability = -stability
remove_all_mutations()
stability = 100
if(!ishuman(holder))
holder.gib()
return
var/mob/living/carbon/human/H = holder
if(prob(max(70-instability,0)))
switch(rand(0,3)) //not complete and utter death
if(0)
H.monkeyize()
if(1)
H.gain_trauma(/datum/brain_trauma/severe/paralysis)
if(2)
H.corgize()
if(3)
to_chat(H, "<span class='notice'>Oh, we actually feel quite alright!</span>")
else
switch(rand(0,3))
if(0)
H.gib()
if(1)
H.dust()
if(2)
H.death()
H.petrify(INFINITY)
if(3)
if(prob(90))
var/obj/item/bodypart/BP = H.get_bodypart(pick(BODY_ZONE_CHEST,BODY_ZONE_HEAD))
if(BP)
BP.dismember()
else
H.gib()
else
H.set_species(/datum/species/dullahan)
//used to update dna UI, UE, and dna.real_name.
/datum/dna/proc/update_dna_identity()
uni_identity = generate_uni_identity()
@@ -181,7 +295,7 @@
blood_type = newblood_type
unique_enzymes = generate_unique_enzymes()
uni_identity = generate_uni_identity()
struc_enzymes = generate_struc_enzymes()
generate_dna_blocks()
features = random_features()
@@ -246,7 +360,7 @@
return dna
/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures)
/mob/living/carbon/human/proc/hardset_dna(ui, list/mutation_index, newreal_name, newblood_type, datum/species/mrace, newfeatures)
if(newfeatures)
dna.features = newfeatures
@@ -267,8 +381,8 @@
dna.uni_identity = ui
updateappearance(icon_update=0)
if(se)
dna.struc_enzymes = se
if(LAZYLEN(mutation_index))
dna.mutation_index = mutation_index
domutcheck()
if(mrace || newfeatures || ui)
@@ -311,19 +425,56 @@
/mob/proc/domutcheck()
return
/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
/mob/living/carbon/domutcheck()
if(!has_dna())
return
for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations)
if(ismob(A.check_block(src, force_powers)))
for(var/mutation in dna.mutation_index)
if(ismob(dna.check_block(mutation)))
return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
update_mutations_overlay()
/datum/dna/proc/check_block(mutation)
var/datum/mutation/human/HM = get_mutation(mutation)
if(check_block_string(mutation))
if(!HM)
. = add_mutation(mutation, MUT_NORMAL)
return
return force_lose(HM)
//Return the active mutation of a type if there is one
/datum/dna/proc/get_mutation(A)
for(var/datum/mutation/human/HM in mutations)
if(HM.type == A)
return HM
/datum/dna/proc/check_block_string(mutation)
if((LAZYLEN(mutation_index) > DNA_MUTATION_BLOCKS) || !(mutation in mutation_index))
return 0
return is_gene_active(mutation)
/datum/dna/proc/is_gene_active(mutation)
return (mutation_index[mutation] == get_sequence(mutation))
/datum/dna/proc/set_se(on=TRUE, datum/mutation/human/HM)
if(!HM || !(HM.type in mutation_index) || (LAZYLEN(mutation_index) < DNA_MUTATION_BLOCKS))
return
. = TRUE
if(on)
mutation_index[HM.type] = get_sequence(HM.type)
else if(get_sequence(HM.type) == mutation_index[HM.type])
mutation_index[HM.type] = create_sequence(HM.type, FALSE, HM.difficulty)
/datum/dna/proc/activate_mutation(mutation)
if(!mutation)
return
if(!mutation_in_sequence(mutation, src)) //cant activate what we dont have, use add_mutation
return FALSE
return add_mutation(mutation, MUT_NORMAL)
/////////////////////////// DNA HELPER-PROCS //////////////////////////////
/proc/getleftblocks(input,blocknumber,blocksize)
if(blocknumber > 1)
return copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
@@ -343,26 +494,33 @@
/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2)
if(!has_dna())
return
var/datum/mutation/human/num = pick(candidates)
. = num.force_give(src)
var/mutation = pick(candidates)
. = dna.add_mutation(mutation)
/mob/living/carbon/proc/randmutb()
/mob/living/carbon/proc/easy_randmut(quality = POSITIVE + NEGATIVE + MINOR_NEGATIVE, scrambled = TRUE, sequence = TRUE, exclude_monkey = TRUE)
if(!has_dna())
return
var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT])
. = HM.force_give(src)
/mob/living/carbon/proc/randmutg()
if(!has_dna())
return
var/datum/mutation/human/HM = pick(GLOB.good_mutations)
. = HM.force_give(src)
/mob/living/carbon/proc/randmutvg()
if(!has_dna())
return
var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM])
. = HM.force_give(src)
var/list/mutations = list()
if(quality & POSITIVE)
mutations += GLOB.good_mutations
if(quality & NEGATIVE)
mutations += GLOB.bad_mutations
if(quality & MINOR_NEGATIVE)
mutations += GLOB.not_good_mutations
var/list/possible = list()
for(var/datum/mutation/human/A in mutations)
if((!sequence || mutation_in_sequence(A.type, dna)) && !dna.get_mutation(A.type))
possible += A.type
if(exclude_monkey)
possible.Remove(RACEMUT)
if(LAZYLEN(possible))
var/mutation = pick(possible)
. = dna.activate_mutation(mutation)
if(scrambled)
var/datum/mutation/human/HM = dna.get_mutation(mutation)
if(HM)
HM.scrambled = TRUE
return TRUE
/mob/living/carbon/proc/randmuti()
if(!has_dna())
@@ -385,9 +543,9 @@
if(!M.has_dna())
return 0
if(se)
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
for(var/i=1, i<=DNA_MUTATION_BLOCKS, i++)
if(prob(probability))
M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
M.dna.generate_dna_blocks()
M.domutcheck()
if(ui)
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
+15 -15
View File
@@ -14,13 +14,13 @@
var/turf/open/T = get_turf(parent)
if(!istype(T))
return
var/mob/living/LM = parent
var/v = volume
var/e = e_range
if(!T.footstep || LM.buckled || !CHECK_MULTIPLE_BITFIELDS(LM.mobility_flags, MOBILITY_STAND | MOBILITY_MOVE) || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING) || (LM.stat != CONSCIOUS) || LM.incapacitated() || LM.IsStun() || LM.IsParalyzed())
return
if(iscarbon(LM))
var/mob/living/carbon/C = LM
if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG))
@@ -29,18 +29,18 @@
v /= 2
e -= 5
steps++
if(steps >= 6)
steps = 0
if(steps % 2)
return
if(!LM.has_gravity(T) && steps != 0) // don't need to step as often when you hop around
return
//begin playsound shenanigans//
//for barefooted non-clawed mobs like monkeys
if(isbarefoot(LM))
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
@@ -48,19 +48,19 @@
TRUE,
GLOB.barefootstep[T.barefootstep][3] + e)
return
//for xenomorphs, dogs, and other clawed mobs
if(isclawfoot(LM))
if(isalienadult(LM)) //xenos are stealthy and get quieter footsteps
v /= 3
e -= 3
playsound(T, pick(GLOB.clawfootstep[T.clawfootstep][1]),
GLOB.clawfootstep[T.clawfootstep][2] * v,
TRUE,
GLOB.clawfootstep[T.clawfootstep][3] + e)
return
//for megafauna and other large and imtimidating mobs such as the bloodminer
if(isheavyfoot(LM))
playsound(T, pick(GLOB.heavyfootstep[T.heavyfootstep][1]),
@@ -68,12 +68,12 @@
TRUE,
GLOB.heavyfootstep[T.heavyfootstep][3] + e)
return
//for slimes
if(isslime(LM))
if(isslime(LM))
playsound(T, 'sound/effects/footstep/slime1.ogg', 15 * v)
return
//for (simple) humanoid mobs (clowns, russians, pirates, etc.)
if(isshoefoot(LM))
if(!ishuman(LM))
@@ -85,13 +85,13 @@
if(ishuman(LM)) //for proper humans, they're special
var/mob/living/carbon/human/H = LM
var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET))
if(H.shoes || feetCover) //are we wearing shoes
playsound(T, pick(GLOB.footstep[T.footstep][1]),
GLOB.footstep[T.footstep][2] * v,
TRUE,
GLOB.footstep[T.footstep][3] + e)
if((!H.shoes && !feetCover) || !(H.mobility_flags & MOBILITY_STAND)) //are we NOT wearing shoes or are we lying/crawling (using hands to move around)?
playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]),
GLOB.barefootstep[T.barefootstep][2] * v,
+2 -1
View File
@@ -76,7 +76,8 @@
else if(!pc)
msg += "No commit information"
if(world.TgsAvailable())
msg += "Server tools version: [world.TgsVersion()]"
var/datum/tgs_version/version = world.TgsVersion()
msg += "Server tools version: [version.raw_parameter]"
// Game mode odds
msg += "<br><b>Current Informational Settings:</b>"
+1 -1
View File
@@ -8,7 +8,7 @@
// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation)
// no_effects: disable the default effectin/effectout of sparks
// forced: whether or not to ignore no_teleport
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = FALSE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE)
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE)
// teleporting most effects just deletes them
var/static/list/delete_atoms = typecacheof(list(
/obj/effect,
+59 -56
View File
@@ -1,93 +1,84 @@
GLOBAL_LIST_EMPTY(mutations_list)
/datum/mutation
var/name
/datum/mutation/New()
GLOB.mutations_list[name] = src
/datum/mutation/human
var/dna_block
name = "mutation"
var/desc = "A mutation."
var/locked
var/quality
var/get_chance = 100
var/lowest_value = 256 * 8
var/text_gain_indication = ""
var/text_lose_indication = ""
var/list/mutable_appearance/visual_indicators = list()
var/static/list/mutable_appearance/visual_indicators = list()
var/obj/effect/proc_holder/spell/power
var/layer_used = MUTATIONS_LAYER //which mutation layer to use
var/list/species_allowed = list() //to restrict mutation to only certain species
var/health_req //minimum health required to acquire the mutation
var/limb_req //required limbs to acquire this mutation
var/time_coeff = 1 //coefficient for timed mutations
var/datum/dna/dna
var/mob/living/carbon/human/owner
var/instability = 0 //instability the holder gets when the mutation is not native
var/blocks = 4 //Amount of those big blocks with gene sequences
var/difficulty = 8 //Amount of missing sequences. Sometimes it removes an entire pair for 2 points
var/timed = FALSE //Boolean to easily check if we're going to self destruct
var/alias //'Mutation #49', decided every round to get some form of distinction between undiscovered mutations
var/scrambled = FALSE //Wheter we can read it if it's active. To avoid cheesing with mutagen
var/class //Decides player accesibility, sorta
//MUT_NORMAL - A mutation that can be activated and deactived by completing a sequence
//MUT_EXTRA - A mutation that is in the mutations tab, and can be given and taken away through though the DNA console. Has a 0 before it's name in the mutation section of the dna console
//MUT_OTHER Cannot be interacted with by players through normal means. I.E. wizards mutate
/datum/mutation/human/proc/force_give(mob/living/carbon/human/owner)
set_block(owner)
. = on_acquiring(owner)
/datum/mutation/human/New(class_ = MUT_OTHER, timer)
. = ..()
class = class_
if(timer)
addtimer(CALLBACK(src, .proc/remove), timer)
timed = TRUE
/datum/mutation/human/proc/force_lose(mob/living/carbon/human/owner)
set_block(owner, 0)
. = on_losing(owner)
/datum/mutation/human/proc/set_se(se_string, on = 1)
if(!se_string || lentext(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE)
return
var/before = copytext(se_string, 1, ((dna_block - 1) * DNA_BLOCK_SIZE) + 1)
var/injection = num2hex(on ? rand(lowest_value, (256 * 16) - 1) : rand(0, lowest_value - 1), DNA_BLOCK_SIZE)
var/after = copytext(se_string, (dna_block * DNA_BLOCK_SIZE) + 1, 0)
return before + injection + after
/datum/mutation/human/proc/set_block(mob/living/carbon/owner, on = 1)
if(owner && owner.has_dna())
owner.dna.struc_enzymes = set_se(owner.dna.struc_enzymes, on)
/datum/mutation/human/proc/check_block_string(se_string)
if(!se_string || lentext(se_string) < DNA_STRUC_ENZYMES_BLOCKS * DNA_BLOCK_SIZE)
return 0
if(hex2num(getblock(se_string, dna_block)) >= lowest_value)
return 1
/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner, force_powers=0)
if(check_block_string(owner.dna.struc_enzymes))
if(prob(get_chance)||force_powers)
. = on_acquiring(owner)
else
. = on_losing(owner)
/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/owner)
if(!owner || !istype(owner) || owner.stat == DEAD || (src in owner.dna.mutations))
/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/H)
if(!H || !istype(H) || H.stat == DEAD || (src in H.dna.mutations))
return TRUE
if(species_allowed.len && !species_allowed.Find(owner.dna.species.id))
if(species_allowed.len && !species_allowed.Find(H.dna.species.id))
return TRUE
if(health_req && owner.health < health_req)
if(health_req && H.health < health_req)
return TRUE
if(limb_req && !owner.get_bodypart(limb_req))
if(limb_req && !H.get_bodypart(limb_req))
return TRUE
owner.dna.mutations.Add(src)
owner = H
dna = H.dna
dna.mutations += src
if(text_gain_indication)
to_chat(owner, text_gain_indication)
if(visual_indicators.len)
var/list/mut_overlay = list(get_visual_indicator(owner))
var/list/mut_overlay = list(get_visual_indicator())
if(owner.overlays_standing[layer_used])
mut_overlay = owner.overlays_standing[layer_used]
mut_overlay |= get_visual_indicator(owner)
mut_overlay |= get_visual_indicator()
owner.remove_overlay(layer_used)
owner.overlays_standing[layer_used] = mut_overlay
owner.apply_overlay(layer_used)
if(power)
power = new power()
power.action_background_icon_state = "bg_tech_blue_on"
power.panel = "Genetic"
owner.AddSpell(power)
/datum/mutation/human/proc/get_visual_indicator(mob/living/carbon/human/owner)
/datum/mutation/human/proc/get_visual_indicator()
return
/datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
/datum/mutation/human/proc/on_attack_hand( atom/target, proximity)
return
/datum/mutation/human/proc/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
/datum/mutation/human/proc/on_ranged_attack(atom/target)
return
/datum/mutation/human/proc/on_move(mob/living/carbon/human/owner, new_loc)
/datum/mutation/human/proc/on_move(new_loc)
return
/datum/mutation/human/proc/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/proc/on_life()
return
/datum/mutation/human/proc/on_losing(mob/living/carbon/human/owner)
@@ -99,9 +90,12 @@ GLOBAL_LIST_EMPTY(mutations_list)
if(owner.overlays_standing[layer_used])
mut_overlay = owner.overlays_standing[layer_used]
owner.remove_overlay(layer_used)
mut_overlay.Remove(get_visual_indicator(owner))
mut_overlay.Remove(get_visual_indicator())
owner.overlays_standing[layer_used] = mut_overlay
owner.apply_overlay(layer_used)
if(power)
owner.RemoveSpell(power)
qdel(src)
return 0
return 1
@@ -118,17 +112,26 @@ GLOBAL_LIST_EMPTY(mutations_list)
/mob/living/carbon/human/update_mutations_overlay()
for(var/datum/mutation/human/CM in dna.mutations)
if(CM.species_allowed.len && !CM.species_allowed.Find(dna.species.id))
CM.force_lose(src) //shouldn't have that mutation at all
dna.force_lose(CM) //shouldn't have that mutation at all
continue
if(CM.visual_indicators.len)
var/list/mut_overlay = list()
if(overlays_standing[CM.layer_used])
mut_overlay = overlays_standing[CM.layer_used]
var/mutable_appearance/V = CM.get_visual_indicator(src)
var/mutable_appearance/V = CM.get_visual_indicator()
if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one
remove_overlay(CM.layer_used)
for(var/mutable_appearance/MA in CM.visual_indicators)
for(var/mutable_appearance/MA in CM.visual_indicators[CM.type])
mut_overlay.Remove(MA)
mut_overlay |= V
overlays_standing[CM.layer_used] = mut_overlay
apply_overlay(CM.layer_used)
/datum/mutation/human/proc/copy_mutation(datum/mutation/human/HM) //Not yet implemented, useful for when assigning specific stats.
/datum/mutation/human/proc/remove()
if(dna)
dna.force_lose(src)
else
qdel(src)
+116
View File
@@ -0,0 +1,116 @@
/datum/mutation/human/telepathy
name = "Telepathy"
desc = "A rare mutation that allows the user to telepathically communicate to others."
quality = POSITIVE
text_gain_indication = "<span class='notice'>You can hear your own voice echoing in your mind!</span>"
text_lose_indication = "<span class='notice'>You don't hear your mind echo anymore.</span>"
difficulty = 12
power = /obj/effect/proc_holder/spell/targeted/telepathy/genetic
instability = 10
/datum/mutation/human/telepathy/on_acquiring(mob/living/carbon/human/owner)
. = ..()
/datum/mutation/human/telepathy/on_losing(mob/living/carbon/human/owner)
. = ..()
/obj/effect/proc_holder/spell/targeted/telepathy/genetic
magic_check = FALSE
/datum/mutation/human/firebreath
name = "Fire Breath"
desc = "An ancient mutation that gives lizards breath of fire."
quality = POSITIVE
difficulty = 12
locked = TRUE
text_gain_indication = "<span class='notice'>Your throat is burning!</span>"
text_lose_indication = "<span class='notice'>Your throat is cooling down.</span>"
power = /obj/effect/proc_holder/spell/aimed/firebreath
instability = 30
/obj/effect/proc_holder/spell/aimed/firebreath
name = "Fire Breath"
desc = "You can breathe fire at a target."
school = "evocation"
charge_max = 600
clothes_req = FALSE
range = 20
projectile_type = /obj/item/projectile/magic/aoe/fireball/firebreath
base_icon_state = "fireball"
action_icon_state = "fireball0"
sound = 'sound/magic/demon_dies.ogg' //horrifying lizard noises
active_msg = "You built up heat in your mouth."
deactive_msg = "You swallow the flame."
/obj/effect/proc_holder/spell/aimed/firebreath/before_cast(list/targets)
. = ..()
if(iscarbon(usr))
var/mob/living/carbon/C = usr
if(C.is_mouth_covered())
C.adjust_fire_stacks(2)
C.IgniteMob()
to_chat(C,"<span class='warning'>Something in front of your mouth caught fire!</span>")
return FALSE
/obj/item/projectile/magic/aoe/fireball/firebreath
name = "fire breath"
exp_heavy = 0
exp_light = 0
exp_flash = 0
exp_fire= 4
/datum/mutation/human/void
name = "Void Magnet"
desc = "A rare genome that attracts odd forces not usually observed."
quality = MINOR_NEGATIVE //upsides and downsides
text_gain_indication = "<span class='notice'>You feel a heavy, dull force just beyond the walls watching you.</span>"
instability = 30
power = /obj/effect/proc_holder/spell/self/void
/datum/mutation/human/void/on_life()
var/obj/effect/proc_holder/spell/self/void/voidpower = power
if(voidpower.in_use) //i don't know how rare this is but coughs are 10% on life so in theory this should be okay
return
if(prob(0.5+((100-dna.stability)/20))) //very rare, but enough to annoy you hopefully. +0.5 probability for every 10 points lost in stability
if(voidpower.action)
voidpower.action.UpdateButtonIcon()
voidpower.invocation_type = "none"
voidpower.cast(user=owner)
/obj/effect/proc_holder/spell/self/void
name = "Convoke Void" //magic the gathering joke here
desc = "A rare genome that attracts odd forces not usually observed. May sometimes pull you in randomly."
school = "evocation"
clothes_req = FALSE
charge_max = 600
invocation = "DOOOOOOOOOOOOOOOOOOOOM!!!"
invocation_type = "shout"
action_icon_state = "void_magnet"
var/in_use = FALSE //so it doesnt cast while you are already deep innit
/obj/effect/proc_holder/spell/self/void/can_cast(mob/user = usr)
. = ..()
if(in_use)
return FALSE
/obj/effect/proc_holder/spell/self/void/cast(mob/user = usr)
in_use = TRUE
user.visible_message("<span class='danger'>[user] is dragged into the void, leaving a hole in [user.p_their()] place!</span>")
var/obj/effect/immortality_talisman/Z = new(get_turf(user))
Z.name = "hole in reality"
Z.desc = "It's shaped an awful lot like [user.name]."
Z.setDir(user.dir)
user.forceMove(Z)
user.notransform = 1
user.status_flags |= GODMODE
addtimer(CALLBACK(src, .proc/return_to_reality, user, Z), 100)
/obj/effect/proc_holder/spell/self/void/proc/return_to_reality(mob/user, obj/effect/immortality_talisman/Z)
in_use = FALSE
invocation_type = initial(invocation_type)
user.status_flags &= ~GODMODE
user.notransform = 0
user.forceMove(get_turf(Z))
user.visible_message("<span class='danger'>[user] pops back into reality!</span>")
Z.can_destroy = TRUE
qdel(Z)
+75 -8
View File
@@ -3,18 +3,19 @@
//Epilepsy gives a very small chance to have a seizure every life tick, knocking you unconscious.
/datum/mutation/human/epilepsy
name = "Epilepsy"
desc = "A genetic defect that sporadically causes seizures."
quality = NEGATIVE
text_gain_indication = "<span class='danger'>You get a headache.</span>"
/datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/epilepsy/on_life()
if(prob(1) && owner.stat == CONSCIOUS)
owner.visible_message("<span class='danger'>[owner] starts having a seizure!</span>", "<span class='userdanger'>You have a seizure!</span>")
owner.Unconscious(200)
owner.Jitter(1000)
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "epilepsy", /datum/mood_event/epilepsy)
addtimer(CALLBACK(src, .proc/jitter_less, owner), 90)
addtimer(CALLBACK(src, .proc/jitter_less), 90)
/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner)
/datum/mutation/human/epilepsy/proc/jitter_less()
if(owner)
owner.jitteriness = 10
@@ -22,19 +23,23 @@
//Unstable DNA induces random mutations!
/datum/mutation/human/bad_dna
name = "Unstable DNA"
desc = "Strange mutation that causes the holder to randomly mutate."
quality = NEGATIVE
text_gain_indication = "<span class='danger'>You feel strange.</span>"
locked = TRUE
/datum/mutation/human/bad_dna/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
to_chat(owner, text_gain_indication)
var/mob/new_mob
if(prob(95))
if(prob(50))
new_mob = owner.randmutb()
new_mob = owner.easy_randmut(NEGATIVE + MINOR_NEGATIVE)
else
new_mob = owner.randmuti()
else
new_mob = owner.randmutg()
new_mob = owner.easy_randmut(POSITIVE)
if(new_mob && ismob(new_mob))
owner = new_mob
. = owner
@@ -44,10 +49,11 @@
//Cough gives you a chronic cough that causes you to drop items.
/datum/mutation/human/cough
name = "Cough"
desc = "A chronic cough."
quality = MINOR_NEGATIVE
text_gain_indication = "<span class='danger'>You start coughing.</span>"
/datum/mutation/human/cough/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/cough/on_life()
if(prob(5) && owner.stat == CONSCIOUS)
owner.drop_all_held_items()
owner.emote("cough")
@@ -56,9 +62,11 @@
//Dwarfism shrinks your body and lets you pass tables.
/datum/mutation/human/dwarfism
name = "Dwarfism"
desc = "A mutation believed to be the cause of dwarfism."
quality = POSITIVE
get_chance = 15
lowest_value = 256 * 12
difficulty = 16
instability = 5
locked = TRUE // Default intert species for now, so locked from regular pool.
/datum/mutation/human/dwarfism/on_acquiring(mob/living/carbon/human/owner)
if(..())
@@ -80,6 +88,7 @@
//Clumsiness has a very large amount of small drawbacks depending on item.
/datum/mutation/human/clumsy
name = "Clumsiness"
desc = "A genome that inhibits certain brain functions, causing the holder to appear clumsy. Honk"
quality = MINOR_NEGATIVE
text_gain_indication = "<span class='danger'>You feel lightheaded.</span>"
@@ -97,6 +106,7 @@
//Tourettes causes you to randomly stand in place and shout.
/datum/mutation/human/tourettes
name = "Tourette's Syndrome"
desc = "A chronic twitch that forces the user to scream bad words." //definitely needs rewriting
quality = NEGATIVE
text_gain_indication = "<span class='danger'>You twitch.</span>"
@@ -119,6 +129,7 @@
//Deafness makes you deaf.
/datum/mutation/human/deaf
name = "Deafness"
desc = "The holder of this genome is completely deaf."
quality = NEGATIVE
text_gain_indication = "<span class='danger'>You can't seem to hear anything.</span>"
@@ -136,8 +147,10 @@
//Monified turns you into a monkey.
/datum/mutation/human/race
name = "Monkified"
desc = "A strange genome, believing to be what differentiates monkeys from humans."
quality = NEGATIVE
time_coeff = 2
locked = TRUE //Species specific, keep out of actual gene pool
/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner)
if(..())
@@ -147,3 +160,57 @@
/datum/mutation/human/race/on_losing(mob/living/carbon/monkey/owner)
if(owner && istype(owner) && owner.stat != DEAD && (owner.dna.mutations.Remove(src)))
. = owner.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
/datum/mutation/human/glow
name = "Glowy"
desc = "You permanently emit a light with a random color and intensity."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your skin begins to glow softly.</span>"
instability = 5
var/obj/effect/dummy/luminescent_glow/glowth //shamelessly copied from luminescents
var/glow = 1.5
/datum/mutation/human/glow/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
glowth = new(owner)
glowth.set_light(glow, glow, dna.features["mcolor"])
/datum/mutation/human/glow/on_losing(mob/living/carbon/human/owner)
if(..())
return
qdel(glowth)
/datum/mutation/human/strong
name = "Strength"
desc = "The user's muscles slightly expand."
quality = POSITIVE
text_gain_indication = "<span class='notice'>You feel strong.</span>"
difficulty = 16
/datum/mutation/human/fire
name = "Fiery Sweat"
desc = "The user's skin will randomly combust, but is generally alot more resilient to burning."
quality = NEGATIVE
text_gain_indication = "<span class='warning'>You feel hot.</span>"
text_lose_indication = "<span class'notice'>You feel a lot cooler.</span>"
difficulty = 14
/datum/mutation/human/fire/on_life()
if(prob(1+(100-dna.stability)/10))
owner.adjust_fire_stacks(2)
owner.IgniteMob()
/datum/mutation/human/fire/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.physiology.burn_mod *= 0.5
/datum/mutation/human/fire/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.physiology.burn_mod *= 2
+6 -5
View File
@@ -1,25 +1,26 @@
//Chameleon causes the owner to slowly become transparent when not moving.
/datum/mutation/human/chameleon
name = "Chameleon"
desc = "A genome that causes the holder's skin to become transparent over time."
quality = POSITIVE
get_chance = 20
lowest_value = 256 * 12
difficulty = 16
text_gain_indication = "<span class='notice'>You feel one with your surroundings.</span>"
text_lose_indication = "<span class='notice'>You feel oddly exposed.</span>"
time_coeff = 5
instability = 25
/datum/mutation/human/chameleon/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
/datum/mutation/human/chameleon/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/chameleon/on_life()
owner.alpha = max(0, owner.alpha - 25)
/datum/mutation/human/chameleon/on_move(mob/living/carbon/human/owner)
/datum/mutation/human/chameleon/on_move()
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
/datum/mutation/human/chameleon/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
/datum/mutation/human/chameleon/on_attack_hand(atom/target, proximity)
if(proximity) //stops tk from breaking chameleon
owner.alpha = CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY
return
+16 -18
View File
@@ -1,32 +1,30 @@
//Cold Resistance gives your entire body an orange halo, and makes you immune to the effects of vacuum and cold.
/datum/mutation/human/cold_resistance
name = "Cold Resistance"
/datum/mutation/human/space_adaptation
name = "Space Adaptation"
desc = "A strange mutation that renders the host immune to the vacuum if space. Will still need an oxygen supply."
quality = POSITIVE
get_chance = 25
lowest_value = 256 * 12
difficulty = 16
text_gain_indication = "<span class='notice'>Your body feels warm!</span>"
time_coeff = 5
instability = 30
/datum/mutation/human/cold_resistance/New()
/datum/mutation/human/space_adaptation/New()
..()
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER)
if(!(type in visual_indicators))
visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER))
/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
/datum/mutation/human/space_adaptation/get_visual_indicator()
return visual_indicators[type][1]
/datum/mutation/human/cold_resistance/on_acquiring(mob/living/carbon/human/owner)
/datum/mutation/human/space_adaptation/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.add_trait(TRAIT_RESISTCOLD, "cold_resistance")
owner.add_trait(TRAIT_RESISTLOWPRESSURE, "cold_resistance")
owner.add_trait(TRAIT_RESISTCOLD, "space_adaptation")
owner.add_trait(TRAIT_RESISTLOWPRESSURE, "space_adaptation")
/datum/mutation/human/cold_resistance/on_losing(mob/living/carbon/human/owner)
/datum/mutation/human/space_adaptation/on_losing(mob/living/carbon/human/owner)
if(..())
return
owner.remove_trait(TRAIT_RESISTCOLD, "cold_resistance")
owner.remove_trait(TRAIT_RESISTLOWPRESSURE, "cold_resistance")
owner.remove_trait(TRAIT_RESISTCOLD, "space_adaptation")
owner.remove_trait(TRAIT_RESISTLOWPRESSURE, "space_adaptation")
/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
if(owner.getFireLoss())
if(prob(1))
owner.heal_bodypart_damage(0,1) //Is this really needed?
+16
View File
@@ -0,0 +1,16 @@
/datum/generecipe
var/required = "" //it hurts so bad but initial is not compatible with lists
var/result = null
/proc/get_mixed_mutation(mutation1, mutation2)
if(!mutation1 || !mutation2)
return FALSE
if(mutation1 == mutation2) //this could otherwise be bad
return FALSE
for(var/A in GLOB.mutation_recipes)
if(findtext(A, "[mutation1]") && findtext(A, "[mutation2]"))
return GLOB.mutation_recipes[A]
/datum/generecipe/hulk
required = "/datum/mutation/human/strong; /datum/mutation/human/radioactive"
result = HULK
+7 -4
View File
@@ -1,12 +1,15 @@
//Hulk turns your skin green, and allows you to punch through walls.
/datum/mutation/human/hulk
name = "Hulk"
desc = "A poorly understood genome that causes the holder's muscles to expand, inhibit speech and gives the person a bad skin condition."
quality = POSITIVE
get_chance = 15
lowest_value = 256 * 12
locked = TRUE
difficulty = 16
text_gain_indication = "<span class='notice'>Your muscles hurt!</span>"
species_allowed = list("human") //no skeleton/lizard hulk
health_req = 25
instability = 40
locked = TRUE
/datum/mutation/human/hulk/on_acquiring(mob/living/carbon/human/owner)
if(..())
@@ -16,11 +19,11 @@
owner.update_body_parts()
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk)
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
/datum/mutation/human/hulk/on_attack_hand(atom/target, proximity)
if(proximity) //no telekinetic hulk attack
return target.attack_hulk(owner)
/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/hulk/on_life()
if(owner.health < 0)
on_losing(owner)
to_chat(owner, "<span class='danger'>You suddenly feel very weak.</span>")
+19
View File
@@ -0,0 +1,19 @@
/datum/mutation/human/radioactive
name = "Radioactivity"
desc = "A volatile mutation that causes the host to sent out deadly beta radiation. This affects both the hosts and their surroundings."
quality = NEGATIVE
text_gain_indication = "<span class='warning'>You can feel it in your bones!</span>"
time_coeff = 5
instability = 5
difficulty = 8
/datum/mutation/human/radioactive/on_life()
radiation_pulse(owner, 20)
/datum/mutation/human/radioactive/New()
..()
if(!(type in visual_indicators))
visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "radiation", -MUTATIONS_LAYER))
/datum/mutation/human/radioactive/get_visual_indicator()
return visual_indicators[type][1]
+10 -5
View File
@@ -1,6 +1,7 @@
//Nearsightedness restricts your vision by several tiles.
/datum/mutation/human/nearsight
name = "Near Sightness"
desc = "The holder of this mutation has poor eyesight."
quality = MINOR_NEGATIVE
text_gain_indication = "<span class='danger'>You can't see very well.</span>"
@@ -18,6 +19,7 @@
//Blind makes you blind. Who knew?
/datum/mutation/human/blind
name = "Blindness"
desc = "Renders the subject completely blind."
quality = NEGATIVE
text_gain_indication = "<span class='danger'>You can't seem to see anything.</span>"
@@ -35,11 +37,12 @@
//X-ray Vision lets you see through walls.
/datum/mutation/human/x_ray
name = "X Ray Vision"
desc = "A strange genome that allows the user to see between the spaces of walls." //actual x-ray would mean you'd constantly be blasting rads, wich might be fun for later //hmb
quality = POSITIVE
get_chance = 25
lowest_value = 256 * 12
difficulty = 18
text_gain_indication = "<span class='notice'>The walls suddenly disappear!</span>"
time_coeff = 2
instability = 25
/datum/mutation/human/x_ray/on_acquiring(mob/living/carbon/human/owner)
if(..())
@@ -58,8 +61,10 @@
//Laser Eyes lets you shoot lasers from your eyes!
/datum/mutation/human/laser_eyes
name = "Laser Eyes"
desc = "Reflects concentrated light back from the eyes."
quality = POSITIVE
dna_block = NON_SCANNABLE
locked = TRUE
difficulty = 16
text_gain_indication = "<span class='notice'>You feel pressure building up behind your eyes.</span>"
layer_used = FRONT_MUTATIONS_LAYER
limb_req = BODY_ZONE_HEAD
@@ -68,9 +73,9 @@
..()
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "lasereyes", -FRONT_MUTATIONS_LAYER)
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
/datum/mutation/human/laser_eyes/get_visual_indicator()
return visual_indicators[1]
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target, mouseparams)
/datum/mutation/human/laser_eyes/on_ranged_attack(atom/target, mouseparams)
if(owner.a_intent == INTENT_HARM)
owner.LaserEyes(target, mouseparams)
+13 -8
View File
@@ -3,16 +3,18 @@
/datum/mutation/human/nervousness
name = "Nervousness"
desc = "Causes the holder to stutter."
quality = MINOR_NEGATIVE
text_gain_indication = "<span class='danger'>You feel nervous.</span>"
/datum/mutation/human/nervousness/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/nervousness/on_life()
if(prob(10))
owner.stuttering = max(10, owner.stuttering)
/datum/mutation/human/wacky
name = "Wacky"
desc = "<span class='sans'>Unknown.</span>"
quality = MINOR_NEGATIVE
text_gain_indication = "<span class='sans'>You feel an off sensation in your voicebox.</span>"
text_lose_indication = "<span class='notice'>The off sensation passes.</span>"
@@ -23,6 +25,7 @@
/datum/mutation/human/mute
name = "Mute"
desc = "Completely inhibits the vocal section of the brain."
quality = NEGATIVE
text_gain_indication = "<span class='danger'>You feel unable to express yourself at all.</span>"
text_lose_indication = "<span class='danger'>You feel able to speak freely again.</span>"
@@ -40,8 +43,8 @@
/datum/mutation/human/smile
name = "Smile"
desc = "Causes the user to be in constant mania."
quality = MINOR_NEGATIVE
dna_block = NON_SCANNABLE
text_gain_indication = "<span class='notice'>You feel so happy. Nothing can be wrong with anything. :)</span>"
text_lose_indication = "<span class='notice'>Everything is terrible again. :(</span>"
@@ -97,8 +100,8 @@
/datum/mutation/human/unintelligible
name = "Unintelligible"
desc = "Partially inhibits the vocal center of the brain, severely distorting speech."
quality = NEGATIVE
dna_block = NON_SCANNABLE
text_gain_indication = "<span class='danger'>You can't seem to form any coherent thoughts!</span>"
text_lose_indication = "<span class='danger'>Your mind feels more clear.</span>"
@@ -130,8 +133,8 @@
/datum/mutation/human/swedish
name = "Swedish"
desc = "A horrible mutation originating from the distant past. Thought to be eradicated after the incident in 2037."
quality = MINOR_NEGATIVE
dna_block = NON_SCANNABLE
text_gain_indication = "<span class='notice'>You feel Swedish, however that works.</span>"
text_lose_indication = "<span class='notice'>The feeling of Swedishness passes.</span>"
@@ -149,8 +152,8 @@
/datum/mutation/human/chav
name = "Chav"
desc = "Unknown"
quality = MINOR_NEGATIVE
dna_block = NON_SCANNABLE
text_gain_indication = "<span class='notice'>Ye feel like a reet prat like, innit?</span>"
text_lose_indication = "<span class='notice'>You no longer feel like being rude and sassy.</span>"
@@ -183,12 +186,13 @@
/datum/mutation/human/elvis
name = "Elvis"
desc = "A terrifying mutation named after its 'patient-zero'."
quality = MINOR_NEGATIVE
dna_block = NON_SCANNABLE
locked = TRUE
text_gain_indication = "<span class='notice'>You feel pretty good, honeydoll.</span>"
text_lose_indication = "<span class='notice'>You feel a little less conversation would be great.</span>"
/datum/mutation/human/elvis/on_life(mob/living/carbon/human/owner)
/datum/mutation/human/elvis/on_life()
switch(pick(1,2))
if(1)
if(prob(15))
@@ -216,8 +220,9 @@
/datum/mutation/human/stoner
name = "Stoner"
desc = "A common mutation that severely decreases intelligence."
quality = NEGATIVE
dna_block = NON_SCANNABLE
locked = TRUE
text_gain_indication = "<span class='notice'>You feel...totally chill, man!</span>"
text_lose_indication = "<span class='notice'>You feel like you have a better sense of time.</span>"
+8 -6
View File
@@ -1,18 +1,20 @@
//Telekinesis lets you interact with objects from range, and gives you a light blue halo around your head.
/datum/mutation/human/telekinesis
name = "Telekinesis"
desc = "A strange mutation that allows the holder to interact with objects through thought."
quality = POSITIVE
get_chance = 20
lowest_value = 256 * 12
difficulty = 18
text_gain_indication = "<span class='notice'>You feel smarter!</span>"
limb_req = BODY_ZONE_HEAD
instability = 30
/datum/mutation/human/telekinesis/New()
..()
visual_indicators |= mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER)
if(!(type in visual_indicators))
visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "telekinesishead", -MUTATIONS_LAYER))
/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
/datum/mutation/human/telekinesis/get_visual_indicator()
return visual_indicators[type][1]
/datum/mutation/human/telekinesis/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
/datum/mutation/human/telekinesis/on_ranged_attack(atom/target)
target.attack_tk(owner)
+13
View File
@@ -541,3 +541,16 @@
else if(isanimal(L))
var/mob/living/simple_animal/SM = L
SM.adjustHealth(-3.5, forced = TRUE)
/datum/status_effect/good_music
id = "Good Music"
alert_type = null
duration = 6 SECONDS
tick_interval = 1 SECONDS
status_type = STATUS_EFFECT_REFRESH
/datum/status_effect/good_music/tick()
owner.dizziness = max(0, owner.dizziness - 2)
owner.jitteriness = max(0, owner.jitteriness - 2)
owner.confused = max(0, owner.confused - 1)
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "goodmusic", /datum/mood_event/goodmusic)
+7
View File
@@ -88,6 +88,7 @@
status_type = STATUS_EFFECT_REPLACE
tick_interval = 1
duration = 100
alert_type = null
/datum/status_effect/pacify/on_creation(mob/living/new_owner, set_duration)
if(isnum(set_duration))
@@ -553,6 +554,12 @@
tick_interval = 10
examine_text = "<span class='warning'>SUBJECTPRONOUN seems slow and unfocused.</span>"
var/stun = TRUE
alert_type = /obj/screen/alert/status_effect/trance
/obj/screen/alert/status_effect/trance
name = "Trance"
desc = "Everything feels so distant, and you can feel your thoughts forming loops inside your head..."
icon_state = "high"
/datum/status_effect/trance/tick()
if(stun)
@@ -63,6 +63,12 @@
owner = null
qdel(src)
/datum/status_effect/proc/refresh()
var/original_duration = initial(duration)
if(original_duration == -1)
return
duration = world.time + original_duration
//clickdelay/nextmove modifiers!
/datum/status_effect/proc/nextmove_modifier()
return 1
@@ -91,6 +97,9 @@
if(S.id == initial(S1.id) && S.status_type)
if(S.status_type == STATUS_EFFECT_REPLACE)
S.be_replaced()
else if(S.status_type == STATUS_EFFECT_REFRESH)
S.refresh()
return
else
return
var/list/arguments = args.Copy()
-3
View File
@@ -71,9 +71,6 @@
var/obj/item/choice_beacon/music/B = new(get_turf(H))
H.put_in_hands(B)
H.equip_to_slot(B, SLOT_IN_BACKPACK)
var/obj/item/musicaltuner/musicaltuner = new(get_turf(H))
H.put_in_hands(musicaltuner)
H.equip_to_slot(musicaltuner, SLOT_IN_BACKPACK)
H.regenerate_icons()
/datum/quirk/night_vision
+5 -2
View File
@@ -159,8 +159,11 @@
SEND_SIGNAL(H.back, COMSIG_TRY_STORAGE_SHOW, H)
to_chat(quirk_holder, "<span class='boldnotice'>There is a precious family [heirloom.name] [where], passed down from generation to generation. Keep it safe!</span>")
var/list/family_name = splittext(quirk_holder.real_name, " ")
heirloom.name = "\improper [family_name[family_name.len]] family [heirloom.name]"
var/list/names = splittext(quirk_holder.real_name, " ")
var/family_name = names[names.len]
heirloom.AddComponent(/datum/component/heirloom, quirk_holder.mind, family_name)
/datum/quirk/family_heirloom/on_process()
if(heirloom in quirk_holder.GetAllContents())
+22
View File
@@ -10,6 +10,28 @@
lose_text = "<span class='notice'>You can taste again!</span>"
medical_record_text = "Patient suffers from ageusia and is incapable of tasting food or reagents."
/datum/quirk/vegetarian
name = "Vegetarian"
desc = "You find the idea of eating meat morally and physically repulsive."
value = 0
gain_text = "<span class='notice'>You feel repulsion at the idea of eating meat.</span>"
lose_text = "<span class='notice'>You feel like eating meat isn't that bad.</span>"
/datum/quirk/vegetarian/add()
var/mob/living/carbon/human/H = quirk_holder
var/datum/species/species = H.dna.species
species.liked_food &= ~MEAT
species.disliked_food |= MEAT
/datum/quirk/vegetarian/remove()
var/mob/living/carbon/human/H = quirk_holder
if(H)
var/datum/species/species = H.dna.species
if(initial(species.liked_food) & MEAT)
species.liked_food |= MEAT
if(!initial(species.disliked_food) & MEAT)
species.disliked_food &= ~MEAT
/datum/quirk/pineapple_liker
name = "Ananas Affinity"
desc = "You find yourself greatly enjoying fruits of the ananas genus. You can't seem to ever get enough of their sweet goodness!"
@@ -38,9 +38,9 @@
H.randmuti()
if(prob(50))
if(prob(90))
H.randmutb()
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
else
H.randmutg()
H.easy_randmut(POSITIVE)
H.domutcheck()
L.rad_act(20)
+4
View File
@@ -379,6 +379,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Kitchen"
icon_state = "kitchen"
/area/crew_quarters/kitchen/coldroom
name = "Kitchen Cold Room"
icon_state = "kitchen_cold"
/area/crew_quarters/bar
name = "Bar"
icon_state = "bar"
+7
View File
@@ -186,6 +186,10 @@
else
M.forceMove(src)
//common name
/atom/proc/update_multiz(prune_on_fail = FALSE)
return FALSE
/atom/proc/assume_air(datum/gas_mixture/giver)
qdel(giver)
return null
@@ -726,3 +730,6 @@ Proc for attack log creation, because really why not
/atom/movable/proc/get_filter(name)
if(filter_data && filter_data[name])
return filters[filter_data.Find(name)]
/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1)
return FALSE
+45
View File
@@ -36,6 +36,51 @@
var/datum/component/orbiter/orbiting
var/can_be_z_moved = TRUE
var/zfalling = FALSE
/atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction)
if(!direction)
direction = DOWN
if(!source)
source = get_turf(src)
if(!source)
return FALSE
if(!target)
target = get_step_multiz(source, direction)
if(!target)
return FALSE
return !(movement_type & FLYING) && has_gravity(source) && !throwing
/atom/movable/proc/onZImpact(turf/T, levels)
var/atom/highest = T
for(var/i in T.contents)
var/atom/A = i
if(!A.density)
continue
if(isobj(A) || ismob(A))
if(A.layer > highest.layer)
highest = A
INVOKE_ASYNC(src, .proc/SpinAnimation, 5, 2)
throw_impact(highest)
return TRUE
//For physical constraints to travelling up/down.
/atom/movable/proc/can_zTravel(turf/destination, direction)
var/turf/T = get_turf(src)
if(!T)
return FALSE
if(!direction)
if(!destination)
return FALSE
direction = get_dir(T, destination)
if(direction != UP && direction != DOWN)
return FALSE
if(!destination)
destination = get_step_multiz(src, direction)
if(!destination)
return FALSE
return T.zPassOut(src, direction, destination) && destination.zPassIn(src, direction, T)
/atom/movable/vv_edit_var(var_name, var_value)
var/static/list/banned_edits = list("step_x", "step_y", "step_size")
var/static/list/careful_edits = list("bound_x", "bound_y", "bound_width", "bound_height")
+6 -4
View File
@@ -88,6 +88,8 @@
name = "cloning data disk"
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
var/list/fields = list()
var/list/mutations = list()
var/max_mutations = 6
var/read_only = 0 //Well,it's still a floppy disk
//Disk stuff.
@@ -135,7 +137,7 @@
return examine(user)
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, se, mindref, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance)
/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks, datum/bank_account/insurance)
if(panel_open)
return FALSE
if(mess || attempting)
@@ -170,18 +172,18 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
H.hardset_dna(ui, mutation_index, H.real_name, null, mrace, features)
if(efficiency > 2)
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations)
H.dna.remove_mutation_group(unclean_mutations)
if(efficiency > 5 && prob(20))
H.randmutvg()
H.easy_randmut(POSITIVE)
if(efficiency < 3)
if(prob(50))
H.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_BASIC)
if(prob(50))
var/mob/M = H.randmutb()
var/mob/M = H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
if(ismob(M))
H = M
+2 -6
View File
@@ -52,7 +52,6 @@
else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
. = pod
/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
src.scanner = findscanner()
if(findfirstcloner && !LAZYLEN(pods))
@@ -125,7 +124,6 @@
dat += "<h3>Cloning Pod Status</h3>"
dat += "<div class='statusDisplay'>[temp]&nbsp;</div>"
// Modules
if (isnull(src.scanner) || !LAZYLEN(pods))
dat += "<h3>Modules</h3>"
@@ -159,7 +157,6 @@
else
dat += "<span class='linkOff'>Start Scan</span>"
var/datum/browser/popup = new(user, "cloning", "Cloning System Control")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
@@ -201,7 +198,6 @@
src.updateUsrDialog()
playsound(src, "terminal_type", 25, 0)
src.add_fingerprint(usr)
src.updateUsrDialog()
return
@@ -254,7 +250,7 @@
var/mind
if(mob_occupant.mind)
mind = "[REF(mob_occupant.mind)]"
mind = "[REF(mob_occupant.mind)]"
var/quirks = list()
for(var/V in mob_occupant.roundstart_quirks)
@@ -275,7 +271,7 @@
else if(pod.occupant)
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else if(pod.growclone(mob_occupant.ckey, mob_occupant.real_name, dna.uni_identity, dna.struc_enzymes, mind, mrace, dna.features, mob_occupant.faction, quirks, has_bank_account))
else if(pod.growclone(mob_occupant.ckey, mob_occupant.real_name, dna.uni_identity, dna.mutation_index, mind, mrace, dna.features, mob_occupant.faction, quirks, has_bank_account))
temp = "[mob_occupant.real_name] => <font class='good'>Cloning cycle in progress...</font>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
else
+410 -122
View File
@@ -1,14 +1,16 @@
#define INJECTOR_TIMEOUT 100
#define REJUVENATORS_INJECT 15
#define REJUVENATORS_MAX 90
#define NUMBER_OF_BUFFERS 3
#define SCRAMBLE_TIMEOUT 600
#define JOKER_TIMEOUT 12000 //20 minutes
#define JOKER_UPGRADE 1800
#define RADIATION_STRENGTH_MAX 15
#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has a more range
#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has more range
#define RADIATION_DURATION_MAX 30
#define RADIATION_ACCURACY_MULTIPLIER 3 //larger is less accurate
#define RADIATION_IRRADIATION_MULTIPLIER 1 //multiplier for how much radiation a test subject receives
#define SCANNER_ACTION_SE 1
@@ -23,21 +25,30 @@
icon_keyboard = "med_key"
density = TRUE
circuit = /obj/item/circuitboard/computer/scan_consolenew
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 400
light_color = LIGHT_COLOR_BLUE
var/datum/techweb/stored_research
var/max_storage = 6
var/combine
var/radduration = 2
var/radstrength = 1
var/list/buffer[NUMBER_OF_BUFFERS]
var/list/stored_mutations = list()
var/injectorready = 0 //world timer cooldown var
var/jokerready = 0
var/scrambleready = 0
var/current_screen = "mainmenu"
var/current_mutation //what block are we inspecting? only used when screen = "info"
var/current_storage //what storage block are we looking at?
var/obj/machinery/dna_scannernew/connected = null
var/obj/item/disk/data/diskette = null
var/list/delayed_action = null
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 400
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES
@@ -58,12 +69,26 @@
if(!isnull(connected))
break
injectorready = world.time + INJECTOR_TIMEOUT
scrambleready = world.time + SCRAMBLE_TIMEOUT
jokerready = world.time + JOKER_TIMEOUT
stored_research = SSresearch.science_tech
/obj/machinery/computer/scan_consolenew/examine(mob/user)
..()
if(jokerready < world.time)
to_chat(user, "<span class='notice'>JOKER algorithm available.</span>")
else
to_chat(user, "<span class='notice'>JOKER algorithm available in about [round(0.00166666667 * (jokerready - world.time))] minutes.")
/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, last_change)
. = ..()
if(!user)
return
var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 800, 630) // Set up the popup browser window
if(user.client)
var/datum/asset/simple/assets = get_asset_datum(/datum/asset/simple/genetics)
assets.send(user.client)
if(!(in_range(src, user) || issilicon(user)))
popup.close()
return
@@ -88,8 +113,6 @@
occupant_status += "</div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [viable_occupant.health]%;' class='progressFill good'></div></div><div class='statusValue'>[viable_occupant.health] %</div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Radiation Level:</div><div class='progressBar'><div style='width: [viable_occupant.radiation/(RAD_MOB_SAFE/100)]%;' class='progressFill bad'></div></div><div class='statusValue'>[viable_occupant.radiation/(RAD_MOB_SAFE/100)] %</div></div>"
var/rejuvenators = viable_occupant.reagents.get_reagent_amount("potass_iodide")
occupant_status += "<div class='line'><div class='statusLabel'>Rejuvenators:</div><div class='progressBar'><div style='width: [round((rejuvenators / REJUVENATORS_MAX) * 100)]%;' class='progressFill highlight'></div></div><div class='statusValue'>[rejuvenators] units</div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Unique Enzymes :</div><div class='statusValue'><span class='highlight'>[viable_occupant.dna.unique_enzymes]</span></div></div>"
occupant_status += "<div class='line'><div class='statusLabel'>Last Operation:</div><div class='statusValue'>[last_change ? last_change : "----"]</div></div>"
else
@@ -147,28 +170,53 @@
buttons += "<a href='?src=[REF(src)];task=togglelock;'>[connected.locked ? "Unlock" : "Lock"] Scanner</a>"
else
buttons += "<span class='linkOff'>Open Scanner</span> <span class='linkOff'>Lock Scanner</span>"
if(viable_occupant)
buttons += "<a href='?src=[REF(src)];task=rejuv'>Inject Rejuvenators</a>"
if(viable_occupant && (scrambleready < world.time))
buttons += "<a href='?src=[REF(src)];task=scramble'>Scramble DNA</a>"
else
buttons += "<span class='linkOff'>Inject Rejuvenators</span>"
buttons += "<span class='linkOff'>Scramble DNA</span>"
if(diskette)
buttons += "<a href='?src=[REF(src)];task=ejectdisk'>Eject Disk</a>"
buttons += "<a href='?src=[REF(src)];task=screen;text=disk;'>Disk</a>"
else
buttons += "<span class='linkOff'>Eject Disk</span>"
if(current_screen == "buffer")
buttons += "<a href='?src=[REF(src)];task=screen;text=mainmenu;'>Radiation Emitter Menu</a>"
buttons += "<span class='linkOff'>Disk</span>"
if(current_screen == "mutations")
buttons += "<span class='linkOff'>Mutations</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=buffer;'>Buffer Menu</a>"
buttons += "<a href='?src=[REF(src)];task=screen;text=mutations;'>Mutations</a>"
if((current_screen == "mainmenu") || !current_screen)
buttons += "<span class='linkOff'>Genetic Sequencer</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=mainmenu;'>Genetic Sequencer</a>"
if(current_screen == "ui")
buttons += "<span class='linkOff'>Unique Identifiers</span>"
else
buttons += "<a href='?src=[REF(src)];task=screen;text=ui;'>Unique Identifiers</a>"
switch(current_screen)
if("working")
temp_html += status
temp_html += "<h1>System Busy</h1>"
temp_html += "Working ... Please wait ([DisplayTimeText(radduration*10)])"
if("buffer")
if("ui")
temp_html += status
temp_html += buttons
temp_html += "<h1>Buffer Menu</h1>"
temp_html += "<h1>Unique Identifiers</h1>"
temp_html += "<a href='?src=[REF(src)];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=[REF(src)];task=setstrength;'>Output Level</a> <a href='?src=[REF(src)];task=setstrength;num=[radstrength+1];'>++</a>"
temp_html += "<br><a href='?src=[REF(src)];task=setduration;num=[radduration-1];'>--</a> <a href='?src=[REF(src)];task=setduration;'>Pulse Duration</a> <a href='?src=[REF(src)];task=setduration;num=[radduration+1];'>++</a>"
temp_html += "<h3>Irradiate Subject</h3>"
temp_html += "<div class='line'><div class='statusLabel'>Unique Identifier:</div><div class='statusValue'><div class='clearBoth'>"
var/max_line_len = 7*DNA_BLOCK_SIZE
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/len = length(viable_occupant.dna.uni_identity)
for(var/i=1, i<=len, i++)
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[i];'>[copytext(viable_occupant.dna.uni_identity,i,i+1)]</a>"
if ((i % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
else
temp_html += "---------"
temp_html += "</div></div><h1>Buffer Menu</h1>"
if(istype(buffer))
for(var/i=1, i<=buffer.len, i++)
@@ -188,7 +236,6 @@
temp_html += "<span class='linkOff'>Save to Disk</span>"
else
var/ui = buffer_slot["UI"]
var/se = buffer_slot["SE"]
var/ue = buffer_slot["UE"]
var/name = buffer_slot["name"]
var/label = buffer_slot["label"]
@@ -234,19 +281,6 @@
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=mixed'>UI+UE Injector</a>"
else
temp_html += "<span class='linkOff'>UI+UE Injector</span>"
if(se)
temp_html += "<br>\tSE: [se] "
if(viable_occupant)
temp_html += "<a href='?src=[REF(src)];task=transferbuffer;num=[i];text=se'>Occupant</a>"
else
temp_html += "<span class='linkOff'>Occupant</span>"
temp_html += "<a href='?src=[REF(src)];task=setdelayed;num=[i];delayaction=[SCANNER_ACTION_SE]'>Occupant:Delayed</a>"
if(injectorready < world.time )
temp_html += "<a href='?src=[REF(src)];task=injector;num=[i];text=se'>Injector</a>"
else
temp_html += "<span class='linkOff'>Injector</span>"
else
temp_html += "<br>\tSE: No Data"
if(viable_occupant)
temp_html += "<br><a href='?src=[REF(src)];task=setbuffer;num=[i];'>Save to Buffer</a>"
else
@@ -260,48 +294,180 @@
temp_html += "<a href='?src=[REF(src)];task=savedisk;num=[i];'>Save to Disk</a>"
else
temp_html += "<span class='linkOff'>Save to Disk</span>"
if("disk")
temp_html += status
temp_html += buttons
if(diskette)
temp_html += "<h3>[diskette.name]</h3><br>"
temp_html += "<a href='?src=[REF(src)];task=ejectdisk'>Eject Disk</a><br>"
if(LAZYLEN(diskette.mutations))
temp_html += "<table>"
for(var/datum/mutation/human/A in diskette.mutations)
temp_html += "<tr><td><span class='linkOff'>[A.name]</span></td>"
temp_html += "<td><a href='?src=[REF(src)];task=deletediskmut;num=[diskette.mutations.Find(A)];'>Delete</a></td>"
if(LAZYLEN(stored_mutations) < max_storage)
temp_html += "<td><a href='?src=[REF(src)];task=importdiskmut;num=[diskette.mutations.Find(A)];'>Import</a></td>"
else
temp_html += "<td><td><span class='linkOff'>Import</span></td>"
temp_html += "</tr>"
temp_html += "</table>"
else
temp_html += "<br>Load diskette to start ----------"
if("info")
if(LAZYLEN(stored_mutations))
if(LAZYLEN(stored_mutations) >= current_storage)
var/datum/mutation/human/HM = stored_mutations[current_storage]
if(HM)
temp_html += display_sequence(HM.type, current_storage)
else
current_screen = "mainmenu"
if("mutations")
temp_html += status
temp_html += buttons
temp_html += "<h3>Mutation Storage:<br></h3>"
temp_html += "<table>"
for(var/datum/mutation/human/HM in stored_mutations)
var/i = stored_mutations.Find(HM)
temp_html += "<tr><td><a href='?src=[REF(src)];task=inspectstorage;num=[i]'>[HM.name]</a></td>"
temp_html += "<td><a href='?src=[REF(src)];task=exportdiskmut;path=[HM.type]'>Export</a></td>"
temp_html += "<td><a href='?src=[REF(src)];task=deletemut;num=[i]'>Delete</a></td>"
if(combine == HM.type)
temp_html += "<td><span class='linkOff'>Combine</span></td></tr>"
else
temp_html += "<td><a href='?src=[REF(src)];task=combine;num=[i]'>Combine</a></td></tr>"
temp_html += "</table>"
else
temp_html += status
temp_html += buttons
temp_html += "<h1>Radiation Emitter Menu</h1>"
temp_html += "<a href='?src=[REF(src)];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=[REF(src)];task=setstrength;'>Output Level</a> <a href='?src=[REF(src)];task=setstrength;num=[radstrength+1];'>++</a>"
temp_html += "<br><a href='?src=[REF(src)];task=setduration;num=[radduration-1];'>--</a> <a href='?src=[REF(src)];task=setduration;'>Pulse Duration</a> <a href='?src=[REF(src)];task=setduration;num=[radduration+1];'>++</a>"
temp_html += "<h3>Irradiate Subject</h3>"
temp_html += "<div class='line'><div class='statusLabel'>Unique Identifier:</div><div class='statusValue'><div class='clearBoth'>"
var/max_line_len = 7*DNA_BLOCK_SIZE
temp_html += "<div class='line'><div class='statusLabel'>Genetic Sequence:</div><br>"
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/len = length(viable_occupant.dna.uni_identity)
for(var/i=1, i<=len, i++)
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[i];'>[copytext(viable_occupant.dna.uni_identity,i,i+1)]</a>"
if ((i % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
if(viable_occupant)
for(var/A in get_mutation_list())
temp_html += display_inactive_sequence(A)
temp_html += "<br>"
else
temp_html += "----"
if(viable_occupant && (current_mutation in get_mutation_list(viable_occupant)))
temp_html += display_sequence(current_mutation)
temp_html += "</div><br>"
else
temp_html += "----"
temp_html += "</div></div></div><br>"
temp_html += "<br><div class='line'><div class='statusLabel'>Structural Enzymes:</div><div class='statusValue'><div class='clearBoth'>"
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/len = length(viable_occupant.dna.struc_enzymes)
for(var/i=1, i<=len, i++)
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulsese;num=[i];'>[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]</a>"
if ((i % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
else
temp_html += "----"
temp_html += "</div></div></div>"
temp_html += "----------"
popup.set_content(temp_html.Join())
popup.open()
/obj/machinery/computer/scan_consolenew/proc/display_inactive_sequence(mutation)
var/temp_html = ""
var/class = "unselected"
var/mob/living/carbon/viable_occupant = get_viable_occupant()
if(!viable_occupant)
return
var/location = viable_occupant.dna.mutation_index.Find(mutation) //We do this because we dont want people using sysexp or similair tools to just read the mutations.
if(!location) //Do this only when needed, dont make a list with mutations for every iteration if you dont need to
var/list/mutations = get_mutation_list(TRUE)
if(mutation in mutations)
location = mutations.Find(mutation)
if(mutation == current_mutation)
class = "selected"
if(location > DNA_MUTATION_BLOCKS)
temp_html += "<a class='clean' href='?src=[REF(src)];task=inspect;num=[location];'><img class='[class]' src='dna_extra.png' width = '65' alt='Extra Mutation'></a>"
else if(mutation in stored_research.discovered_mutations)
temp_html += "<a class='clean' href='?src=[REF(src)];task=inspect;num=[location];'><img class='[class]' src='dna_discovered.png' width = '65' alt='Discovered Mutation'></a>"
else
temp_html += "<a class='clean' clean href='?src=[REF(src)];task=inspect;num=[location];'><img class='[class]' src='dna_undiscovered.png' width = '65' alt=Undiscovered Mutation'></a>"
return temp_html
/obj/machinery/computer/scan_consolenew/proc/display_sequence(mutation, storage_slot) //Storage slot is for when viewing from the stored mutations
var/temp_html = ""
if(!mutation)
temp_html += "ERR-"
return
var/mut_name = "Unknown gene"
var/mut_desc = "No information available."
var/alias
var/discovered = FALSE
var/active = FALSE
var/scrambled = FALSE
var/mob/living/carbon/viable_occupant = get_viable_occupant()
if(viable_occupant)
var/datum/mutation/human/HM = viable_occupant.dna.get_mutation(mutation)
if(HM)
if(HM.scrambled)
scrambled = TRUE
active = TRUE
var/datum/mutation/human/A = get_initialized_mutation(mutation)
alias = A.alias
if(active && !scrambled)
discover(mutation)
if(stored_research && (mutation in stored_research.discovered_mutations))
mut_name = A.name
mut_desc = A.desc
discovered = TRUE
var/extra
if(viable_occupant && !(storage_slot || mutation_in_sequence(mutation, viable_occupant.dna)))
extra = TRUE
var/datum/mutation/human/HM = get_initialized_mutation(mutation)
if(discovered && !scrambled)
var/mutcolor
switch(A.quality)
if(POSITIVE)
mutcolor = "good"
if(MINOR_NEGATIVE)
mutcolor = "average"
if(NEGATIVE)
mutcolor = "bad"
temp_html += "<div class='statusDisplay'><div class='statusLine'><span class='[mutcolor]'><b>[mut_name]</b></span><small> ([alias])</small><br>"
else
temp_html += "<div class='statusDisplay'><div class='statusLine'><b>[alias]</b><br>"
temp_html += "<div class='statusLine'>[mut_desc]<br></div>"
temp_html += "<div class='statusLine'>Sequence:<br><br></div>"
if(!scrambled)
for(var/block in 1 to HM.blocks)
var/whole_sequence = get_valid_gene_string(mutation)
var/sequence = copytext(whole_sequence, 1+(block-1)*(DNA_SEQUENCE_LENGTH*2),(DNA_SEQUENCE_LENGTH*2*block+1))
temp_html += "<div class='statusLine'><table class='statusDisplay'><tr>"
for(var/i in 1 to DNA_SEQUENCE_LENGTH)
var/num = 1+(i-1)*2
var/genenum = num+(DNA_SEQUENCE_LENGTH*2*(block-1))
temp_html += "<td><div class='statusLine'><span class='dnaBlockNumber'><a href='?src=[REF(src)];task=pulsegene;num=[genenum];path=[mutation];'>[sequence[num]]</span></a></div></td>"
temp_html += "</tr><tr>"
for(var/i in 1 to DNA_SEQUENCE_LENGTH)
temp_html += "<td><div class='statusLine'>|</div></td>"
temp_html += "</tr><tr>"
for(var/i in 1 to DNA_SEQUENCE_LENGTH)
var/num = i*2
var/genenum = num+(DNA_SEQUENCE_LENGTH*2*(block-1))
temp_html += "<td><div class='statusLine'><span class='dnaBlockNumber'><a href='?src=[REF(src)];task=pulsegene;num=[genenum];path=[mutation];'>[sequence[num]]</span></a></div></td>"
temp_html += "</tr></table></div>"
temp_html += "<br><br><br><br><br>"
else
temp_html = "<div class='statusLine'>Sequence unreadable due to unpredictable mutation.</div>"
if((active || storage_slot) && (injectorready < world.time) && !scrambled)
temp_html += "<a href='?src=[REF(src)];task=activator;path=[mutation];slot=[storage_slot];'>Print Activator</a>"
temp_html += "<a href='?src=[REF(src)];task=mutator;path=[mutation];slot;=[storage_slot];'>Print Mutator</a>"
else
temp_html += "<span class='linkOff'>Print Activator</span>"
temp_html += "<span class='linkOff'>Print Mutator</span>"
temp_html += "<br><div class='statusLine'>"
if(storage_slot)
temp_html += "<a href='?src=[REF(src)];task=deletemut;num=[storage_slot];'>Delete</a>"
if((LAZYLEN(stored_mutations) < max_storage) && diskette && !diskette.read_only)
temp_html += "<a href='?src=[REF(src)];task=exportdiskmut;path=[mutation];'>Export</a>"
else
temp_html += "<span class='linkOff'>Export</span>"
temp_html += "<a href='?src=[REF(src)];task=screen;text=mutations;'>Back</a>"
else if(active && !scrambled)
temp_html += "<a href='?src=[REF(src)];task=savemut;path=[mutation];'>Store</a>"
if(extra || scrambled)
temp_html += "<a href='?src=[REF(src)];task=nullify;'>Nullify</a>"
else
temp_html += "<span class='linkOff'>Nullify</span>"
temp_html += "</div></div>"
return temp_html
/obj/machinery/computer/scan_consolenew/Topic(href, href_list)
if(..())
@@ -340,11 +506,14 @@
radstrength = WRAP(num, 1, RADIATION_STRENGTH_MAX+1)
if("screen")
current_screen = href_list["text"]
if("rejuv")
if(viable_occupant && viable_occupant.reagents)
var/potassiodide_amount = viable_occupant.reagents.get_reagent_amount("potass_iodide")
var/can_add = max(min(REJUVENATORS_MAX - potassiodide_amount, REJUVENATORS_INJECT), 0)
viable_occupant.reagents.add_reagent("potass_iodide", can_add)
if("scramble")
if(viable_occupant && (scrambleready < world.time))
viable_occupant.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA))
viable_occupant.dna.generate_dna_blocks()
scrambleready = world.time + SCRAMBLE_TIMEOUT
to_chat(usr,"<span class'notice'>DNA scrambled.</span>")
viable_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER*50/(connected.damage_coeff ** 2)
if("setbufferlabel")
var/text = sanitize(input(usr, "Input a new label:", "Input a Text", null) as text|null)
if(num && text)
@@ -358,7 +527,6 @@
buffer[num] = list(
"label"="Buffer[num]:[viable_occupant.real_name]",
"UI"=viable_occupant.dna.uni_identity,
"SE"=viable_occupant.dna.struc_enzymes,
"UE"=viable_occupant.dna.unique_enzymes,
"name"=viable_occupant.real_name,
"blood_type"=viable_occupant.dna.blood_type
@@ -372,8 +540,6 @@
if("transferbuffer")
if(num && viable_occupant)
switch(href_list["text"]) //Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove
if("se")
apply_buffer(SCANNER_ACTION_SE,num)
if("ui")
apply_buffer(SCANNER_ACTION_UI,num)
if("ue")
@@ -387,28 +553,6 @@
if(istype(buffer_slot))
var/obj/item/dnainjector/timed/I
switch(href_list["text"])
if("se")
if(buffer_slot["SE"])
I = new /obj/item/dnainjector/timed(loc)
var/powers = 0
for(var/datum/mutation/human/HM in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations)
if(HM.check_block_string(buffer_slot["SE"]))
I.add_mutations.Add(HM)
if(HM in GLOB.good_mutations)
powers += 1
if(HM in GLOB.bad_mutations + GLOB.not_good_mutations)
powers -= 1 //To prevent just unlocking everything to get all powers to a syringe for max tech
else
I.remove_mutations.Add(HM)
var/time_coeff
for(var/datum/mutation/human/HM in I.add_mutations)
if(!time_coeff)
time_coeff = HM.time_coeff
continue
time_coeff = min(time_coeff,HM.time_coeff)
if(connected)
I.duration = I.duration * time_coeff * connected.damage_coeff
I.damage_coeff = connected.damage_coeff
if("ui")
if(buffer_slot["UI"])
I = new /obj/item/dnainjector/timed(loc)
@@ -447,7 +591,7 @@
if("setdelayed")
if(num)
delayed_action = list("action"=text2num(href_list["delayaction"]),"buffer"=num)
if("pulseui","pulsese")
if("pulseui")
if(num && viable_occupant && connected)
radduration = WRAP(radduration, 1, RADIATION_DURATION_MAX+1)
radstrength = WRAP(radstrength, 1, RADIATION_STRENGTH_MAX+1)
@@ -459,7 +603,7 @@
ui_interact(usr)
sleep(radduration*10)
current_screen = "mainmenu"
current_screen = "ui"
if(viable_occupant && connected && connected.occupant==viable_occupant)
viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation
@@ -480,35 +624,146 @@
viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0)
viable_occupant.updateappearance(mutations_overlay_update=1)
if("pulsese")
var/len = length(viable_occupant.dna.struc_enzymes)
num = WRAP(num, 1, len+1)
num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len)
var/block = round((num-1)/DNA_BLOCK_SIZE)+1
var/subblock = num - block*DNA_BLOCK_SIZE
last_change = "SE #[block]-[subblock]; "
var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1)
last_change += "[hex]"
hex = scramble(hex, radstrength, radduration)
last_change += "->[hex]"
viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0)
viable_occupant.domutcheck()
else
current_screen = "mainmenu"
if(connected)
connected.locked = locked_state
if("inspect")
if(viable_occupant)
var/list/mutations = get_mutation_list(TRUE)
if(current_mutation == mutations[num])
current_mutation = null
else
current_mutation = mutations[num]
if("inspectstorage")
current_storage = num
current_screen = "info"
if("savemut")
if(viable_occupant)
var/succes
if(LAZYLEN(stored_mutations) < max_storage)
var/mutation = text2path(href_list["path"])
if(ispath(mutation, /datum/mutation/human)) //sanity checks
var/datum/mutation/human/HM = viable_occupant.dna.get_mutation(mutation)
if(HM)
var/datum/mutation/human/A = new HM.type()
A.copy_mutation(HM)
succes = TRUE
stored_mutations[A] = get_sequence(mutation) //We only store active mutations and all active mutations have the full sequence.
to_chat(usr,"<span class='notice'>Mutation succesfully stored.</span>")
if(!succes) //we can exactly return here
to_chat(usr,"<span class='warning'>Mutation storage is full.</span>")
if("deletemut")
var/datum/mutation/human/HM = stored_mutations[num]
if(HM)
stored_mutations.Remove(HM)
qdel(HM)
current_screen = "mutations"
if("activator")
if(injectorready < world.time)
var/mutation = text2path(href_list["path"])
if(ispath(mutation, /datum/mutation/human))
var/datum/mutation/human/HM = get_valid_mutation(mutation)
if(HM)
var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc)
I.add_mutations += HM.type
I.name = "[HM.name] activator"
I.damage_coeff = connected.damage_coeff*4
injectorready = world.time + INJECTOR_TIMEOUT
if("mutator")
if(injectorready < world.time)
var/mutation = text2path(href_list["path"])
if(ispath(mutation, /datum/mutation/human))
var/datum/mutation/human/HM = get_valid_mutation(mutation)
if(HM)
var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc)
I.add_mutations += HM.type
I.doitanyway = TRUE
I.name = "[HM.name] injector"
I.damage_coeff = connected.damage_coeff
injectorready = world.time + INJECTOR_TIMEOUT*5
if("nullify")
if(viable_occupant)
var/datum/mutation/human/A = viable_occupant.dna.get_mutation(current_mutation)
if(A && (!mutation_in_sequence(current_mutation, viable_occupant.dna) || A.scrambled))
viable_occupant.dna.remove_mutation(current_mutation)
viable_occupant.dna.update_instability(TRUE)
current_screen = "mainmenu"
current_mutation = null
if("pulsegene")
if(current_screen != "info")
var/path = text2path(href_list["path"])
if(viable_occupant && num && (path in viable_occupant.dna.mutation_index))
var/list/genes = list("A","T","G","C","X")
if(jokerready < world.time)
genes += "JOKER"
var/sequence = get_gene_string(path, viable_occupant.dna)
var/original = sequence[num]
var/new_gene = input("From [original] to-", "New block", original) as null|anything in genes
if(!new_gene)
new_gene = original
if(viable_occupant == get_viable_occupant()) //No cheesing
if((new_gene == "JOKER") && (jokerready < world.time))
var/true_genes = get_sequence(current_mutation)
new_gene = true_genes[num]
jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected.precision_coeff-1))
sequence = copytext(sequence, 1, num) + new_gene + copytext(sequence, num+1, length(sequence)+1)
viable_occupant.dna.mutation_index[path] = sequence
viable_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER/connected.damage_coeff
viable_occupant.domutcheck()
if("exportdiskmut")
if(diskette && !diskette.read_only)
var/path = text2path(href_list["path"])
if(ispath(path, /datum/mutation/human))
var/datum/mutation/human/A = get_valid_mutation(path)
if(A && diskette && (LAZYLEN(diskette.mutations) < diskette.max_mutations))
var/datum/mutation/human/HM = new A.type()
diskette.mutations += HM
HM.copy_mutation(A)
to_chat(usr, "<span class='notice'>Succesfully written [A.name] to [diskette.name].</span>")
if("deletediskmut")
if(diskette && !diskette.read_only)
if(num && (LAZYLEN(diskette.mutations) >= num))
var/datum/mutation/human/A = diskette.mutations[num]
diskette.mutations.Remove(A)
qdel(A)
if("importdiskmut")
if(diskette && (LAZYLEN(diskette.mutations) >= num))
if(LAZYLEN(stored_mutations) < max_storage)
var/datum/mutation/human/A = diskette.mutations[num]
var/datum/mutation/human/HM = new A.type()
HM.copy_mutation(A)
stored_mutations[HM] = get_sequence(HM.type)
to_chat(usr,"<span class='notice'>Succesfully written [A.name] to storage.")
if("combine")
if(num && (LAZYLEN(stored_mutations) >= num))
if(LAZYLEN(stored_mutations) < max_storage)
var/datum/mutation/human/A = stored_mutations[num]
var/path = A.type
if(combine)
var/result_path = get_mixed_mutation(combine, path)
if(result_path)
stored_mutations[new result_path()] = get_sequence(result_path)
to_chat(usr, "<span class='boldnotice'>Succes! New mutation has been added to storage</span>")
discover(result_path)
combine = null
else
to_chat(usr, "<span class='warning'>Failed. No mutation could be created.</span>")
combine = null
else
combine = path
to_chat(usr,"<span class='notice'>Selected [A.name] for combining</span>")
else
to_chat(usr, "<span class='warning'>Not enough space to store potential mutation.</span>")
ui_interact(usr,last_change)
/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs,rd)
var/length = length(input)
var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER)
if(ran == 0)
ran = pick(-1,1) //hacky, statistically should almost never happen. 0-change makes people mad though
ran = pick(-1,1) //hacky, statistically should almost never happen. 0-chance makes people mad though
else if(ran < 0)
ran = round(ran) //negative, so floor it
else
@@ -537,10 +792,6 @@
//Each laser level reduces damage by lvl^2, so no effect on 1 lvl, 4 times less damage on 2 and 9 times less damage on 3
//Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove
switch(action)
if(SCANNER_ACTION_SE)
if(buffer_slot["SE"])
viable_occupant.dna.struc_enzymes = buffer_slot["SE"]
viable_occupant.domutcheck()
if(SCANNER_ACTION_UI)
if(buffer_slot["UI"])
viable_occupant.dna.uni_identity = buffer_slot["UI"]
@@ -567,10 +818,47 @@
apply_buffer(delayed_action["action"],delayed_action["buffer"])
delayed_action = null //or make it stick + reset button ?
/obj/machinery/computer/scan_consolenew/proc/get_valid_mutation(mutation)
for(var/datum/mutation/human/A in stored_mutations)
if(A.type == mutation)
return A
var/mob/living/carbon/C = get_viable_occupant()
if(C)
return C.dna.get_mutation(mutation)
/obj/machinery/computer/scan_consolenew/proc/get_mutation_list(include_storage) //Returns a list of the mutation index types and any extra mutations
var/mob/living/carbon/viable_occupant = get_viable_occupant()
var/list/paths = list()
if(viable_occupant)
for(var/A in viable_occupant.dna.mutation_index)
paths += A
for(var/datum/mutation/human/A in viable_occupant.dna.mutations)
if(A.class == MUT_EXTRA)
paths += A.type
if(include_storage)
for(var/datum/mutation/human/A in stored_mutations)
paths += A.type
return paths
/obj/machinery/computer/scan_consolenew/proc/get_valid_gene_string(mutation)
var/mob/living/carbon/C = get_viable_occupant()
if(C && (mutation in C.dna.mutation_index))
return get_gene_string(mutation, C.dna)
else if(C && (LAZYLEN(C.dna.mutations)))
for(var/datum/mutation/human/A in C.dna.mutations)
if(A.type == mutation)
return get_sequence(mutation)
for(var/datum/mutation/human/A in stored_mutations)
if(A.type == mutation)
return stored_mutations[A]
/obj/machinery/computer/scan_consolenew/proc/discover(mutation)
if(stored_research && !(mutation in stored_research.discovered_mutations))
stored_research.discovered_mutations += mutation
return TRUE
/////////////////////////// DNA MACHINES
#undef INJECTOR_TIMEOUT
#undef REJUVENATORS_INJECT
#undef REJUVENATORS_MAX
#undef NUMBER_OF_BUFFERS
#undef RADIATION_STRENGTH_MAX
+3 -3
View File
@@ -26,9 +26,9 @@
var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations)
H.dna.remove_mutation_group(unclean_mutations)
if(efficiency > 5 && prob(20))
H.randmutvg()
H.easy_randmut(POSITIVE)
if(efficiency < 3 && prob(50))
var/mob/M = H.randmutb()
var/mob/M = H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
if(ismob(M))
H = M
@@ -294,6 +294,6 @@
temp = "<font class='bad'>Cloning cycle already in progress.</font>"
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
else
pod.growclone(null, mob_occupant.real_name, dna.uni_identity, dna.struc_enzymes, clone_species, dna.features, mob_occupant.faction)
pod.growclone(null, mob_occupant.real_name, dna.uni_identity, dna.mutation_index, clone_species, dna.features, 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, 0)
@@ -251,8 +251,8 @@
chassis.clearInternalDamage(int_dam_flag)
repaired = 1
break
if(health_boost<0 || chassis.obj_integrity < chassis.max_integrity)
chassis.obj_integrity += min(health_boost, chassis.max_integrity-chassis.obj_integrity)
if(h_boost<0 || chassis.obj_integrity < chassis.max_integrity)
chassis.obj_integrity += min(h_boost, chassis.max_integrity-chassis.obj_integrity)
repaired = 1
if(repaired)
if(!chassis.use_power(energy_drain))
@@ -54,9 +54,20 @@
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
var/already_rotting = FALSE
/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
. = ..()
reagents.add_reagent("liquidgibs", 5)
if(already_rotting)
start_rotting(rename=FALSE)
else
addtimer(CALLBACK(src, .proc/start_rotting), 2 MINUTES)
/obj/effect/decal/cleanable/blood/gibs/proc/start_rotting(rename=TRUE)
name = "rotting [initial(name)]"
desc += " It smells terrible."
AddComponent(/datum/component/rot/gibs)
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return
@@ -108,6 +119,7 @@
name = "old rotting gibs"
desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
bloodiness = 0
already_rotting = TRUE
/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
. = ..()
@@ -174,15 +174,15 @@
/obj/effect/decal/cleanable/glitter/pink
name = "pink glitter"
icon_state = "plasma_old"
icon_state = "plasma"
/obj/effect/decal/cleanable/glitter/white
name = "white glitter"
icon_state = "nitrous_oxide_old"
icon_state = "nitrous_oxide"
/obj/effect/decal/cleanable/glitter/blue
name = "blue glitter"
icon_state = "freon_old"
icon_state = "freon"
/obj/effect/decal/cleanable/plasma
name = "stabilized plasma"
+3
View File
@@ -58,6 +58,9 @@
/obj/effect/abstract/singularity_act()
return
/obj/effect/abstract/has_gravity(turf/T)
return FALSE
/obj/effect/dummy/singularity_pull()
return
+11 -5
View File
@@ -231,6 +231,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
/obj/effect/landmark/start/depsec/science
name = "science_sec"
//Antagonist spawns
/obj/effect/landmark/start/wizard
name = "wizard"
icon = 'icons/effects/landmarks_static.dmi'
@@ -281,17 +283,17 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
SSjob.latejoin_trackers += loc
return INITIALIZE_HINT_QDEL
// carp.
//space carps, magicarps, lone ops, slaughter demons, possibly revenants spawn here
/obj/effect/landmark/carpspawn
name = "carpspawn"
icon_state = "carp_spawn"
// observer-start.
//observer start
/obj/effect/landmark/observer_start
name = "Observer-Start"
icon_state = "observer_start"
// xenos.
//xenos, morphs and nightmares spawn here
/obj/effect/landmark/xeno_spawn
name = "xeno_spawn"
icon_state = "xeno_spawn"
@@ -301,7 +303,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.xeno_spawn += loc
return INITIALIZE_HINT_QDEL
// blobs.
//objects with the stationloving component (nuke disk) respawn here.
//also blobs that have their spawn forcemoved (running out of time when picking their spawn spot), santa and respawning devils
/obj/effect/landmark/blobstart
name = "blobstart"
icon_state = "blob_start"
@@ -311,6 +314,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.blobstart += loc
return INITIALIZE_HINT_QDEL
//spawns sec equipment lockers depending on the number of sec officers
/obj/effect/landmark/secequipment
name = "secequipment"
icon_state = "secequipment"
@@ -320,6 +324,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.secequipment += loc
return INITIALIZE_HINT_QDEL
//players that get put in admin jail show up here
/obj/effect/landmark/prisonwarp
name = "prisonwarp"
icon_state = "prisonwarp"
@@ -338,6 +343,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.emergencyresponseteamspawn += loc
return INITIALIZE_HINT_QDEL
//ninja energy nets teleport victims here
/obj/effect/landmark/holding_facility
name = "Holding Facility"
icon_state = "holding_facility"
@@ -404,7 +410,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.city_of_cogs_spawns += loc
return INITIALIZE_HINT_QDEL
//generic event spawns
//handles clockwork portal+eminence teleport destinations
/obj/effect/landmark/event_spawn
name = "generic event spawn"
icon_state = "generic_event"
+26 -26
View File
@@ -53,7 +53,7 @@
can_charge = 0
fire_delay = 50
var/obj/item/chrono_eraser/TED = null
var/obj/effect/chrono_field/field = null
var/obj/structure/chrono_field/field = null
var/turf/startpos = null
/obj/item/gun/energy/chrono_gun/Initialize()
@@ -80,12 +80,12 @@
field_disconnect(field)
return ..()
/obj/item/gun/energy/chrono_gun/proc/field_connect(obj/effect/chrono_field/F)
var/mob/living/user = src.loc
/obj/item/gun/energy/chrono_gun/proc/field_connect(obj/structure/chrono_field/F)
var/mob/living/user = loc
if(F.gun)
if(isliving(user) && F.captured)
to_chat(user, "<span class='alert'><b>FAIL: <i>[F.captured]</i> already has an existing connection.</b></span>")
src.field_disconnect(F)
field_disconnect(F)
else
startpos = get_turf(src)
field = F
@@ -94,9 +94,9 @@
to_chat(user, "<span class='notice'>Connection established with target: <b>[F.captured]</b></span>")
/obj/item/gun/energy/chrono_gun/proc/field_disconnect(obj/effect/chrono_field/F)
/obj/item/gun/energy/chrono_gun/proc/field_disconnect(obj/structure/chrono_field/F)
if(F && field == F)
var/mob/living/user = src.loc
var/mob/living/user = loc
if(F.gun == src)
F.gun = null
if(isliving(user) && F.captured)
@@ -104,7 +104,7 @@
field = null
startpos = null
/obj/item/gun/energy/chrono_gun/proc/field_check(obj/effect/chrono_field/F)
/obj/item/gun/energy/chrono_gun/proc/field_check(obj/structure/chrono_field/F)
if(F)
if(field == F)
var/turf/currentpos = get_turf(src)
@@ -134,7 +134,7 @@
/obj/item/projectile/energy/chrono_beam/on_hit(atom/target)
if(target && gun && isliving(target))
var/obj/effect/chrono_field/F = new(target.loc, target, gun)
var/obj/structure/chrono_field/F = new(target.loc, target, gun)
gun.field_connect(F)
@@ -154,14 +154,16 @@
/obj/effect/chrono_field
/obj/structure/chrono_field
name = "eradication field"
desc = "An aura of time-bluespace energy."
icon = 'icons/effects/effects.dmi'
icon_state = "chronofield"
density = FALSE
anchored = TRUE
blend_mode = BLEND_MULTIPLY
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
move_resist = INFINITY
interaction_flags_atom = NONE
var/mob/living/captured = null
var/obj/item/gun/energy/chrono_gun/gun = null
var/tickstokill = 15
@@ -169,10 +171,10 @@
var/preloaded = 0
var/RPpos = null
/obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/gun/energy/chrono_gun/G)
/obj/structure/chrono_field/Initialize(mapload, mob/living/target, obj/item/gun/energy/chrono_gun/G)
if(target && isliving(target) && G)
target.forceMove(src)
src.captured = target
captured = target
var/icon/mob_snapshot = getFlatIcon(target)
var/icon/cached_icon = new()
@@ -187,13 +189,14 @@
desc = initial(desc) + "<br><span class='info'>It appears to contain [target.name].</span>"
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/chrono_field/Destroy()
/obj/structure/chrono_field/Destroy()
if(gun && gun.field_check(src))
gun.field_disconnect(src)
return ..()
/obj/effect/chrono_field/update_icon()
/obj/structure/chrono_field/update_icon()
var/ttk_frame = 1 - (tickstokill / initial(tickstokill))
ttk_frame = CLAMP(CEILING(ttk_frame * CHRONO_FRAME_COUNT, 1), 1, CHRONO_FRAME_COUNT)
if(ttk_frame != RPpos)
@@ -202,14 +205,14 @@
underlays = list() //hack: BYOND refuses to update the underlay to match the icon_state otherwise
underlays += mob_underlay
/obj/effect/chrono_field/process()
/obj/structure/chrono_field/process()
if(captured)
if(tickstokill > initial(tickstokill))
for(var/atom/movable/AM in contents)
AM.forceMove(drop_location())
qdel(src)
else if(tickstokill <= 0)
to_chat(captured, "<span class='boldnotice'>As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy...</span>")
to_chat(captured, "<span class='boldnotice'>As the last essence of your being is erased from time, you are taken back to your most enjoyable memory. You feel happy...</span>")
var/mob/dead/observer/ghost = captured.ghostize(1)
if(captured.mind)
if(ghost)
@@ -234,7 +237,7 @@
else
qdel(src)
/obj/effect/chrono_field/bullet_act(obj/item/projectile/P)
/obj/structure/chrono_field/bullet_act(obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy/chrono_beam))
var/obj/item/projectile/energy/chrono_beam/beam = P
var/obj/item/gun/energy/chrono_gun/Pgun = beam.gun
@@ -243,10 +246,10 @@
else
return 0
/obj/effect/chrono_field/assume_air()
/obj/structure/chrono_field/assume_air()
return 0
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
/obj/structure/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
GM.add_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
GM.gases[/datum/gas/oxygen][MOLES] = MOLES_O2STANDARD
@@ -254,19 +257,16 @@
GM.temperature = T20C
return GM
/obj/effect/chrono_field/Move()
/obj/structure/chrono_field/singularity_act()
return
/obj/effect/chrono_field/singularity_act()
/obj/structure/chrono_field/singularity_pull()
return
/obj/effect/chrono_field/singularity_pull()
/obj/structure/chrono_field/ex_act()
return
/obj/effect/chrono_field/ex_act()
return
/obj/effect/chrono_field/blob_act(obj/structure/blob/B)
/obj/structure/chrono_field/blob_act(obj/structure/blob/B)
return
@@ -57,7 +57,7 @@
build_path = /obj/machinery/dna_scannernew
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stock_parts/matter_bin = 1,
/obj/item/stock_parts/micro_laser = 1,
/obj/item/stack/sheet/glass = 1,
/obj/item/stack/cable_coil = 2)
@@ -500,8 +500,8 @@
name = "Scanner Gate (Machine Board)"
build_path = /obj/machinery/scanner_gate
req_components = list(
/obj/item/stock_parts/scanning_module = 3)
/obj/item/stock_parts/scanning_module = 3)
/obj/item/circuitboard/machine/pacman
name = "PACMAN-type Generator (Machine Board)"
build_path = /obj/machinery/power/port_gen/pacman
@@ -27,6 +27,10 @@
qdel(F)
return
var/turf/T = get_turf(target)
var/obj/structure/projected_forcefield/found_field = locate() in T
if(found_field)
to_chat(user, "<span class='warning'>There is already a forcefield in that location!</span>")
return
if(T.density)
return
if(get_dist(T,src) > field_distance_limit)
+2 -45
View File
@@ -10,18 +10,14 @@
var/datum/song/handheld/song
var/instrumentId = "generic"
var/instrumentExt = "mid"
var/tune_time = 0
/obj/item/instrument/Initialize()
. = ..()
song = new(instrumentId, src, instrumentExt)
/obj/item/instrument/Destroy()
if (tune_time)
STOP_PROCESSING(SSobj, src)
qdel(song)
song = null
return ..()
QDEL_NULL(song)
. = ..()
/obj/item/instrument/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -48,34 +44,6 @@
user.set_machine(src)
song.interact(user)
/obj/item/instrument/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/musicaltuner))
var/mob/living/carbon/human/H = user
if (H.has_trait(TRAIT_MUSICIAN))
if (!tune_time)
H.visible_message("[H] tunes [src] to perfection!", "<span class='notice'>You tune [src] to perfection!</span>")
tune_time = 300
START_PROCESSING(SSobj, src)
else
to_chat(H, "<span class='notice'>[src] is already well tuned!</span>")
else
to_chat(H, "<span class='warning'>You have no idea how to use this.</span>")
/obj/item/instrument/process()
if (tune_time)
if (song.playing)
for (var/mob/living/M in song.hearing_mobs)
M.dizziness = max(0,M.dizziness-2)
M.jitteriness = max(0,M.jitteriness-2)
M.confused = max(M.confused-1)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "goodmusic", /datum/mood_event/goodmusic)
tune_time--
else
if (!tune_time)
if (song.playing)
loc.visible_message("<span class='warning'>[src] starts sounding a little off...</span>")
STOP_PROCESSING(SSobj, src)
/obj/item/instrument/violin
name = "space violin"
desc = "A wooden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
@@ -255,17 +223,6 @@
///
/obj/item/musicaltuner
name = "musical tuner"
desc = "A device for tuning musical instruments both manual and electronic alike."
icon = 'icons/obj/device.dmi'
icon_state = "musicaltuner"
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
/obj/item/choice_beacon/music
name = "instrument delivery beacon"
desc = "Summon your tool of art."
@@ -6,6 +6,7 @@ T-RAY
HEALTH ANALYZER
GAS ANALYZER
SLIME SCANNER
NANITE SCANNER
*/
/obj/item/t_scanner
@@ -652,3 +653,62 @@ SLIME SCANNER
var/response = SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, TRUE)
if(!response)
to_chat(user, "<span class='info'>No nanites detected in the subject.</span>")
/obj/item/sequence_scanner
name = "genetic sequence scanner"
icon = 'icons/obj/device.dmi'
icon_state = "gene"
item_state = "healthanalyzer"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
desc = "A hand-held scanner able to swiftly scan someone for potential mutations. Hold near a DNA console to update from their database."
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
throwforce = 3
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
var/list/discovered = list() //hit a dna console to update the scanners database
/obj/item/sequence_scanner/attack(mob/living/M, mob/living/carbon/human/user)
user.visible_message("<span class='notice'>[user] has analyzed [M]'s genetic sequence.</span>")
add_fingerprint(user)
gene_scan(M, user, src)
/obj/item/sequence_scanner/afterattack(obj/O, mob/user, proximity)
. = ..()
if(!istype(O) || !proximity)
return
if(istype(O, /obj/machinery/computer/scan_consolenew))
var/obj/machinery/computer/scan_consolenew/C = O
if(C.stored_research)
to_chat(user, "<span class='notice'>[name] database updated.</span>")
discovered = C.stored_research.discovered_mutations
else
to_chat(user,"<span class='warning'>No database to update from.</span>")
/proc/gene_scan(mob/living/carbon/C, mob/living/user, obj/item/sequence_scanner/G)
if(!iscarbon(C) || !C.has_dna())
return
to_chat(user, "<span class='notice'>[C.name]'s potential mutations.")
for(var/A in C.dna.mutation_index)
var/datum/mutation/human/HM = get_initialized_mutation(A)
var/mut_name
if(G && (A in G.discovered))
mut_name = "[HM.name] ([HM.alias])"
else
mut_name = HM.alias
var/temp = get_gene_string(HM.type, C.dna)
var/display
for(var/i in 0 to length(temp) / DNA_MUTATION_BLOCKS-1)
if(i)
display += "-"
display += copytext(temp, 1 + i*DNA_MUTATION_BLOCKS, DNA_MUTATION_BLOCKS*(1+i) + 1)
to_chat(user, "<span class='boldnotice'>- [mut_name] > [display]</span>")
+86 -75
View File
@@ -14,33 +14,25 @@
var/list/add_mutations = list()
var/list/remove_mutations = list()
var/list/add_mutations_static = list()
var/list/remove_mutations_static = list()
var/used = 0
/obj/item/dnainjector/attack_paw(mob/user)
return attack_hand(user)
/obj/item/dnainjector/proc/prepare()
for(var/mut_key in add_mutations_static)
add_mutations.Add(GLOB.mutations_list[mut_key])
for(var/mut_key in remove_mutations_static)
remove_mutations.Add(GLOB.mutations_list[mut_key])
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/datum/mutation/human/HM in remove_mutations)
HM.force_lose(M)
for(var/datum/mutation/human/HM in add_mutations)
if(HM.name == RACEMUT)
for(var/HM in remove_mutations)
M.dna.remove_mutation(HM)
for(var/HM in add_mutations)
if(HM == RACEMUT)
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
log_msg += " (MONKEY)"
HM.force_give(M)
if(mutation_in_sequence(HM, M.dna))
M.dna.activate_mutation(HM)
else
M.dna.add_mutation(HM, MUT_EXTRA)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
M.real_name = fields["name"]
@@ -90,123 +82,123 @@
/obj/item/dnainjector/antihulk
name = "\improper DNA injector (Anti-Hulk)"
desc = "Cures green skin."
remove_mutations_static = list(HULK)
remove_mutations = list(HULK)
/obj/item/dnainjector/hulkmut
name = "\improper DNA injector (Hulk)"
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations_static = list(HULK)
add_mutations = list(HULK)
/obj/item/dnainjector/xraymut
name = "\improper DNA injector (X-ray)"
desc = "Finally you can see what the Captain does."
add_mutations_static = list(XRAY)
add_mutations = list(XRAY)
/obj/item/dnainjector/antixray
name = "\improper DNA injector (Anti-X-ray)"
desc = "It will make you see harder."
remove_mutations_static = list(XRAY)
remove_mutations = list(XRAY)
/////////////////////////////////////
/obj/item/dnainjector/antiglasses
name = "\improper DNA injector (Anti-Glasses)"
desc = "Toss away those glasses!"
remove_mutations_static = list(BADSIGHT)
remove_mutations = list(BADSIGHT)
/obj/item/dnainjector/glassesmut
name = "\improper DNA injector (Glasses)"
desc = "Will make you need dorkish glasses."
add_mutations_static = list(BADSIGHT)
add_mutations = list(BADSIGHT)
/obj/item/dnainjector/epimut
name = "\improper DNA injector (Epi.)"
desc = "Shake shake shake the room!"
add_mutations_static = list(EPILEPSY)
add_mutations = list(EPILEPSY)
/obj/item/dnainjector/antiepi
name = "\improper DNA injector (Anti-Epi.)"
desc = "Will fix you up from shaking the room."
remove_mutations_static = list(EPILEPSY)
remove_mutations = list(EPILEPSY)
////////////////////////////////////
/obj/item/dnainjector/anticough
name = "\improper DNA injector (Anti-Cough)"
desc = "Will stop that awful noise."
remove_mutations_static = list(COUGH)
remove_mutations = list(COUGH)
/obj/item/dnainjector/coughmut
name = "\improper DNA injector (Cough)"
desc = "Will bring forth a sound of horror from your throat."
add_mutations_static = list(COUGH)
add_mutations = list(COUGH)
/obj/item/dnainjector/antidwarf
name = "\improper DNA injector (Anti-Dwarfism)"
desc = "Helps you grow big and strong."
remove_mutations_static = list(DWARFISM)
remove_mutations = list(DWARFISM)
/obj/item/dnainjector/dwarf
name = "\improper DNA injector (Dwarfism)"
desc = "It's a small world after all."
add_mutations_static = list(DWARFISM)
add_mutations = list(DWARFISM)
/obj/item/dnainjector/clumsymut
name = "\improper DNA injector (Clumsy)"
desc = "Makes clown minions."
add_mutations_static = list(CLOWNMUT)
add_mutations = list(CLOWNMUT)
/obj/item/dnainjector/anticlumsy
name = "\improper DNA injector (Anti-Clumsy)"
desc = "Apply this for Security Clown."
remove_mutations_static = list(CLOWNMUT)
remove_mutations = list(CLOWNMUT)
/obj/item/dnainjector/antitour
name = "\improper DNA injector (Anti-Tour.)"
desc = "Will cure Tourette's."
remove_mutations_static = list(TOURETTES)
remove_mutations = list(TOURETTES)
/obj/item/dnainjector/tourmut
name = "\improper DNA injector (Tour.)"
desc = "Gives you a nasty case of Tourette's."
add_mutations_static = list(TOURETTES)
add_mutations = list(TOURETTES)
/obj/item/dnainjector/stuttmut
name = "\improper DNA injector (Stutt.)"
desc = "Makes you s-s-stuttterrr."
add_mutations_static = list(NERVOUS)
add_mutations = list(NERVOUS)
/obj/item/dnainjector/antistutt
name = "\improper DNA injector (Anti-Stutt.)"
desc = "Fixes that speaking impairment."
remove_mutations_static = list(NERVOUS)
remove_mutations = list(NERVOUS)
/obj/item/dnainjector/antifire
name = "\improper DNA injector (Anti-Fire)"
desc = "Cures fire."
remove_mutations_static = list(COLDRES)
remove_mutations = list(SPACEMUT)
/obj/item/dnainjector/firemut
name = "\improper DNA injector (Fire)"
desc = "Gives you fire."
add_mutations_static = list(COLDRES)
add_mutations = list(SPACEMUT)
/obj/item/dnainjector/blindmut
name = "\improper DNA injector (Blind)"
desc = "Makes you not see anything."
add_mutations_static = list(BLINDMUT)
add_mutations = list(BLINDMUT)
/obj/item/dnainjector/antiblind
name = "\improper DNA injector (Anti-Blind)"
desc = "IT'S A MIRACLE!!!"
remove_mutations_static = list(BLINDMUT)
remove_mutations = list(BLINDMUT)
/obj/item/dnainjector/antitele
name = "\improper DNA injector (Anti-Tele.)"
desc = "Will make you not able to control your mind."
remove_mutations_static = list(TK)
remove_mutations = list(TK)
/obj/item/dnainjector/telemut
name = "\improper DNA injector (Tele.)"
desc = "Super brain man!"
add_mutations_static = list(TK)
add_mutations = list(TK)
/obj/item/dnainjector/telemut/darkbundle
name = "\improper DNA injector"
@@ -215,100 +207,99 @@
/obj/item/dnainjector/deafmut
name = "\improper DNA injector (Deaf)"
desc = "Sorry, what did you say?"
add_mutations_static = list(DEAFMUT)
add_mutations = list(DEAFMUT)
/obj/item/dnainjector/antideaf
name = "\improper DNA injector (Anti-Deaf)"
desc = "Will make you hear once more."
remove_mutations_static = list(DEAFMUT)
remove_mutations = list(DEAFMUT)
/obj/item/dnainjector/h2m
name = "\improper DNA injector (Human > Monkey)"
desc = "Will make you a flea bag."
add_mutations_static = list(RACEMUT)
add_mutations = list(RACEMUT)
/obj/item/dnainjector/m2h
name = "\improper DNA injector (Monkey > Human)"
desc = "Will make you...less hairy."
remove_mutations_static = list(RACEMUT)
remove_mutations = list(RACEMUT)
/obj/item/dnainjector/antichameleon
name = "\improper DNA injector (Anti-Chameleon)"
remove_mutations_static = list(CHAMELEON)
remove_mutations = list(CHAMELEON)
/obj/item/dnainjector/chameleonmut
name = "\improper DNA injector (Chameleon)"
add_mutations_static = list(CHAMELEON)
add_mutations = list(CHAMELEON)
/obj/item/dnainjector/antiwacky
name = "\improper DNA injector (Anti-Wacky)"
remove_mutations_static = list(WACKY)
remove_mutations = list(WACKY)
/obj/item/dnainjector/wackymut
name = "\improper DNA injector (Wacky)"
add_mutations_static = list(WACKY)
add_mutations = list(WACKY)
/obj/item/dnainjector/antimute
name = "\improper DNA injector (Anti-Mute)"
remove_mutations_static = list(MUT_MUTE)
remove_mutations = list(MUT_MUTE)
/obj/item/dnainjector/mutemut
name = "\improper DNA injector (Mute)"
add_mutations_static = list(MUT_MUTE)
add_mutations = list(MUT_MUTE)
/obj/item/dnainjector/antismile
name = "\improper DNA injector (Anti-Smile)"
remove_mutations_static = list(SMILE)
remove_mutations = list(SMILE)
/obj/item/dnainjector/smilemut
name = "\improper DNA injector (Smile)"
add_mutations_static = list(SMILE)
add_mutations = list(SMILE)
/obj/item/dnainjector/unintelligiblemut
name = "\improper DNA injector (Unintelligible)"
add_mutations_static = list(UNINTELLIGIBLE)
add_mutations = list(UNINTELLIGIBLE)
/obj/item/dnainjector/antiunintelligible
name = "\improper DNA injector (Anti-Unintelligible)"
remove_mutations_static = list(UNINTELLIGIBLE)
remove_mutations = list(UNINTELLIGIBLE)
/obj/item/dnainjector/swedishmut
name = "\improper DNA injector (Swedish)"
add_mutations_static = list(SWEDISH)
add_mutations = list(SWEDISH)
/obj/item/dnainjector/antiswedish
name = "\improper DNA injector (Anti-Swedish)"
remove_mutations_static = list(SWEDISH)
remove_mutations = list(SWEDISH)
/obj/item/dnainjector/chavmut
name = "\improper DNA injector (Chav)"
add_mutations_static = list(CHAV)
add_mutations = list(CHAV)
/obj/item/dnainjector/antichav
name = "\improper DNA injector (Anti-Chav)"
remove_mutations_static = list(CHAV)
remove_mutations = list(CHAV)
/obj/item/dnainjector/elvismut
name = "\improper DNA injector (Elvis)"
add_mutations_static = list(ELVIS)
add_mutations = list(ELVIS)
/obj/item/dnainjector/antielvis
name = "\improper DNA injector (Anti-Elvis)"
remove_mutations_static = list(ELVIS)
remove_mutations = list(ELVIS)
/obj/item/dnainjector/lasereyesmut
name = "\improper DNA injector (Laser Eyes)"
add_mutations_static = list(LASEREYES)
add_mutations = list(LASEREYES)
/obj/item/dnainjector/antilasereyes
name = "\improper DNA injector (Anti-Laser Eyes)"
remove_mutations_static = list(LASEREYES)
remove_mutations = list(LASEREYES)
/obj/item/dnainjector/timed
var/duration = 600
/obj/item/dnainjector/timed/inject(mob/living/carbon/M, mob/user)
prepare()
if(M.stat == DEAD) //prevents dead people from having their DNA changed
to_chat(user, "<span class='notice'>You can't modify [M]'s DNA while [M.p_theyre()] dead.</span>")
return FALSE
@@ -317,23 +308,22 @@
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
var/endtime = world.time+duration
for(var/datum/mutation/human/HM in remove_mutations)
if(HM.name == RACEMUT)
for(var/mutation in remove_mutations)
if(mutation == RACEMUT)
if(ishuman(M))
continue
M = HM.force_lose(M)
M = M.dna.remove_mutation(mutation)
else
HM.force_lose(M)
for(var/datum/mutation/human/HM in add_mutations)
if((HM in M.dna.mutations) && !(M.dna.temporary_mutations[HM.name]))
M.dna.remove_mutation(mutation)
for(var/mutation in add_mutations)
if(M.dna.get_mutation(mutation))
continue //Skip permanent mutations we already have.
if(HM.name == RACEMUT && ishuman(M))
if(mutation == RACEMUT && ishuman(M))
message_admins("[ADMIN_LOOKUPFLW(user)] injected [key_name_admin(M)] with the [name] <span class='danger'>(MONKEY)</span>")
log_msg += " (MONKEY)"
M = HM.force_give(M)
M = M.dna.add_mutation(mutation, MUT_OTHER, endtime)
else
HM.force_give(M)
M.dna.temporary_mutations[HM.name] = endtime
M.dna.add_mutation(mutation, MUT_OTHER, endtime)
if(fields)
if(fields["name"] && fields["UE"] && fields["blood_type"])
if(!M.dna.previous["name"])
@@ -361,9 +351,30 @@
/obj/item/dnainjector/timed/hulk
name = "\improper DNA injector (Hulk)"
desc = "This will make you big and strong, but give you a bad skin condition."
add_mutations_static = list(HULK)
add_mutations = list(HULK)
/obj/item/dnainjector/timed/h2m
name = "\improper DNA injector (Human > Monkey)"
desc = "Will make you a flea bag."
add_mutations_static = list(RACEMUT)
add_mutations = list(RACEMUT)
/obj/item/dnainjector/activator
name = "\improper DNA activator"
desc = "Activates the current mutation on injection, if the subject has it."
var/doitanyway = FALSE
/obj/item/dnainjector/activator/inject(mob/living/carbon/M, mob/user)
if(M.has_dna() && !M.has_trait(TRAIT_RADIMMUNE) && !M.has_trait(TRAIT_NOCLONE))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/mutation in add_mutations)
if(!M.dna.activate_mutation(mutation) && !doitanyway)
log_msg += "(FAILED)"
else if(doitanyway)
M.dna.add_mutation(mutation, MUT_EXTRA)
log_msg += "([mutation])"
log_attack("[log_msg] [loc_name(user)]")
M.dna.update_instability(TRUE)
return TRUE
return FALSE
@@ -32,6 +32,12 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
new/datum/stack_recipe("lime comfy chair", /obj/structure/chair/comfy/lime, 2, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("teal comfy chair", /obj/structure/chair/comfy/teal, 2, one_per_turf = TRUE, on_floor = TRUE), \
)), \
new/datum/stack_recipe_list("sofas", list(
new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, 1, one_per_turf = TRUE, on_floor = TRUE),
new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, 1, one_per_turf = TRUE, on_floor = TRUE),
new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, 1, one_per_turf = TRUE, on_floor = TRUE),
new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, 1, one_per_turf = TRUE, on_floor = TRUE)
)),
null, \
new/datum/stack_recipe("rack parts", /obj/item/rack_parts), \
new/datum/stack_recipe("closet", /obj/structure/closet, 2, time = 15, one_per_turf = TRUE, on_floor = TRUE), \
@@ -154,6 +154,10 @@
..() // Plasma asserted in parent
air_contents.gases[/datum/gas/plasma][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/plasmaman/belt/empty/Initialize()
. = ..() // Plasma asserted in parent
air_contents.gases[/datum/gas/plasma][MOLES] = 0
@@ -177,13 +181,26 @@
air_contents.assert_gas(/datum/gas/oxygen)
air_contents.gases[/datum/gas/oxygen][MOLES] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
return
/obj/item/tank/internals/emergency_oxygen/empty/Initialize()
. = ..()
air_contents.gases[/datum/gas/oxygen][MOLES] = 0
/obj/item/tank/internals/emergency_oxygen/engi
name = "extended-capacity emergency oxygen tank"
icon_state = "emergency_engi"
volume = 2 // should last a bit over 30 minutes if full
/obj/item/tank/internals/emergency_oxygen/engi/empty/Initialize()
. = ..()
air_contents.gases[/datum/gas/oxygen][MOLES] = 0
/obj/item/tank/internals/emergency_oxygen/double
name = "double emergency oxygen tank"
icon_state = "emergency_double"
volume = 8
/obj/item/tank/internals/emergency_oxygen/double/empty/Initialize()
. = ..()
air_contents.gases[/datum/gas/oxygen][MOLES] = 0
@@ -0,0 +1,14 @@
/obj/structure/chair/sofa
name = "old ratty sofa"
icon_state = "sofamiddle"
icon = 'icons/obj/sofa.dmi'
buildstackamount = 1
/obj/structure/chair/sofa/left
icon_state = "sofaend_left"
/obj/structure/chair/sofa/right
icon_state = "sofaend_right"
/obj/structure/chair/sofa/corner
icon_state = "sofacorner"
@@ -107,6 +107,7 @@
new /obj/item/reagent_containers/blood/OMinus(src)
new /obj/item/reagent_containers/blood/OPlus(src)
new /obj/item/reagent_containers/blood/lizard(src)
new /obj/item/reagent_containers/blood/ethereal(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/blood/random(src)
+7 -4
View File
@@ -33,7 +33,7 @@
// note is a number from 1-7 for A-G
// acc is either "b", "n", or "#"
// oct is 1-8 (or 9 for C)
/datum/song/proc/playnote(note, acc as text, oct)
/datum/song/proc/playnote(mob/user, note, acc as text, oct)
// handle accidental -> B<>C of E<>F
if(acc == "b" && (note == 3 || note == 6)) // C or F
if(note == 3)
@@ -67,14 +67,17 @@
if((world.time - MUSICIAN_HEARCHECK_MINDELAY) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
for(var/mob/M in get_hearers_in_view(15, source))
if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS))
continue
LAZYADD(hearing_mobs, M)
last_hearcheck = world.time
var/sound/music_played = sound(soundfile)
for(var/i in hearing_mobs)
var/mob/M = i
if(user.has_trait(TRAIT_MUSICIAN) && isliving(M))
var/mob/living/L = M
L.apply_status_effect(STATUS_EFFECT_GOOD_MUSIC)
if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS))
continue
M.playsound_local(source, null, 100, falloff = 5, S = music_played)
/datum/song/proc/updateDialog(mob/user)
@@ -127,7 +130,7 @@
cur_acc[cur_note] = "b"
else if(prob(75))
cur_acc[cur_note] = "n"
playnote(cur_note, cur_acc[cur_note], cur_oct[cur_note])
playnote(user, cur_note, cur_acc[cur_note], cur_oct[cur_note])
if(notes.len >= 2 && text2num(notes[2]))
sleep(sanitize_tempo(tempo / text2num(notes[2])))
else
+9 -9
View File
@@ -55,15 +55,15 @@
/obj/structure/plasticflaps/CanAStarPass(ID, to_dir, caller)
if(isliving(caller))
if(isbot(caller))
return 1
return TRUE
var/mob/living/M = caller
if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY)
return 0
return FALSE
var/atom/movable/M = caller
if(M && M.pulling)
return CanAStarPass(ID, to_dir, M.pulling)
return 1 //diseases, stings, etc can pass
return TRUE //diseases, stings, etc can pass
/obj/structure/plasticflaps/CanPass(atom/movable/A, turf/T)
if(istype(A) && (A.pass_flags & PASSGLASS))
@@ -71,24 +71,24 @@
var/obj/structure/bed/B = A
if(istype(A, /obj/structure/bed) && (B.has_buckled_mobs() || B.density))//if it's a bed/chair and is dense or someone is buckled, it will not pass
return 0
return FALSE
if(istype(A, /obj/structure/closet/cardboard))
var/obj/structure/closet/cardboard/C = A
if(C.move_delay)
return 0
return FALSE
if(ismecha(A))
return 0
return FALSE
else if(isliving(A)) // You Shall Not Pass!
var/mob/living/M = A
if(isbot(A)) //Bots understand the secrets
return 1
return TRUE
if(M.buckled && istype(M.buckled, /mob/living/simple_animal/bot/mulebot)) // mulebot passenger gets a free pass.
return 1
return TRUE
if((M.mobility_flags & MOBILITY_STAND) && !M.ventcrawler && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
return 0
return FALSE
return ..()
/obj/structure/plasticflaps/deconstruct(disassembled = TRUE)
+111
View File
@@ -0,0 +1,111 @@
#define STAIR_TERMINATOR_AUTOMATIC 0
#define STAIR_TERMINATOR_NO 1
#define STAIR_TERMINATOR_YES 2
/obj/structure/stairs
name = "stairs"
icon = 'icons/obj/stairs.dmi'
icon_state = "stairs"
anchored = TRUE
//dir = direction of travel to go upwards
var/force_open_above = FALSE
var/terminator_mode = STAIR_TERMINATOR_AUTOMATIC
var/datum/component/redirect/multiz_signal_listener
/obj/structure/stairs/Initialize(mapload)
if(force_open_above)
force_open_above()
build_signal_listener()
update_surrounding()
return ..()
/obj/structure/stairs/Destroy()
QDEL_NULL(multiz_signal_listener)
return ..()
/obj/structure/stairs/Move() //Look this should never happen but...
. = ..()
if(force_open_above)
build_signal_listener()
update_surrounding()
/obj/structure/stairs/proc/update_surrounding()
update_icon()
for(var/i in GLOB.cardinals)
var/turf/T = get_step(get_turf(src), i)
var/obj/structure/stairs/S = locate() in T
if(S)
S.update_icon()
/obj/structure/stairs/Uncross(atom/movable/AM, turf/newloc)
if(!newloc || !AM)
return ..()
if(isliving(AM) && isTerminator() && (get_dir(src, newloc) == dir))
stair_ascend(AM)
return FALSE
return ..()
/obj/structure/stairs/Cross(atom/movable/AM)
if(isTerminator() && (get_dir(src, AM) == dir))
return FALSE
return ..()
/obj/structure/stairs/update_icon()
if(isTerminator())
icon_state = "stairs_t"
else
icon_state = "stairs"
/obj/structure/stairs/proc/stair_ascend(atom/movable/AM)
var/turf/checking = get_step_multiz(get_turf(src), UP)
if(!istype(checking))
return
if(!checking.zPassIn(AM, UP, get_turf(src)))
return
var/turf/target = get_step_multiz(get_turf(src), (dir|UP))
if(istype(target) && !target.can_zFall(AM, null, get_step_multiz(target, DOWN))) //Don't throw them into a tile that will just dump them back down.
AM.forceMove(target)
/obj/structure/stairs/vv_edit_var(var_name, var_value)
. = ..()
if(.)
if(var_name == NAMEOF(src, force_open_above))
if(!var_value)
QDEL_NULL(multiz_signal_listener)
else
build_signal_listener()
force_open_above()
/obj/structure/stairs/proc/build_signal_listener()
QDEL_NULL(multiz_signal_listener)
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
multiz_signal_listener = T.AddComponent(/datum/component/redirect, list(COMSIG_TURF_MULTIZ_NEW = CALLBACK(src, .proc/on_multiz_new)))
/obj/structure/stairs/proc/force_open_above()
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
if(T && !istype(T))
T.ChangeTurf(/turf/open/openspace)
/obj/structure/stairs/proc/on_multiz_new(turf/source, dir)
if(dir == UP)
var/turf/open/openspace/T = get_step_multiz(get_turf(src), UP)
if(T && !istype(T))
T.ChangeTurf(/turf/open/openspace)
/obj/structure/stairs/intercept_zImpact(atom/movable/AM, levels = 1)
return isTerminator()
/obj/structure/stairs/proc/isTerminator() //If this is the last stair in a chain and should move mobs up
if(terminator_mode != STAIR_TERMINATOR_AUTOMATIC)
return (terminator_mode == STAIR_TERMINATOR_YES)
var/turf/T = get_turf(src)
if(!T)
return FALSE
var/turf/them = get_step(T, dir)
if(!them)
return FALSE
for(var/obj/structure/stairs/S in them)
if(S.dir == dir)
return FALSE
return TRUE
+19 -32
View File
@@ -16,6 +16,22 @@
if(wet)
AddComponent(/datum/component/wet_floor, wet, INFINITY, 0, INFINITY, TRUE)
//direction is direction of travel of A
/turf/open/zPassIn(atom/movable/A, direction, turf/source)
return (direction == DOWN)
//direction is direction of travel of A
/turf/open/zPassOut(atom/movable/A, direction, turf/destination)
return (direction == UP)
//direction is direction of travel of air
/turf/open/zAirIn(direction, turf/source)
return (direction == DOWN)
//direction is direction of travel of air
/turf/open/zAirOut(direction, turf/source)
return (direction == UP)
/turf/open/indestructible
name = "floor"
icon = 'icons/turf/floors.dmi'
@@ -157,43 +173,14 @@
update_visuals()
current_cycle = times_fired
//cache some vars
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in GLOB.cardinals)
var/turf/open/enemy_tile = get_step(src, direction)
if(!istype(enemy_tile))
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= enemy_tile
continue
CalculateAdjacentTurfs()
for(var/i in atmos_adjacent_turfs)
var/turf/open/enemy_tile = i
var/datum/gas_mixture/enemy_air = enemy_tile.return_air()
//only check this turf, if it didn't check us when it was initalized
if(enemy_tile.current_cycle < times_fired)
if(CANATMOSPASS(src, enemy_tile))
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(enemy_tile.atmos_adjacent_turfs)
atmos_adjacent_turfs[enemy_tile] = TRUE
enemy_tile.atmos_adjacent_turfs[src] = TRUE
else
if (atmos_adjacent_turfs)
atmos_adjacent_turfs -= enemy_tile
if (enemy_tile.atmos_adjacent_turfs)
enemy_tile.atmos_adjacent_turfs -= src
UNSETEMPTY(enemy_tile.atmos_adjacent_turfs)
continue
else
if (!atmos_adjacent_turfs || !atmos_adjacent_turfs[enemy_tile])
continue
if(!excited && air.compare(enemy_air))
//testing("Active turf found. Return value of compare(): [is_active]")
excited = TRUE
SSair.active_turfs |= src
UNSETEMPTY(atmos_adjacent_turfs)
if (atmos_adjacent_turfs)
src.atmos_adjacent_turfs = atmos_adjacent_turfs
/turf/open/proc/GetHeatCapacity()
. = air.heat_capacity()
+108
View File
@@ -0,0 +1,108 @@
/turf/open/openspace
name = "open space"
desc = "Watch your step!"
icon_state = "grey"
baseturfs = /turf/open/openspace
CanAtmosPassVertical = ATMOS_PASS_YES
plane = FLOOR_OPENSPACE_PLANE
layer = OPENSPACE_LAYER
//mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/can_cover_up = TRUE
var/can_build_on = TRUE
/turf/open/openspace/debug/update_multiz()
..()
return TRUE
/turf/open/openspace/Initialize()
. = ..()
return INITIALIZE_HINT_LATELOAD
/turf/open/openspace/LateInitialize()
update_multiz(TRUE, TRUE)
/turf/open/openspace/Destroy()
vis_contents.len = 0
return ..()
/turf/open/openspace/update_multiz(prune_on_fail = FALSE, init = FALSE)
. = ..()
var/turf/T = below()
if(!T)
vis_contents.len = 0
if(prune_on_fail)
ChangeTurf(/turf/open/floor/plating)
return FALSE
if(init)
vis_contents += T
return TRUE
/turf/open/openspace/multiz_turf_del(turf/T, dir)
if(dir != DOWN)
return
update_multiz()
/turf/open/openspace/multiz_turf_new(turf/T, dir)
if(dir != DOWN)
return
update_multiz()
/turf/open/openspace/zAirIn()
return TRUE
/turf/open/openspace/zAirOut()
return TRUE
/turf/open/openspace/zPassIn(atom/movable/A, direction, turf/source)
return TRUE
/turf/open/openspace/zPassOut(atom/movable/A, direction, turf/destination)
return TRUE
/turf/open/openspace/proc/CanCoverUp()
return can_cover_up
/turf/open/openspace/proc/CanBuildHere()
return can_build_on
/turf/open/openspace/attackby(obj/item/C, mob/user, params)
..()
if(!CanBuildHere())
return
if(istype(C, /obj/item/stack/rods))
var/obj/item/stack/rods/R = C
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
var/obj/structure/lattice/catwalk/W = locate(/obj/structure/lattice/catwalk, src)
if(W)
to_chat(user, "<span class='warning'>There is already a catwalk here!</span>")
return
if(L)
if(R.use(1))
to_chat(user, "<span class='notice'>You construct a catwalk.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
new/obj/structure/lattice/catwalk(src)
else
to_chat(user, "<span class='warning'>You need two rods to build a catwalk!</span>")
return
if(R.use(1))
to_chat(user, "<span class='notice'>You construct a lattice.</span>")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
ReplaceWithLattice()
else
to_chat(user, "<span class='warning'>You need one rod to build a lattice.</span>")
return
if(istype(C, /obj/item/stack/tile/plasteel))
if(!CanCoverUp())
return
var/obj/structure/lattice/L = locate(/obj/structure/lattice, src)
if(L)
var/obj/item/stack/tile/plasteel/S = C
if(S.use(1))
qdel(L)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "<span class='notice'>You build a floor.</span>")
PlaceOnTop(/turf/open/floor/plating)
else
to_chat(user, "<span class='warning'>You need one floor tile to build a floor!</span>")
else
to_chat(user, "<span class='warning'>The plating is going to need some support! Place metal rods first.</span>")
@@ -78,14 +78,21 @@
icon_state = "solarpanel"
/turf/open/floor/plasteel/freezer
icon_state = "freezerfloor"
/turf/open/floor/plasteel/freezer/kitchen_coldroom
initial_gas_mix = KITCHEN_COLDROOM_ATMOS
/turf/open/floor/plasteel/freezer/airless
initial_gas_mix = AIRLESS_ATMOS
/turf/open/floor/plasteel/kitchen_coldroom
name = "cold room floor"
initial_gas_mix = KITCHEN_COLDROOM_ATMOS
/turf/open/floor/plasteel/kitchen_coldroom/freezerfloor
icon_state = "freezerfloor"
/turf/open/floor/plasteel/grimy
icon_state = "grimy"
tiled_dirt = FALSE
-1
View File
@@ -19,7 +19,6 @@
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
bullet_bounce_sound = null
/turf/open/space/basic/New() //Do not convert to Initialize
//This is used to optimize the map loader
return
+66 -1
View File
@@ -39,7 +39,7 @@
return FALSE
. = ..()
/turf/Initialize()
/turf/Initialize(mapload)
if(flags_1 & INITIALIZED_1)
stack_trace("Warning: [src]([type]) initialized multiple times!")
flags_1 |= INITIALIZED_1
@@ -68,6 +68,15 @@
if (light_power && light_range)
update_light()
var/turf/T = SSmapping.get_turf_above(src)
if(T)
T.multiz_turf_new(src, DOWN)
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN)
T = SSmapping.get_turf_below(src)
if(T)
T.multiz_turf_new(src, UP)
SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP)
if (opacity)
has_opaque_atom = TRUE
@@ -83,6 +92,12 @@
if(!changing_turf)
stack_trace("Incorrect turf deletion")
changing_turf = FALSE
var/turf/T = SSmapping.get_turf_above(src)
if(T)
T.multiz_turf_del(src, DOWN)
T = SSmapping.get_turf_below(src)
if(T)
T.multiz_turf_del(src, UP)
if(force)
..()
//this will completely wipe turf state
@@ -105,6 +120,54 @@
return
user.Move_Pulled(src)
/turf/proc/multiz_turf_del(turf/T, dir)
/turf/proc/multiz_turf_new(turf/T, dir)
//zPassIn doesn't necessarily pass an atom!
//direction is direction of travel of air
/turf/proc/zPassIn(atom/movable/A, direction, turf/source)
return FALSE
//direction is direction of travel of air
/turf/proc/zPassOut(atom/movable/A, direction, turf/destination)
return FALSE
//direction is direction of travel of air
/turf/proc/zAirIn(direction, turf/source)
return FALSE
//direction is direction of travel of air
/turf/proc/zAirOut(direction, turf/source)
return FALSE
/turf/proc/zImpact(atom/movable/A, levels = 1)
for(var/i in contents)
var/atom/thing = i
if(thing.intercept_zImpact(A, levels))
return FALSE
if(zFall(A, ++levels))
return FALSE
A.visible_message("<span class='danger'>[A] crashes into [src]!</span>")
A.onZImpact(src, levels)
return TRUE
/turf/proc/can_zFall(atom/movable/A, levels = 1, turf/target)
return zPassOut(A, DOWN, target) && target.zPassIn(A, DOWN, src)
/turf/proc/zFall(atom/movable/A, levels = 1, force = FALSE)
var/turf/target = get_step_multiz(src, DOWN)
if(!target || (!isobj(A) && !ismob(A)))
return FALSE
if(!force && (!can_zFall(A, levels, target) || !A.can_zFall(src, levels, target, DOWN)))
return FALSE
A.visible_message("<span class='danger'>[A] falls through [src]!</span>")
A.zfalling = TRUE
A.forceMove(target)
A.zfalling = FALSE
target.zImpact(A, levels)
return TRUE
/turf/proc/handleRCL(obj/item/twohanded/rcl/C, mob/user)
if(C.loaded)
for(var/obj/structure/cable/LC in src)
@@ -193,6 +256,8 @@
var/obj/O = AM
if(O.obj_flags & FROZEN)
O.make_unfrozen()
if(!AM.zfalling)
zFall(AM)
/turf/proc/is_plasteel_floor()
return FALSE
+2 -1
View File
@@ -462,7 +462,8 @@
message_admins("[kna] [msg][roles_to_ban[1] == "Server" ? "" : " Roles: [roles_to_ban.Join("\n")]"]")
if(applies_to_admins)
send2irc("BAN ALERT","[kn] [msg]")
create_message("note", player_ckey, null, reason, null, null, 0, 0, null, 0, severity)
var/note_reason = "Banned from [roles_to_ban[1] == "Server" ? "the server" : " Roles: [roles_to_ban.Join(", ")]"] [isnull(duration) ? "permanently" : "for [time_message]"] - [reason]"
create_message("note", player_ckey, admin_ckey, note_reason, null, null, 0, 0, null, 0, severity)
var/client/C = GLOB.directory[player_ckey]
var/datum/admin_help/AH = admin_ticket_log(player_ckey, msg)
var/appeal_url = "No ban appeal url set!"
+4 -4
View File
@@ -55,7 +55,7 @@
if(AH)
message_admins("[key_name_admin(src)] has started replying to [key_name_admin(C, 0, 0)]'s admin help.")
var/msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null
var/msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as message|null
if (!msg)
message_admins("[key_name_admin(src)] has cancelled their reply to [key_name_admin(C, 0, 0)]'s admin help.")
return
@@ -90,7 +90,7 @@
if(!ircreplyamount) //to prevent people from spamming irc
return
if(!msg)
msg = input(src,"Message:", "Private message to Administrator") as text|null
msg = input(src,"Message:", "Private message to Administrator") as message|null
if(!msg)
return
@@ -112,7 +112,7 @@
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message to [key_name(recipient, 0, 0)]") as text|null
msg = input(src,"Message:", "Private message to [key_name(recipient, 0, 0)]") as message|null
msg = trim(msg)
if(!msg)
return
@@ -191,7 +191,7 @@
spawn() //so we don't hold the caller proc up
var/sender = src
var/sendername = key
var/reply = input(recipient, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply
var/reply = input(recipient, msg,"Admin PM from-[sendername]", "") as message|null //show message and await a reply
if(recipient && reply)
if(sender)
recipient.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
@@ -789,3 +789,11 @@ Congratulations! You are now trained for invasive xenobiology research!"}
airlock_type = /obj/machinery/door/airlock/abductor
material_type = /obj/item/stack/sheet/mineral/abductor
noglass = TRUE
/obj/item/clothing/under/abductor
desc = "The most advanced form of jumpsuit known to reality, looks uncomfortable."
name = "alien jumpsuit"
icon_state = "abductor-suit"
item_state = "bl_suit"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 10, bio = 10, rad = 0, fire = 0, acid = 0)
can_adjust = 0
@@ -1,6 +1,6 @@
/datum/outfit/abductor
name = "Abductor Basic"
uniform = /obj/item/clothing/under/color/grey //they're greys gettit
uniform = /obj/item/clothing/under/abductor
shoes = /obj/item/clothing/shoes/combat
back = /obj/item/storage/backpack
ears = /obj/item/radio/headset/abductor
@@ -11,16 +11,15 @@
if(!istype(H)) // req_human could be done in can_sting stuff.
return
..()
var/datum/mutation/human/HM = GLOB.mutations_list[CHAMELEON]
if(HM in H.dna.mutations)
HM.force_lose(H)
if(H.dna.get_mutation(CHAMELEON))
H.dna.remove_mutation(CHAMELEON)
else
HM.force_give(H)
H.dna.add_mutation(CHAMELEON)
return TRUE
/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user)
if(user.has_dna())
var/mob/living/carbon/C = user
var/datum/mutation/human/HM = GLOB.mutations_list[CHAMELEON]
if(HM in C.dna.mutations)
HM.force_lose(C)
C.dna.remove_mutation(CHAMELEON)
+2 -2
View File
@@ -399,12 +399,12 @@ structure_check() searches for nearby cultist structures required for the invoca
continue
if(!A.anchored)
movedsomething = TRUE
if(do_teleport(A, T, forceMove = TRUE, channel = TELEPORT_CHANNEL_CULT))
if(do_teleport(A, target, forceMove = TRUE, channel = TELEPORT_CHANNEL_CULT))
movesuccess = TRUE
if(movedsomething)
..()
if(moveuserlater)
if(do_teleport(user, T, channel = TELEPORT_CHANNEL_CULT))
if(do_teleport(user, target, channel = TELEPORT_CHANNEL_CULT))
movesuccess = TRUE
if(movesuccess)
visible_message("<span class='warning'>There is a sharp crack of inrushing air, and everything above the rune disappears!</span>", null, "<i>You hear a sharp crack.</i>")
+6
View File
@@ -34,6 +34,12 @@
. = ..()
name_source = GLOB.commando_names
/datum/antagonist/ert/deathsquad/apply_innate_effects(mob/living/mob_override)
owner.add_trait(TRAIT_DISK_VERIFIER, DEATHSQUAD_TRAIT)
/datum/antagonist/ert/deathsquad/remove_innate_effects(mob/living/mob_override)
owner.remove_trait(TRAIT_DISK_VERIFIER, DEATHSQUAD_TRAIT)
/datum/antagonist/ert/security // kinda handled by the base template but here for completion
/datum/antagonist/ert/security/red
@@ -600,10 +600,7 @@ This is here to make the tiles around the station mininuke change when it's arme
if(!fake)
return
var/ghost = isobserver(user)
var/captain = user.mind && user.mind.assigned_role == "Captain"
var/nukie = user.mind && user.mind.has_antag_datum(/datum/antagonist/nukeop)
if(ghost || captain || nukie)
if(isobserver(user) || user.has_trait(TRAIT_DISK_VERIFIER) || (user.mind && user.mind.has_trait(TRAIT_DISK_VERIFIER)))
to_chat(user, "<span class='warning'>The serial numbers on [src] are incorrect.</span>")
/obj/item/disk/nuclear/attackby(obj/item/I, mob/living/user, params)
@@ -642,3 +639,7 @@ This is here to make the tiles around the station mininuke change when it's arme
/obj/item/disk/nuclear/fake
fake = TRUE
/obj/item/disk/nuclear/fake/obvious
name = "cheap plastic imitation of the nuclear authentication disk"
desc = "How anyone could mistake this for the real thing is beyond you."
+2 -1
View File
@@ -23,10 +23,12 @@
/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_synd_icons_added(M)
owner.add_trait(TRAIT_DISK_VERIFIER, NUKEOP_TRAIT)
/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
update_synd_icons_removed(M)
owner.remove_trait(TRAIT_DISK_VERIFIER, NUKEOP_TRAIT)
/datum/antagonist/nukeop/proc/equip_op()
if(!ishuman(owner.current))
@@ -42,7 +44,6 @@
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0)
to_chat(owner, "<span class='notice'>You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!</span>")
owner.announce_objectives()
return
/datum/antagonist/nukeop/on_gain()
give_alias()
@@ -70,7 +70,7 @@
/mob/living/simple_animal/revenant/Initialize(mapload)
. = ..()
AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null))
AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
AddSpell(new /obj/effect/proc_holder/spell/targeted/telepathy/revenant(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/blight(null))
@@ -106,36 +106,14 @@
action_background_icon_state = "bg_revenant"
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
name = "Transmit"
desc = "Telepathically transmits a message to the target."
/obj/effect/proc_holder/spell/targeted/telepathy/revenant
name = "Revenant Transmit"
panel = "Revenant Abilities"
charge_max = 0
clothes_req = 0
range = 7
include_user = 0
action_icon = 'icons/mob/actions/actions_revenant.dmi'
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
charge_counter = charge_max
return
log_directed_talk(user, M, msg, LOG_SAY, "revenant whisper")
to_chat(user, "<span class='revenboldnotice'>You transmit to [M]:</span> <span class='revennotice'>[msg]</span>")
if(!M.anti_magic_check(FALSE, TRUE)) //hear no evil
to_chat(M, "<span class='revenboldnotice'>You hear something behind you talking...</span> <span class='revennotice'>[msg]</span>")
for(var/ded in GLOB.dead_mob_list)
if(!isobserver(ded))
continue
var/follow_rev = FOLLOW_LINK(ded, user)
var/follow_whispee = FOLLOW_LINK(ded, M)
to_chat(ded, "[follow_rev] <span class='revenboldnotice'>[user] Revenant Transmit:</span> <span class='revennotice'>\"[msg]\" to</span> [follow_whispee] <span class='name'>[M]</span>")
notice = "revennotice"
boldnotice = "revenboldnotice"
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
@@ -25,5 +25,5 @@
return
H.dna.add_mutation(HULK)
H.dna.add_mutation(XRAY)
H.dna.add_mutation(COLDRES)
H.dna.add_mutation(SPACEMUT)
H.dna.add_mutation(TK)
@@ -247,6 +247,12 @@
category = "Assistance"
cost = 1
/datum/spellbook_entry/tap
name = "Soul Tap"
spell_type = /obj/effect/proc_holder/spell/self/tap
category = "Assistance"
cost = 3
/datum/spellbook_entry/spacetime_dist
name = "Spacetime Distortion"
spell_type = /obj/effect/proc_holder/spell/spacetime_dist
@@ -532,12 +538,12 @@
if(times>0)
. += "You cast it [times] times.<br>"
return .
/datum/spellbook_entry/summon/curse_of_madness
name = "Curse of Madness"
desc = "Curses the station, warping the minds of everyone inside, causing lasting traumas. Warning: this spell can affect you if not cast from a safe distance."
cost = 4
/datum/spellbook_entry/summon/curse_of_madness/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
active = TRUE
@@ -1,4 +1,6 @@
/atom/var/CanAtmosPass = ATMOS_PASS_YES
/atom/var/CanAtmosPassVertical = ATMOS_PASS_YES
/atom/proc/CanAtmosPass(turf/T)
switch (CanAtmosPass)
if (ATMOS_PASS_PROC)
@@ -8,42 +10,45 @@
else
return CanAtmosPass
/turf/closed/CanAtmosPass = ATMOS_PASS_NO
/turf/CanAtmosPass = ATMOS_PASS_NO
/turf/CanAtmosPassVertical = ATMOS_PASS_NO
/turf/open/CanAtmosPass = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T)
var/R
/turf/open/CanAtmosPassVertical = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = dir_inverse_multiz(dir)
var/R = FALSE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
R = TRUE
if(blocks_air || T.blocks_air)
R = 1
R = TRUE
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!CANATMOSPASS(O, other))
R = 1
if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other))))
R = TRUE
if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
var/D = get_dir(src, T)
atmos_supeconductivity |= D
D = get_dir(T, src)
T.atmos_supeconductivity |= D
return 0 //no need to keep going, we got all we asked
atmos_supeconductivity |= dir
T.atmos_supeconductivity |= opp
return FALSE //no need to keep going, we got all we asked
atmos_supeconductivity &= ~get_dir(src, T)
T.atmos_supeconductivity &= ~get_dir(T, src)
atmos_supeconductivity &= ~dir
T.atmos_supeconductivity &= ~opp
return !R
/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
return 0
return FALSE
/turf/proc/CalculateAdjacentTurfs()
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
if(!T)
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
if(!isopenturf(T))
continue
if( !(blocks_air || T.blocks_air) && CANATMOSPASS(T, src) )
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (CANVERTICALATMOSPASS(T, src)) : (CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE
@@ -72,11 +77,13 @@
var/turf/curloc = src
for (var/direction in GLOB.diagonals)
for (var/direction in GLOB.diagonals_multiz)
var/matchingDirections = 0
var/turf/S = get_step(curloc, direction)
var/turf/S = get_step_multiz(curloc, direction)
if(!S)
continue
for (var/checkDirection in GLOB.cardinals)
for (var/checkDirection in GLOB.cardinals_multiz)
var/turf/checkTurf = get_step(S, checkDirection)
if(!S.atmos_adjacent_turfs || !S.atmos_adjacent_turfs[checkTurf])
continue
@@ -42,8 +42,7 @@
/turf/open/Destroy()
if(active_hotspot)
qdel(active_hotspot)
active_hotspot = null
QDEL_NULL(active_hotspot)
// Adds the adjacent turfs to the current atmos processing
for(var/T in atmos_adjacent_turfs)
SSair.add_to_active(T)
@@ -121,10 +121,10 @@
/datum/gas/pluoxium = new/datum/tlv/no_checks
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
/obj/machinery/airalarm/kitchen_cold_room // Kitchen cold rooms start off at -80°C or 193.15°K.
TLV = list(
"pressure" = new/datum/tlv(ONE_ATMOSPHERE * 0.8, ONE_ATMOSPHERE* 0.9, ONE_ATMOSPHERE * 1.1, ONE_ATMOSPHERE * 1.2), // kPa
"temperature" = new/datum/tlv(T0C-73.15, T0C-63.15, T0C, T0C+10),
"temperature" = new/datum/tlv(T0C-273.15, T0C-100, T0C-60, T0C),
/datum/gas/oxygen = new/datum/tlv(16, 19, 135, 140), // Partial pressure, kpa
/datum/gas/nitrogen = new/datum/tlv(-1, -1, 1000, 1000),
/datum/gas/carbon_dioxide = new/datum/tlv(-1, -1, 5, 10),
@@ -178,6 +178,13 @@
if(target_temperature == initial(target_temperature))
target_temperature = min_temperature
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom
name = "cold room freezer"
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on/coldroom/Initialize()
. = ..()
target_temperature = T0C-80
/obj/machinery/atmospherics/components/unary/thermomachine/freezer/RefreshParts()
..()
var/L
@@ -94,7 +94,7 @@
to_chat(user, "<B>Your wish is granted, but at a terrible cost...</B>")
to_chat(user, "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart.")
user.dna.add_mutation(LASEREYES)
user.dna.add_mutation(COLDRES)
user.dna.add_mutation(SPACEMUT)
user.dna.add_mutation(XRAY)
user.set_species(/datum/species/shadow)
if("Wealth")
+1 -1
View File
@@ -55,7 +55,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "centcom_podlauncher", "Config/Launch Supplypod", 700, 700, master_ui, state)
ui = new(user, src, ui_key, "centcom_podlauncher", "Config/Launch Supplypod", 350, 700, master_ui, state)
ui.open()
/datum/centcom_podlauncher/ui_data(mob/user) //Sends info about the pod to the UI.
+2 -1
View File
@@ -1098,7 +1098,8 @@
/obj/item/reagent_containers/blood/BMinus,
/obj/item/reagent_containers/blood/OPlus,
/obj/item/reagent_containers/blood/OMinus,
/obj/item/reagent_containers/blood/lizard)
/obj/item/reagent_containers/blood/lizard,
/obj/item/reagent_containers/blood/ethereal)
crate_name = "blood freezer"
crate_type = /obj/structure/closet/crate/freezer

Some files were not shown because too many files have changed in this diff Show More