diff --git a/_maps/RandomRuins/SpaceRuins/crashedship.dmm b/_maps/RandomRuins/SpaceRuins/crashedship.dmm index 5016189876..4f118ee7fe 100644 --- a/_maps/RandomRuins/SpaceRuins/crashedship.dmm +++ b/_maps/RandomRuins/SpaceRuins/crashedship.dmm @@ -501,10 +501,7 @@ /area/awaymission/BMPship/Aft) "bI" = ( /obj/machinery/door/unpowered/shuttle, -/turf/open/floor/plasteel{ - icon_state = "carpetside"; - dir = 1 - }, +/turf/open/floor/carpet, /area/awaymission/BMPship/Fore) "bJ" = ( /obj/machinery/door/airlock/silver, @@ -808,7 +805,6 @@ /turf/closed/wall/mineral/titanium/overspace, /area/template_noop) "cG" = ( -/turf/open/floor/carpet, /turf/closed/wall/mineral/titanium/interior, /area/awaymission/BMPship/Fore) "cH" = ( @@ -2497,7 +2493,6 @@ /turf/open/floor/plating, /area/awaymission/BMPship/Aft) "ht" = ( -/turf/open/floor/plating, /turf/closed/wall/mineral/titanium/interior, /area/awaymission/BMPship/Aft) "hu" = ( diff --git a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm index 5b593e5b7f..cfc78c0dbf 100644 --- a/_maps/RandomRuins/SpaceRuins/deepstorage.dmm +++ b/_maps/RandomRuins/SpaceRuins/deepstorage.dmm @@ -3275,7 +3275,6 @@ /area/ruin/space/has_grav/deepstorage/power) "fY" = ( /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 4 }, /obj/structure/cable/yellow{ @@ -3396,7 +3395,6 @@ dir = 8 }, /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 4 }, /obj/structure/cable/yellow{ diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm index 8e636c03f9..ecbbb20daa 100644 --- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm @@ -4238,7 +4238,6 @@ "kk" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 4 }, /obj/machinery/light{ @@ -4338,7 +4337,6 @@ "kx" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 4 }, /turf/open/floor/plasteel/white, @@ -4418,11 +4416,9 @@ "kI" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/corner{ - icon_state = "warninglinecorner"; dir = 1 }, /obj/effect/turf_decal/stripes/corner{ - icon_state = "warninglinecorner"; dir = 4 }, /turf/open/floor/plasteel/white, @@ -4431,7 +4427,6 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/corner, /obj/effect/turf_decal/stripes/corner{ - icon_state = "warninglinecorner"; dir = 8 }, /turf/open/floor/plasteel/white, diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/moonoutpost19.dmm index 4c9a995864..66b2ffcb8a 100644 --- a/_maps/RandomZLevels/moonoutpost19.dmm +++ b/_maps/RandomZLevels/moonoutpost19.dmm @@ -28445,14 +28445,14 @@ ab ab ab ab -of -oj ab -op -oz ab -oE -oO +ab +ab +ab +ab +ab +ab ab aa aa @@ -28702,13 +28702,13 @@ ab ab ab ab -og -oi -ab -oq ab ab -oF +ab +ab +ab +ab +ab ab ab aa @@ -28959,14 +28959,14 @@ ab ab ab ab -oh -ok ab ab -oA ab ab -oP +ab +ab +ab +ab ab aa aa @@ -29216,14 +29216,14 @@ ab ab ab ab -oi -ol ab -or -oB ab -oG -oQ +ab +ab +ab +ab +ab +ab ab aa aa @@ -29473,14 +29473,14 @@ ab ab ab ab -oi -om ab -os -oC ab -oH -oR +ab +ab +ab +ab +ab +ab ab aa aa @@ -29730,13 +29730,13 @@ ab ab ab ab -oi -on -ab -ot ab ab -oI +ab +ab +ab +ab +ab ab ab aa @@ -29980,6 +29980,15 @@ ac ac ac ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -29987,15 +29996,6 @@ ab ab ab ab -oi -oo -ab -ou -oD -ab -oJ -oS -ab aa aa aa @@ -30237,6 +30237,15 @@ ac ac ac ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -30244,15 +30253,6 @@ ab ab ab ab -ab -ab -ab -ov -ab -ab -oK -ab -ab aa aa aa @@ -30494,15 +30494,15 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -30751,6 +30751,15 @@ ac ac ac ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -30758,15 +30767,6 @@ ab ab ab ab -ab -ab -ab -ow -ab -ab -oL -ab -ab aa aa aa @@ -31008,6 +31008,15 @@ ac ac ac ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -31015,15 +31024,6 @@ ab ab ab ab -ab -ab -ab -ox -ab -ab -oM -ab -ab aa aa aa @@ -31265,15 +31265,15 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -31522,6 +31522,15 @@ ac ac ac ac +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -31529,15 +31538,6 @@ ab ab ab ab -ab -ab -ab -oy -oy -ab -oN -oN -ab aa aa aa @@ -31779,15 +31779,15 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac +ac +ac +ac ab ab ab @@ -32039,12 +32039,12 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac ab ab ab @@ -32296,12 +32296,12 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac ab ab ab @@ -32553,12 +32553,12 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac ab ab ab @@ -32810,12 +32810,12 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac ab ab ab @@ -33067,12 +33067,12 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac ab ab ab @@ -33324,12 +33324,12 @@ ac ac ac ac -ab -ab -ab -ab -ab -ab +ac +ac +ac +ac +ac +ac ab ab ab diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm index bdf5091d25..0f8c2e70bb 100644 --- a/_maps/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/undergroundoutpost45.dmm @@ -33969,11 +33969,11 @@ ab ab ab ab -yJ -yN ab -yT -zd +ab +ab +ab +ab ab aa aa @@ -34226,10 +34226,10 @@ ab ab ab ab -yK -yM ab -yU +ab +ab +ab ab ab aa @@ -34483,11 +34483,11 @@ ab ab ab ab -yL -yO ab ab -ze +ab +ab +ab ab aa aa @@ -34740,11 +34740,11 @@ ab ab ab ab -yM -yP ab -yV -zf +ab +ab +ab +ab ab aa aa @@ -34997,11 +34997,11 @@ ab ab ab ab -yM -yQ ab -yW -zg +ab +ab +ab +ab ab aa aa @@ -35254,10 +35254,10 @@ ab ab ab ab -yM -yR ab -yX +ab +ab +ab ab ab aa @@ -35504,6 +35504,12 @@ ad ad ad ad +ad +ad +ad +ad +ad +ad ab ab ab @@ -35511,12 +35517,6 @@ ab ab ab ab -yM -yS -ab -yY -zh -ab aa aa aa @@ -35761,6 +35761,12 @@ ad ad ad ad +ad +ad +ad +ad +ad +ad ab ab ab @@ -35768,12 +35774,6 @@ ab ab ab ab -ab -ab -ab -yZ -ab -ab aa aa aa @@ -36018,12 +36018,12 @@ ad ad ad ad -ab -ab -ab -ab -ab -ab +ad +ad +ad +ad +ad +ad ab ab ab @@ -36275,6 +36275,12 @@ ad ad ad ad +ad +ad +ad +ad +ad +ad ab ab ab @@ -36282,12 +36288,6 @@ ab ab ab ab -ab -ab -ab -za -ab -ab aa aa aa @@ -36532,6 +36532,12 @@ ad ad ad ad +ad +ad +ad +ad +ad +ad ab ab ab @@ -36539,12 +36545,6 @@ ab ab ab ab -ab -ab -ab -zb -ab -ab aa aa aa @@ -36789,12 +36789,12 @@ ad ad ad ad -ab -ab -ab -ab -ab -ab +ad +ad +ad +ad +ad +ad ab ab ab @@ -37046,6 +37046,12 @@ ad ad ad ad +ad +ad +ad +ad +ad +ad ab ab ab @@ -37053,12 +37059,6 @@ ab ab ab ab -ab -ab -ab -yM -yM -ab aa aa aa @@ -37303,12 +37303,12 @@ ad ad ad ad -ab -ab -ab -ab -ab -ab +ad +ad +ad +ad +ad +ad ab ab ab @@ -37563,9 +37563,9 @@ ad ad ad ad -ab -ab -ab +ad +ad +ad ab ab ab @@ -37820,9 +37820,9 @@ ad ad ad ad -ab -ab -ab +ad +ad +ad ab ab ab @@ -38077,9 +38077,9 @@ ad ad ad ad -ab -ab -ab +ad +ad +ad ab ab ab @@ -38334,9 +38334,9 @@ ad ad ad ad -ab -ab -ab +ad +ad +ad ab ab ab @@ -38591,9 +38591,9 @@ ad ad ad ad -ab -ab -ab +ad +ad +ad ab ab ab @@ -38848,9 +38848,9 @@ ad ad ad ad -ab -ab -ab +ad +ad +ad ab ab ab diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 1437c84ad1..1db3e9697d 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -27778,6 +27778,7 @@ /obj/structure/table, /obj/item/folder/white, /obj/item/device/radio/headset/headset_med, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/white, /area/medical/chemistry) "boe" = ( @@ -40361,7 +40362,6 @@ /area/science/xenobiology) "bPE" = ( /obj/structure/table/reinforced, -/obj/item/clothing/gloves/color/latex, /obj/item/device/slime_scanner, /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -40390,7 +40390,6 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "bPH" = ( -/obj/machinery/chem_dispenser/constructable, /obj/machinery/requests_console{ department = "Science"; departmentType = 2; @@ -40401,6 +40400,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/structure/table/reinforced, +/obj/item/clothing/gloves/color/latex, +/obj/item/clothing/glasses/science, /turf/open/floor/plasteel, /area/science/xenobiology) "bPI" = ( @@ -58930,9 +58932,7 @@ /turf/open/floor/plasteel/white, /area/science/xenobiology) "cTZ" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (NORTH)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 1 }, /turf/open/floor/plasteel/white, diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index cf700888de..95256fae4c 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -73609,8 +73609,8 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "cOM" = ( -/obj/machinery/chem_dispenser/constructable, /obj/effect/turf_decal/delivery, +/obj/machinery/chem_master, /turf/open/floor/plasteel, /area/science/xenobiology) "cON" = ( @@ -77224,6 +77224,7 @@ /obj/structure/table/glass, /obj/item/clipboard, /obj/item/toy/figure/chemist, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/whiteyellow/corner{ dir = 1 }, @@ -141433,7 +141434,7 @@ ecI cJK cLq cNa -cOL +cYG cQH cRX cTK diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 3058201916..26bc13dde1 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -59764,6 +59764,7 @@ dir = 1; pixel_y = -24 }, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/whiteyellow{ dir = 4 }, @@ -81419,13 +81420,6 @@ /area/science/xenobiology) "dce" = ( /obj/structure/table/glass, -/obj/item/storage/box/beakers{ - pixel_x = 2; - pixel_y = 7 - }, -/obj/item/storage/box/syringes{ - pixel_y = 5 - }, /obj/item/storage/box/monkeycubes{ pixel_x = 2; pixel_y = -2 @@ -81782,8 +81776,15 @@ }, /area/science/xenobiology) "dcL" = ( -/obj/machinery/chem_dispenser/constructable, /obj/machinery/light, +/obj/structure/table/glass, +/obj/item/storage/box/beakers{ + pixel_x = 2; + pixel_y = 7 + }, +/obj/item/storage/box/syringes{ + pixel_y = 5 + }, /turf/open/floor/plasteel/whitepurple/side, /area/science/xenobiology) "dcM" = ( diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 777ae4d710..154df34231 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -9126,7 +9126,6 @@ /area/hallway/primary/central) "awl" = ( /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 1 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -16174,9 +16173,7 @@ pixel_y = -5; req_access_txt = "17" }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 2 }, /turf/open/floor/plasteel/blue/corner, @@ -16834,9 +16831,7 @@ d2 = 2; icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (NORTH)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 1 }, /turf/open/floor/plasteel, @@ -30295,9 +30290,7 @@ dir = 8; network = list("SS13","RD") }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 2 }, /turf/open/floor/plasteel/white, @@ -32792,6 +32785,7 @@ /obj/item/hand_labeler, /obj/item/device/radio/headset/headset_med, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/item/circuitboard/machine/smoke_machine, /turf/open/floor/plasteel/white, /area/medical/chemistry) "bwW" = ( @@ -33324,9 +33318,7 @@ dir = 4; pixel_x = 11 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (WEST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 8 }, /turf/open/floor/plasteel/white, @@ -34762,9 +34754,7 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 27 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (WEST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 8 }, /obj/machinery/door/firedoor, @@ -38582,9 +38572,7 @@ /obj/structure/sign/nosmoking_2{ pixel_y = -32 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (NORTH)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 1 }, /turf/open/floor/engine, @@ -38954,9 +38942,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 2 }, /turf/open/floor/plasteel/green/side, @@ -39131,9 +39117,7 @@ /obj/effect/turf_decal/stripes/end{ dir = 1 }, -/turf/open/floor/plating{ - icon_state = "plating_warn_end" - }, +/turf/open/floor/plating, /area/science/mineral_storeroom) "bJW" = ( /obj/machinery/light{ @@ -42151,9 +42135,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 2 }, /turf/open/floor/plasteel/black, @@ -42169,9 +42151,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (NORTH)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 1 }, /turf/open/floor/plasteel/black, @@ -42784,9 +42764,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (WEST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 8 }, /turf/open/floor/plasteel/black, @@ -42806,9 +42784,7 @@ dir = 4 }, /obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (EAST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 4 }, /turf/open/floor/plasteel/black, @@ -45603,9 +45579,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (WEST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 8 }, /turf/open/floor/plasteel, @@ -45720,9 +45694,7 @@ dir = 1; pixel_y = 29 }, -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (EAST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 4 }, /turf/open/floor/plasteel, @@ -46278,9 +46250,7 @@ /turf/open/floor/plasteel, /area/engine/engineering) "can" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 2 }, /turf/open/floor/plasteel, @@ -46373,9 +46343,7 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cav" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (NORTH)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 1 }, /turf/open/floor/plasteel, @@ -53351,9 +53319,7 @@ /turf/closed/wall, /area/library) "cxC" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (NORTH)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 1 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -53364,9 +53330,7 @@ }, /area/library) "cxD" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 2 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -53466,9 +53430,7 @@ /turf/closed/wall, /area/library) "cyz" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (EAST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -53479,9 +53441,7 @@ }, /area/library) "cyA" = ( -/obj/effect/turf_decal/stripes/line{ - tag = "icon-warninglinecorner (WEST)"; - icon_state = "warninglinecorner"; +/obj/effect/turf_decal/stripes/corner{ dir = 8 }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ diff --git a/_maps/shuttles/emergency_cere.dmm b/_maps/shuttles/emergency_cere.dmm index 8a280916e2..25ed35ba1c 100644 --- a/_maps/shuttles/emergency_cere.dmm +++ b/_maps/shuttles/emergency_cere.dmm @@ -428,7 +428,6 @@ /area/shuttle/escape) "bs" = ( /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 1 }, /obj/machinery/light{ @@ -443,7 +442,6 @@ /area/shuttle/escape) "bt" = ( /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 1 }, /turf/open/floor/plasteel, @@ -451,7 +449,6 @@ "bu" = ( /obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ - icon_state = "warningline"; dir = 1 }, /obj/structure/closet, diff --git a/_maps/shuttles/emergency_meteor.dmm b/_maps/shuttles/emergency_meteor.dmm index dcfd38acf8..014649014e 100644 --- a/_maps/shuttles/emergency_meteor.dmm +++ b/_maps/shuttles/emergency_meteor.dmm @@ -1,4 +1,4 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "a" = ( /turf/open/space, /area/space) @@ -50,18 +50,6 @@ "i" = ( /obj/effect/station_crash, /turf/open/floor/plating/asteroid, -/area/shuttle/escape{ - luminosity = 0 - }) -"j" = ( -/obj/docking_port/mobile/emergency{ - dwidth = 20; - height = 40; - name = "a meteor with engines strapped to it"; - timid = 1; - width = 40 - }, -/turf/open/floor/plating/asteroid, /area/shuttle/escape{ luminosity = 0 }) @@ -89,6 +77,19 @@ "n" = ( /obj/structure/shuttle/engine/propulsion, /turf/open/floor/plating/airless, +/area/shuttle/escape{ + luminosity = 0 + }) +"L" = ( +/obj/docking_port/mobile/emergency{ + dwidth = 20; + height = 40; + movement_force = list("KNOCKDOWN" = 3, "THROW" = 6); + name = "a meteor with engines strapped to it"; + timid = 1; + width = 40 + }, +/turf/open/floor/plating/asteroid, /area/shuttle/escape{ luminosity = 0 }) @@ -114,7 +115,7 @@ b d d d -j +L d d b diff --git a/code/__DEFINES/_tick.dm b/code/__DEFINES/_tick.dm index 93ac8ed70d..20eb648fe6 100644 --- a/code/__DEFINES/_tick.dm +++ b/code/__DEFINES/_tick.dm @@ -1,5 +1,5 @@ #define TICK_LIMIT_RUNNING 80 -#define TICK_LIMIT_TO_RUN 78 +#define TICK_LIMIT_TO_RUN 70 #define TICK_LIMIT_MC 70 #define TICK_LIMIT_MC_INIT_DEFAULT 98 diff --git a/code/__DEFINES/diseases.dm b/code/__DEFINES/diseases.dm new file mode 100644 index 0000000000..58d8066e9c --- /dev/null +++ b/code/__DEFINES/diseases.dm @@ -0,0 +1,26 @@ +//Visibility Flags +#define HIDDEN_SCANNER 1 +#define HIDDEN_PANDEMIC 2 + +//Disease Flags +#define CURABLE 1 +#define CAN_CARRY 2 +#define CAN_RESIST 4 + +//Spread Flags +#define VIRUS_SPREAD_SPECIAL 1 +#define VIRUS_SPREAD_NON_CONTAGIOUS 2 +#define VIRUS_SPREAD_BLOOD 4 +#define VIRUS_SPREAD_CONTACT_FLUIDS 8 +#define VIRUS_SPREAD_CONTACT_SKIN 16 +#define VIRUS_SPREAD_AIRBORNE 32 + + +//Severity Defines +#define VIRUS_SEVERITY_POSITIVE "Positive" //Diseases that buff, heal, or at least do nothing at all +#define VIRUS_SEVERITY_NONTHREAT "Harmless" //Diseases that may have annoying effects, but nothing disruptive (sneezing) +#define VIRUS_SEVERITY_MINOR "Minor" //Diseases that can annoy in concrete ways (dizziness) +#define VIRUS_SEVERITY_MEDIUM "Medium" //Diseases that can do minor harm, or severe annoyance (vomit) +#define VIRUS_SEVERITY_HARMFUL "Harmful" //Diseases that can do significant harm, or severe disruption (brainrot) +#define VIRUS_SEVERITY_DANGEROUS "Dangerous" //Diseases that can kill or maim if left untreated (flesh eating, blindness) +#define VIRUS_SEVERITY_BIOHAZARD "BIOHAZARD" //Diseases that can quickly kill an unprepared victim (fungal tb, gbs) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index c3da908ee1..04ce1bbe36 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -8,6 +8,8 @@ #define ismovableatom(A) (istype(A, /atom/movable)) +#define isatom(A) (istype(A, /atom)) + //Turfs //#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake. diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index 28017de85c..987d52e0cd 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -20,4 +20,8 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using #define HOURS MINUTES*60 -#define TICKS *world.tick_lag \ No newline at end of file +#define TICKS *world.tick_lag + +#define DS2TICKS(DS) (DS/world.tick_lag) + +#define TICKS2DS(T) (T TICKS) \ No newline at end of file diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index a16f91b317..caddfdf509 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -570,9 +570,12 @@ return hex2num(copytext(hexa, 6, 8)) /proc/lavaland_equipment_pressure_check(turf/T) + . = FALSE if(!istype(T)) return var/datum/gas_mixture/environment = T.return_air() + if(!istype(environment)) + return var/pressure = environment.return_pressure() if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE) - return TRUE + . = TRUE diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index de606b137e..4800f35b65 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -321,7 +321,7 @@ Proc for attack log creation, because really why not var/starttime = world.time . = 1 while (world.time < endtime) - stoplag() + stoplag(1) if (progress) progbar.update(world.time - starttime) if(QDELETED(user) || QDELETED(target)) @@ -382,7 +382,7 @@ Proc for attack log creation, because really why not var/starttime = world.time . = 1 while (world.time < endtime) - stoplag() + stoplag(1) if (progress) progbar.update(world.time - starttime) @@ -437,7 +437,7 @@ Proc for attack log creation, because really why not . = 1 mainloop: while(world.time < endtime) - sleep(1) + stoplag(1) if(progress) progbar.update(world.time - starttime) if(QDELETED(user) || !targets) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 6c7bb0cda6..473817e12c 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -504,10 +504,10 @@ Turf and target are separate in case you want to teleport some distance from a t /atom/proc/GetAllContents(list/output=list()) . = output - output += src - for(var/i in 1 to contents.len) - var/atom/thing = contents[i] - thing.GetAllContents(output) + output += src + for(var/i in 1 to contents.len) + var/atom/thing = contents[i] + thing.GetAllContents(output) //Step-towards method of determining whether one atom can see another. Similar to viewers() /proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. @@ -1225,16 +1225,19 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) //Increases delay as the server gets more overloaded, //as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful -#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta,1)), 1) +#define DELTA_CALC max(((max(TICK_USAGE, world.cpu) / 100) * max(Master.sleep_delta-1,1)), 1) -/proc/stoplag() +//returns the number of ticks slept +/proc/stoplag(initial_delay) if (!Master || !(Master.current_runlevel & RUNLEVELS_DEFAULT)) sleep(world.tick_lag) return 1 + if (!initial_delay) + initial_delay = world.tick_lag . = 0 - var/i = 1 + var/i = DS2TICKS(initial_delay) do - . += round(i*DELTA_CALC) + . += Ceiling(i*DELTA_CALC) sleep(i*world.tick_lag*DELTA_CALC) i *= 2 while (TICK_USAGE > min(TICK_LIMIT_TO_RUN, Master.current_ticklimit)) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index b92853a2c4..5607dde491 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -33,7 +33,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/init_time var/tickdrift = 0 - var/sleep_delta + var/sleep_delta = 1 var/make_runtime = 0 @@ -53,7 +53,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/restart_clear = 0 var/static/restart_timeout = 0 var/static/restart_count = 0 - + //current tick limit, assigned before running a subsystem. //used by CHECK_TICK as well so that the procs subsystems call can obey that SS's tick limits var/static/current_ticklimit = TICK_LIMIT_RUNNING @@ -276,35 +276,45 @@ GLOBAL_REAL(Master, /datum/controller/master) = new iteration = 1 var/error_level = 0 - var/sleep_delta = 0 + var/sleep_delta = 1 var/list/subsystems_to_check //the actual loop. + while (1) tickdrift = max(0, MC_AVERAGE_FAST(tickdrift, (((REALTIMEOFDAY - init_timeofday) - (world.time - init_time)) / world.tick_lag))) + var/starting_tick_usage = TICK_USAGE if (processing <= 0) current_ticklimit = TICK_LIMIT_RUNNING sleep(10) continue - //if there are mutiple sleeping procs running before us hogging the cpu, we have to run later - // because sleeps are processed in the order received, so longer sleeps are more likely to run first - if (TICK_USAGE > TICK_LIMIT_MC) - sleep_delta += 2 + //Anti-tick-contention heuristics: + //if there are mutiple sleeping procs running before us hogging the cpu, we have to run later. + // (because sleeps are processed in the order received, longer sleeps are more likely to run first) + if (starting_tick_usage > TICK_LIMIT_MC) //if there isn't enough time to bother doing anything this tick, sleep a bit. + sleep_delta *= 2 current_ticklimit = TICK_LIMIT_RUNNING * 0.5 - sleep(world.tick_lag * (processing + sleep_delta)) + sleep(world.tick_lag * (processing * sleep_delta)) continue - sleep_delta = MC_AVERAGE_FAST(sleep_delta, 0) - if (last_run + (world.tick_lag * processing) > world.time) - sleep_delta += 1 - if (TICK_USAGE > (TICK_LIMIT_MC*0.5)) + //Byond resumed us late. assume it might have to do the same next tick + if (last_run + Ceiling(world.tick_lag * (processing * sleep_delta), world.tick_lag) < world.time) sleep_delta += 1 + sleep_delta = MC_AVERAGE_FAST(sleep_delta, 1) //decay sleep_delta + + if (starting_tick_usage > (TICK_LIMIT_MC*0.75)) //we ran 3/4 of the way into the tick + sleep_delta += 1 + + //debug if (make_runtime) var/datum/controller/subsystem/SS SS.can_fire = 0 + if (!Failsafe || (Failsafe.processing_interval > 0 && (Failsafe.lasttick+(Failsafe.processing_interval*5)) < world.time)) new/datum/controller/failsafe() // (re)Start the failsafe. + + //now do the actual stuff if (!queue_head || !(iteration % 3)) var/checking_runlevel = current_runlevel if(cached_runlevel != checking_runlevel) @@ -321,6 +331,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new subsystems_to_check = current_runlevel_subsystems else subsystems_to_check = tickersubsystems + if (CheckQueue(subsystems_to_check) <= 0) if (!SoftReset(tickersubsystems, runlevel_sorted_subsystems)) log_world("MC: SoftReset() failed, crashing") @@ -351,8 +362,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new iteration++ last_run = world.time src.sleep_delta = MC_AVERAGE_FAST(src.sleep_delta, sleep_delta) - current_ticklimit = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc. - sleep(world.tick_lag * (processing + sleep_delta)) + current_ticklimit = TICK_LIMIT_RUNNING + if (processing * sleep_delta <= world.tick_lag) + current_ticklimit -= (TICK_LIMIT_RUNNING * 0.25) //reserve the tail 1/4 of the next tick for the mc if we plan on running next tick + sleep(world.tick_lag * (processing * sleep_delta)) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 02a9808f48..50e3dab667 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -118,8 +118,10 @@ SUBSYSTEM_DEF(ticker) if(isemptylist(music)) music = world.file2list(ROUND_START_MUSIC_LIST, "\n") - - login_music = pick(music) + login_music = pick(music) + else + login_music = "config/title_music/sounds/[pick(music)]" + if(!GLOB.syndicate_code_phrase) GLOB.syndicate_code_phrase = generate_code_phrase() diff --git a/code/datums/browser.dm b/code/datums/browser.dm index cae6e04e9b..48fb688e53 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -177,7 +177,7 @@ /datum/browser/alert/proc/wait() while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time)) - stoplag() + stoplag(1) /datum/browser/alert/Topic(href,href_list) if (href_list["close"] || !user || !user.client) diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm new file mode 100644 index 0000000000..cedede6b04 --- /dev/null +++ b/code/datums/components/infective.dm @@ -0,0 +1,13 @@ +/datum/component/infective + var/list/datum/disease/diseases //make sure these are the static, non-processing versions! + +/datum/component/infective/Initialize(list/datum/disease/_diseases) + RegisterSignal(COMSIG_MOVABLE_CROSSED, .proc/Infect) + diseases = _diseases + +/datum/component/infective/proc/Infect(atom/movable/AM) + var/mob/living/carbon/victim = AM + if(istype(victim)) + for(var/datum/disease/D in diseases) + victim.ContactContractDisease(D, "feet") + return TRUE \ No newline at end of file diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index d4b75e3892..0c025aab44 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -20,6 +20,7 @@ var/last_inserted_id var/last_amount_inserted var/last_insert_success + var/precise_insertion = FALSE var/datum/callback/precondition //MAX_STACK_SIZE = 50 //MINERAL_MATERIAL_AMOUNT = 2000 @@ -70,10 +71,21 @@ if(!has_space(material_amount)) to_chat(user, "[parent] is full. Please remove metal or glass from [parent] in order to insert more.") return + INVOKE_ASYNC(src, .proc/user_insert, I, user) + +/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user) + var/requested_amount + if(istype(I, /obj/item/stack) && precise_insertion) + var/atom/current_parent = parent + requested_amount = input(user, "How much do you want to insert?", "Inserting sheets") as num|null + if(isnull(requested_amount) || (requested_amount <= 0)) + return + if(QDELETED(I) || QDELETED(user) || QDELETED(src) || parent != current_parent || !user.canUseTopic(current_parent) || !user.is_holding(I) || !user.Adjacent(current_parent)) + return if(!user.temporarilyRemoveItemFromInventory(I)) to_chat(user, "[I] is stuck to you and cannot be placed into [parent].") return - var/inserted = insert_item(I) + var/inserted = insert_item(I, stack_amt = requested_amount) if(inserted) last_insert_success = TRUE if(istype(I, /obj/item/stack)) @@ -84,7 +96,7 @@ to_chat(user, "You insert a material total of [inserted] into [parent].") qdel(I) else - user.put_in_active_hand(I) + user.put_in_active_hand(I) //For inserting an amount of material /datum/component/material_container/proc/insert_amount(amt, id = null) @@ -101,21 +113,25 @@ M.amount += amt total_amount += amt return (total_amount - total_amount_saved) - return 0 + return FALSE /datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt = 0) + if(isnull(amt)) + amt = S.amount + if(amt <= 0) - return 0 + return FALSE + if(amt > S.amount) amt = S.amount var/material_amt = get_item_material_amount(S) if(!material_amt) - return 0 + return FALSE amt = min(amt, round(((max_amount - total_amount) / material_amt))) if(!amt) - return 0 + return FALSE last_inserted_id = insert_materials(S,amt) last_inserted_type = S.type @@ -123,16 +139,15 @@ last_amount_inserted = amt return amt -/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1) +/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt) if(!I) - return 0 + return FALSE if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - return insert_stack(I, S.amount) + return insert_stack(I, stack_amt) var/material_amount = get_item_material_amount(I) if(!material_amount || !has_space(material_amount)) - return 0 + return FALSE last_inserted_id = insert_materials(I, multiplier) last_inserted_type = I.type @@ -155,13 +170,13 @@ //mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200) /datum/component/material_container/proc/use_amount(list/mats, multiplier=1) if(!mats || !mats.len) - return 0 + return FALSE var/datum/material/M for(var/MAT in materials) M = materials[MAT] if(M.amount < (mats[MAT] * multiplier)) - return 0 + return FALSE var/total_amount_save = total_amount for(var/MAT in materials) @@ -179,7 +194,7 @@ M.amount -= amt total_amount -= amt return amt - return 0 + return FALSE /datum/component/material_container/proc/can_use_amount(amt, id, list/mats) if(amt && id) @@ -198,7 +213,7 @@ //For spawning mineral sheets; internal use only /datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null) if(!M.sheet_type) - return 0 + return FALSE if(sheet_amt > 0) if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT)) sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT) @@ -215,12 +230,12 @@ count += sheet_amt use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id) return count - return 0 + return FALSE /datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null) if(materials[id]) return retrieve(sheet_amt, materials[id], target) - return 0 + return FALSE /datum/component/material_container/proc/retrieve_amount(amt, id, target) return retrieve_sheets(amount2sheet(amt), id, target) @@ -238,24 +253,24 @@ /datum/component/material_container/proc/has_materials(list/mats, multiplier=1) if(!mats || !mats.len) - return 0 + return FALSE var/datum/material/M for(var/MAT in mats) M = materials[MAT] if(M.amount < (mats[MAT] * multiplier)) - return 0 - return 1 + return FALSE + return TRUE /datum/component/material_container/proc/amount2sheet(amt) if(amt >= MINERAL_MATERIAL_AMOUNT) return round(amt / MINERAL_MATERIAL_AMOUNT) - return 0 + return FALSE /datum/component/material_container/proc/sheet2amount(sheet_amt) if(sheet_amt > 0) return sheet_amt * MINERAL_MATERIAL_AMOUNT - return 0 + return FALSE /datum/component/material_container/proc/amount(id) var/datum/material/M = materials[id] @@ -265,7 +280,7 @@ //if this container does not support glass, any glass in 'I' will not be taken into account /datum/component/material_container/proc/get_item_material_amount(obj/item/I) if(!istype(I)) - return 0 + return FALSE var/material_amount = 0 for(var/MAT in materials) material_amount += I.materials[MAT] diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index a00d43ad8f..f13239a113 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -23,7 +23,7 @@ return 1 -/mob/proc/ContractDisease(datum/disease/D) +/mob/proc/ContactContractDisease(datum/disease/D) if(!CanContractDisease(D)) return 0 AddDisease(D) @@ -56,42 +56,31 @@ DD.affected_mob.med_hud_set_status() -/mob/living/carbon/ContractDisease(datum/disease/D) +/mob/living/carbon/ContactContractDisease(datum/disease/D, target_zone) if(!CanContractDisease(D)) return 0 var/obj/item/clothing/Cl = null - var/passed = 1 + var/passed = TRUE - var/head_ch = 100 + var/head_ch = 80 var/body_ch = 100 - var/hands_ch = 25 - var/feet_ch = 25 - - if(D.spread_flags & CONTACT_HANDS) - head_ch = 0 - body_ch = 0 - hands_ch = 100 - feet_ch = 0 - if(D.spread_flags & CONTACT_FEET) - head_ch = 0 - body_ch = 0 - hands_ch = 0 - feet_ch = 100 + var/hands_ch = 35 + var/feet_ch = 15 if(prob(15/D.permeability_mod)) return if(satiety>0 && prob(satiety/10)) // positive satiety makes it harder to contract the disease. return - - var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4) + if(!target_zone) + target_zone = pick(head_ch;"head",body_ch;"body",hands_ch;"hands",feet_ch;"feet") if(ishuman(src)) var/mob/living/carbon/human/H = src switch(target_zone) - if(1) + if("head") if(isobj(H.head) && !istype(H.head, /obj/item/paper)) Cl = H.head passed = prob((Cl.permeability_coefficient*100) - 1) @@ -101,14 +90,14 @@ if(passed && isobj(H.wear_neck)) Cl = H.wear_neck passed = prob((Cl.permeability_coefficient*100) - 1) - if(2) + if("body") if(isobj(H.wear_suit)) Cl = H.wear_suit passed = prob((Cl.permeability_coefficient*100) - 1) if(passed && isobj(slot_w_uniform)) Cl = slot_w_uniform passed = prob((Cl.permeability_coefficient*100) - 1) - if(3) + if("hands") if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS) Cl = H.wear_suit passed = prob((Cl.permeability_coefficient*100) - 1) @@ -116,7 +105,7 @@ if(passed && isobj(H.gloves)) Cl = H.gloves passed = prob((Cl.permeability_coefficient*100) - 1) - if(4) + if("feet") if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&FEET) Cl = H.wear_suit passed = prob((Cl.permeability_coefficient*100) - 1) @@ -128,19 +117,30 @@ else if(ismonkey(src)) var/mob/living/carbon/monkey/M = src switch(target_zone) - if(1) + if("head") if(M.wear_mask && isobj(M.wear_mask)) Cl = M.wear_mask passed = prob((Cl.permeability_coefficient*100) - 1) - if(!passed && (D.spread_flags & AIRBORNE) && !internal) - passed = (prob((50*D.permeability_mod) - 1)) - if(passed) AddDisease(D) +/mob/proc/AirborneContractDisease(datum/disease/D) + if((D.spread_flags & VIRUS_SPREAD_AIRBORNE) && prob((50*D.permeability_mod) - 1)) + ForceContractDisease(D) -//Same as ContractDisease, except never overidden clothes checks +/mob/living/carbon/AirborneContractDisease(datum/disease/D) + if(internal) + return + ..() + +/mob/living/carbon/human/AirborneContractDisease(datum/disease/D) + if(dna && (NOBREATH in dna.species.species_traits)) + return + ..() + + +//Proc to use when you 100% want to infect someone, as long as they aren't immune /mob/proc/ForceContractDisease(datum/disease/D) if(!CanContractDisease(D)) return 0 diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 13ad3ece4e..69da2ab96d 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -1,36 +1,8 @@ - -//Visibility Flags -#define HIDDEN_SCANNER 1 -#define HIDDEN_PANDEMIC 2 - -//Disease Flags -#define CURABLE 1 -#define CAN_CARRY 2 -#define CAN_RESIST 4 - -//Spread Flags -#define SPECIAL 1 -#define NON_CONTAGIOUS 2 -#define BLOOD 4 -#define CONTACT_FEET 8 -#define CONTACT_HANDS 16 -#define CONTACT_GENERAL 32 -#define AIRBORNE 64 - - -//Severity Defines -#define NONTHREAT "No threat" -#define MINOR "Minor" -#define MEDIUM "Medium" -#define HARMFUL "Harmful" -#define DANGEROUS "Dangerous!" -#define BIOHAZARD "BIOHAZARD THREAT!" - /datum/disease //Flags var/visibility_flags = 0 var/disease_flags = CURABLE|CAN_CARRY|CAN_RESIST - var/spread_flags = AIRBORNE + var/spread_flags = VIRUS_SPREAD_AIRBORNE | VIRUS_SPREAD_CONTACT_FLUIDS | VIRUS_SPREAD_CONTACT_SKIN //Fluff var/form = "Virus" @@ -54,7 +26,7 @@ var/carrier = FALSE //If our host is only a carrier var/bypasses_immunity = FALSE //Does it skip species virus immunity check? Some things may diseases and not viruses var/permeability_mod = 1 - var/severity = NONTHREAT + var/severity = VIRUS_SEVERITY_POSITIVE var/list/required_organs = list() var/needs_all_cures = TRUE var/list/strain_data = list() //dna_spread special bullshit @@ -95,25 +67,22 @@ if(!. || (needs_all_cures && . < cures.len)) return 0 - +//Airborne spreading /datum/disease/proc/spread(force_spread = 0) if(!affected_mob) return - if((spread_flags & SPECIAL || spread_flags & NON_CONTAGIOUS || spread_flags & BLOOD) && !force_spread) + if(!(spread_flags & VIRUS_SPREAD_AIRBORNE) && !force_spread) return if(affected_mob.reagents.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10))) return - var/spread_range = 1 + var/spread_range = 2 if(force_spread) spread_range = force_spread - if(spread_flags & AIRBORNE) - spread_range++ - var/turf/T = affected_mob.loc if(istype(T)) for(var/mob/living/carbon/C in oview(spread_range, affected_mob)) @@ -121,7 +90,7 @@ if(V) while(TRUE) if(V == T) - C.ContractDisease(src) + C.AirborneContractDisease(src) break var/turf/Temp = get_step_towards(V, T) if(!CANATMOSPASS(V, Temp)) @@ -129,10 +98,10 @@ V = Temp -/datum/disease/proc/cure() +/datum/disease/proc/cure(add_resistance = TRUE) if(affected_mob) if(disease_flags & CAN_RESIST) - if(!(type in affected_mob.resistances)) + if(add_resistance && !(type in affected_mob.resistances)) affected_mob.resistances += type remove_virus() qdel(src) @@ -152,12 +121,6 @@ /datum/disease/proc/GetDiseaseID() return type - -/datum/disease/proc/IsSpreadByTouch() - if(spread_flags & CONTACT_FEET || spread_flags & CONTACT_HANDS || spread_flags & CONTACT_GENERAL) - return 1 - return 0 - //don't use this proc directly. this should only ever be called by cure() /datum/disease/proc/remove_virus() affected_mob.viruses -= src //remove the datum from the list diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 062f5cddee..1070039f0c 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -183,19 +183,19 @@ properties["stealth"] += S.stealth properties["stage_rate"] += S.stage_speed properties["transmittable"] += S.transmittable - properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom + if(!S.neutered) + properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom return // Assign the properties that are in the list. /datum/disease/advance/proc/AssignProperties() if(properties && properties.len) - switch(properties["stealth"]) - if(2 to INFINITY) - visibility_flags = HIDDEN_SCANNER + if(properties["stealth"] >= 2) + visibility_flags = HIDDEN_SCANNER + + SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), VIRUS_SPREAD_BLOOD, VIRUS_SPREAD_AIRBORNE)) - // The more symptoms we have, the less transmittable it is but some symptoms can make up for it. - SetSpread(Clamp(2 ** (properties["transmittable"] - symptoms.len), BLOOD, AIRBORNE)) permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1) cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20 stage_prob = max(properties["stage_rate"], 2) @@ -208,35 +208,43 @@ // Assign the spread type and give it the correct description. /datum/disease/advance/proc/SetSpread(spread_id) switch(spread_id) - if(NON_CONTAGIOUS) + if(VIRUS_SPREAD_NON_CONTAGIOUS) + spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS spread_text = "None" - if(SPECIAL) + if(VIRUS_SPREAD_SPECIAL) + spread_flags = VIRUS_SPREAD_SPECIAL spread_text = "None" - if(CONTACT_GENERAL, CONTACT_HANDS, CONTACT_FEET) - spread_text = "On contact" - if(AIRBORNE) - spread_text = "Airborne" - if(BLOOD) + if(VIRUS_SPREAD_BLOOD) + spread_flags = VIRUS_SPREAD_BLOOD spread_text = "Blood" - - spread_flags = spread_id + if(VIRUS_SPREAD_CONTACT_FLUIDS) + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_FLUIDS + spread_text = "Fluids" + if(VIRUS_SPREAD_CONTACT_SKIN) + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_FLUIDS | VIRUS_SPREAD_CONTACT_SKIN + spread_text = "On contact" + if(VIRUS_SPREAD_AIRBORNE) + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_FLUIDS | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_AIRBORNE + spread_text = "Airborne" /datum/disease/advance/proc/SetSeverity(level_sev) switch(level_sev) if(-INFINITY to 0) - severity = NONTHREAT + severity = VIRUS_SEVERITY_POSITIVE if(1) - severity = MINOR + severity = VIRUS_SEVERITY_NONTHREAT if(2) - severity = MEDIUM + severity = VIRUS_SEVERITY_MINOR if(3) - severity = HARMFUL + severity = VIRUS_SEVERITY_MEDIUM if(4) - severity = DANGEROUS - if(5 to INFINITY) - severity = BIOHAZARD + severity = VIRUS_SEVERITY_HARMFUL + if(5) + severity = VIRUS_SEVERITY_DANGEROUS + if(6 to INFINITY) + severity = VIRUS_SEVERITY_BIOHAZARD else severity = "Unknown" diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm index 4829920d4f..4b12ec403c 100644 --- a/code/datums/diseases/advance/symptoms/choking.dm +++ b/code/datums/diseases/advance/symptoms/choking.dm @@ -94,7 +94,7 @@ Bonus stage_speed = -1 transmittable = -2 level = 7 - severity = 3 + severity = 6 base_message_chance = 15 symptom_delay_min = 14 symptom_delay_max = 30 diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index d3c3ea2da8..323f794eee 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -40,7 +40,7 @@ BONUS return if(A.properties["stealth"] >= 4) suppress_warning = TRUE - if(A.spread_flags &= AIRBORNE) //infect bystanders + if(A.spread_flags &= VIRUS_SPREAD_AIRBORNE) //infect bystanders infective = TRUE if(A.properties["resistance"] >= 3) //strong enough to drop items power = 1.5 diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm index 3bae01c7a7..c2afb34a9e 100644 --- a/code/datums/diseases/advance/symptoms/deafness.dm +++ b/code/datums/diseases/advance/symptoms/deafness.dm @@ -24,7 +24,7 @@ Bonus stage_speed = -1 transmittable = -3 level = 4 - severity = 3 + severity = 4 base_message_chance = 100 symptom_delay_min = 25 symptom_delay_max = 80 diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm index 836b4a4719..af1e460024 100644 --- a/code/datums/diseases/advance/symptoms/genetics.dm +++ b/code/datums/diseases/advance/symptoms/genetics.dm @@ -23,7 +23,7 @@ Bonus stage_speed = 0 transmittable = -3 level = 6 - severity = 3 + severity = 4 var/list/possible_mutations var/archived_dna = null base_message_chance = 50 diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm index 76b92159d8..5509f8b07b 100644 --- a/code/datums/diseases/advance/symptoms/hallucigen.dm +++ b/code/datums/diseases/advance/symptoms/hallucigen.dm @@ -23,7 +23,7 @@ Bonus stage_speed = -3 transmittable = -1 level = 5 - severity = 3 + severity = 2 base_message_chance = 25 symptom_delay_min = 25 symptom_delay_max = 90 diff --git a/code/datums/diseases/advance/symptoms/narcolepsy.dm b/code/datums/diseases/advance/symptoms/narcolepsy.dm index cc13d99406..24ba024aa6 100644 --- a/code/datums/diseases/advance/symptoms/narcolepsy.dm +++ b/code/datums/diseases/advance/symptoms/narcolepsy.dm @@ -22,7 +22,7 @@ Bonus level = 6 symptom_delay_min = 15 symptom_delay_max = 80 - severity = 5 + severity = 4 var/sleep_level = 0 var/sleepy_ticks = 0 var/stamina = FALSE diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index e7edcff703..df6bda1729 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -23,7 +23,6 @@ Bonus stage_speed = -4 transmittable = -3 level = 5 - severity = 0 symptom_delay_min = 5 symptom_delay_max = 10 var/purge_alcohol = FALSE diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm index 2f29091071..84f9ef49cc 100644 --- a/code/datums/diseases/advance/symptoms/vision.dm +++ b/code/datums/diseases/advance/symptoms/vision.dm @@ -24,7 +24,7 @@ Bonus stage_speed = -4 transmittable = -3 level = 5 - severity = 4 + severity = 5 base_message_chance = 50 symptom_delay_min = 25 symptom_delay_max = 80 diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm index e271bce5ed..14d7f105ab 100644 --- a/code/datums/diseases/advance/symptoms/vomit.dm +++ b/code/datums/diseases/advance/symptoms/vomit.dm @@ -28,7 +28,7 @@ Bonus stage_speed = 0 transmittable = 1 level = 3 - severity = 4 + severity = 3 base_message_chance = 100 symptom_delay_min = 25 symptom_delay_max = 80 diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index c9e610aa3b..f8f4343649 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -24,7 +24,7 @@ Bonus stage_speed = -2 transmittable = -2 level = 4 - severity = 1 + severity = 3 base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 45 @@ -75,7 +75,7 @@ Bonus stage_speed = -2 transmittable = -2 level = 3 - severity = 1 + severity = 3 base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 45 diff --git a/code/datums/diseases/anxiety.dm b/code/datums/diseases/anxiety.dm index 780cb0b1e5..4673d2e980 100644 --- a/code/datums/diseases/anxiety.dm +++ b/code/datums/diseases/anxiety.dm @@ -3,13 +3,13 @@ form = "Infection" max_stages = 4 spread_text = "On contact" - spread_flags = CONTACT_GENERAL + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS cure_text = "Ethanol" cures = list("ethanol") agent = "Excess Lepidopticides" viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) desc = "If left untreated subject will regurgitate butterflies." - severity = MEDIUM + severity = VIRUS_SEVERITY_MINOR /datum/disease/anxiety/stage_act() ..() diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index 8c681b8ec3..61d1519e7d 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -7,9 +7,9 @@ viable_mobtypes = list(/mob/living/carbon/human) permeability_mod = 1 desc = "If left untreated the subject will become very weak, and may vomit often." - severity = "Dangerous!" + severity = VIRUS_SEVERITY_MEDIUM disease_flags = CAN_CARRY|CAN_RESIST - spread_flags = NON_CONTAGIOUS + spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS visibility_flags = HIDDEN_PANDEMIC required_organs = list(/obj/item/organ/appendix) bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm index 5c9c9a1522..3a7e8cfbe3 100644 --- a/code/datums/diseases/beesease.dm +++ b/code/datums/diseases/beesease.dm @@ -1,40 +1,40 @@ -/datum/disease/beesease - name = "Beesease" - form = "Infection" - max_stages = 4 - spread_text = "On contact" - spread_flags = CONTACT_GENERAL - cure_text = "Sugar" - cures = list("sugar") - agent = "Apidae Infection" +/datum/disease/beesease + name = "Beesease" + form = "Infection" + max_stages = 4 + spread_text = "On contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Sugar" + cures = list("sugar") + agent = "Apidae Infection" viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - desc = "If left untreated subject will regurgitate bees." - severity = DANGEROUS - -/datum/disease/beesease/stage_act() - ..() - switch(stage) - if(2) //also changes say, see say.dm - if(prob(2)) - to_chat(affected_mob, "You taste honey in your mouth.") - if(3) - if(prob(10)) - to_chat(affected_mob, "Your stomach rumbles.") - if(prob(2)) - to_chat(affected_mob, "Your stomach stings painfully.") - if(prob(20)) - affected_mob.adjustToxLoss(2) - affected_mob.updatehealth() - if(4) - if(prob(10)) - affected_mob.visible_message("[affected_mob] buzzes.", \ - "Your stomach buzzes violently!") - if(prob(5)) - to_chat(affected_mob, "You feel something moving in your throat.") - if(prob(1)) - affected_mob.visible_message("[affected_mob] coughs up a swarm of bees!", \ - "You cough up a swarm of bees!") - new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc) - //if(5) - //Plus if you die, you explode into bees - return \ No newline at end of file + desc = "If left untreated subject will regurgitate bees." + severity = VIRUS_SEVERITY_MEDIUM + +/datum/disease/beesease/stage_act() + ..() + switch(stage) + if(2) //also changes say, see say.dm + if(prob(2)) + to_chat(affected_mob, "You taste honey in your mouth.") + if(3) + if(prob(10)) + to_chat(affected_mob, "Your stomach rumbles.") + if(prob(2)) + to_chat(affected_mob, "Your stomach stings painfully.") + if(prob(20)) + affected_mob.adjustToxLoss(2) + affected_mob.updatehealth() + if(4) + if(prob(10)) + affected_mob.visible_message("[affected_mob] buzzes.", \ + "Your stomach buzzes violently!") + if(prob(5)) + to_chat(affected_mob, "You feel something moving in your throat.") + if(prob(1)) + affected_mob.visible_message("[affected_mob] coughs up a swarm of bees!", \ + "You cough up a swarm of bees!") + new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc) + //if(5) + //Plus if you die, you explode into bees + return diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm index e830cafbef..576518b955 100644 --- a/code/datums/diseases/brainrot.dm +++ b/code/datums/diseases/brainrot.dm @@ -1,59 +1,59 @@ -/datum/disease/brainrot - name = "Brainrot" - max_stages = 4 - spread_text = "On contact" - spread_flags = CONTACT_GENERAL - cure_text = "Mannitol" - cures = list("mannitol") - agent = "Cryptococcus Cosmosis" - viable_mobtypes = list(/mob/living/carbon/human) - cure_chance = 15//higher chance to cure, since two reagents are required - desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication." +/datum/disease/brainrot + name = "Brainrot" + max_stages = 4 + spread_text = "On contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Mannitol" + cures = list("mannitol") + agent = "Cryptococcus Cosmosis" + viable_mobtypes = list(/mob/living/carbon/human) + cure_chance = 15//higher chance to cure, since two reagents are required + desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication." required_organs = list(/obj/item/organ/brain) - severity = DANGEROUS - -/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR - ..() - - switch(stage) - if(2) - if(prob(2)) - affected_mob.emote("blink") - if(prob(2)) - affected_mob.emote("yawn") - if(prob(2)) - to_chat(affected_mob, "You don't feel like yourself.") - if(prob(5)) - affected_mob.adjustBrainLoss(1) - affected_mob.updatehealth() - if(3) - if(prob(2)) - affected_mob.emote("stare") - if(prob(2)) - affected_mob.emote("drool") - if(prob(10) && affected_mob.getBrainLoss()<=98)//shouldn't retard you to death now - affected_mob.adjustBrainLoss(2) - affected_mob.updatehealth() - if(prob(2)) - to_chat(affected_mob, "Your try to remember something important...but can't.") - - if(4) - if(prob(2)) - affected_mob.emote("stare") - if(prob(2)) - affected_mob.emote("drool") - if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now - affected_mob.adjustBrainLoss(3) - affected_mob.updatehealth() - if(prob(2)) - to_chat(affected_mob, "Strange buzzing fills your head, removing all thoughts.") - if(prob(3)) - to_chat(affected_mob, "You lose consciousness...") - affected_mob.visible_message("[affected_mob] suddenly collapses") - affected_mob.Unconscious(rand(100,200)) - if(prob(1)) - affected_mob.emote("snore") - if(prob(15)) - affected_mob.stuttering += 3 - - return + severity = VIRUS_SEVERITY_HARMFUL + +/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR + ..() + + switch(stage) + if(2) + if(prob(2)) + affected_mob.emote("blink") + if(prob(2)) + affected_mob.emote("yawn") + if(prob(2)) + to_chat(affected_mob, "You don't feel like yourself.") + if(prob(5)) + affected_mob.adjustBrainLoss(1) + affected_mob.updatehealth() + if(3) + if(prob(2)) + affected_mob.emote("stare") + if(prob(2)) + affected_mob.emote("drool") + if(prob(10) && affected_mob.getBrainLoss()<=98)//shouldn't retard you to death now + affected_mob.adjustBrainLoss(2) + affected_mob.updatehealth() + if(prob(2)) + to_chat(affected_mob, "Your try to remember something important...but can't.") + + if(4) + if(prob(2)) + affected_mob.emote("stare") + if(prob(2)) + affected_mob.emote("drool") + if(prob(15) && affected_mob.getBrainLoss()<=98) //shouldn't retard you to death now + affected_mob.adjustBrainLoss(3) + affected_mob.updatehealth() + if(prob(2)) + to_chat(affected_mob, "Strange buzzing fills your head, removing all thoughts.") + if(prob(3)) + to_chat(affected_mob, "You lose consciousness...") + affected_mob.visible_message("[affected_mob] suddenly collapses") + affected_mob.Unconscious(rand(100,200)) + if(prob(1)) + affected_mob.emote("snore") + if(prob(15)) + affected_mob.stuttering += 3 + + return diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm index 468c9f2373..38b23cf3de 100644 --- a/code/datums/diseases/cold.dm +++ b/code/datums/diseases/cold.dm @@ -1,66 +1,65 @@ -/datum/disease/cold - name = "The Cold" - max_stages = 3 - spread_flags = AIRBORNE - cure_text = "Rest & Spaceacillin" - cures = list("spaceacillin") - agent = "XY-rhinovirus" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - permeability_mod = 0.5 - desc = "If left untreated the subject will contract the flu." - severity = MINOR - -/datum/disease/cold/stage_act() - ..() - switch(stage) - if(2) -/* - if(affected_mob.sleeping && prob(40)) //removed until sleeping is fixed - to_chat(affected_mob, "\blue You feel better.") - cure() - return -*/ - if(affected_mob.lying && prob(40)) //changed FROM prob(10) until sleeping is fixed - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1) && prob(5)) - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(1)) - to_chat(affected_mob, "Mucous runs down the back of your throat.") - if(3) -/* - if(affected_mob.sleeping && prob(25)) //removed until sleeping is fixed - to_chat(affected_mob, "\blue You feel better.") - cure() - return -*/ - if(affected_mob.lying && prob(25)) //changed FROM prob(5) until sleeping is fixed - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1) && prob(1)) - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(1)) - to_chat(affected_mob, "Mucous runs down the back of your throat.") - if(prob(1) && prob(50)) - if(!affected_mob.resistances.Find(/datum/disease/flu)) - var/datum/disease/Flu = new /datum/disease/flu(0) - affected_mob.ContractDisease(Flu) - cure() \ No newline at end of file +/datum/disease/cold + name = "The Cold" + max_stages = 3 + cure_text = "Rest & Spaceacillin" + cures = list("spaceacillin") + agent = "XY-rhinovirus" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + permeability_mod = 0.5 + desc = "If left untreated the subject will contract the flu." + severity = VIRUS_SEVERITY_NONTHREAT + +/datum/disease/cold/stage_act() + ..() + switch(stage) + if(2) +/* + if(affected_mob.sleeping && prob(40)) //removed until sleeping is fixed + to_chat(affected_mob, "\blue You feel better.") + cure() + return +*/ + if(affected_mob.lying && prob(40)) //changed FROM prob(10) until sleeping is fixed + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1) && prob(5)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(1)) + to_chat(affected_mob, "Mucous runs down the back of your throat.") + if(3) +/* + if(affected_mob.sleeping && prob(25)) //removed until sleeping is fixed + to_chat(affected_mob, "\blue You feel better.") + cure() + return +*/ + if(affected_mob.lying && prob(25)) //changed FROM prob(5) until sleeping is fixed + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1) && prob(1)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(1)) + to_chat(affected_mob, "Mucous runs down the back of your throat.") + if(prob(1) && prob(50)) + if(!affected_mob.resistances.Find(/datum/disease/flu)) + var/datum/disease/Flu = new /datum/disease/flu(0) + affected_mob.ForceContractDisease(Flu) + cure() diff --git a/code/datums/diseases/cold9.dm b/code/datums/diseases/cold9.dm index a875130709..4b65fee700 100644 --- a/code/datums/diseases/cold9.dm +++ b/code/datums/diseases/cold9.dm @@ -1,39 +1,39 @@ -/datum/disease/cold9 - name = "The Cold" - max_stages = 3 - spread_text = "On contact" - spread_flags = CONTACT_GENERAL - cure_text = "Common Cold Anti-bodies & Spaceacillin" - cures = list("spaceacillin") - agent = "ICE9-rhinovirus" - viable_mobtypes = list(/mob/living/carbon/human) - desc = "If left untreated the subject will slow, as if partly frozen." - severity = MEDIUM - -/datum/disease/cold9/stage_act() - ..() - switch(stage) - if(2) - affected_mob.bodytemperature -= 10 - if(prob(1) && prob(10)) - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(5)) - to_chat(affected_mob, "You feel stiff.") - if(3) - affected_mob.bodytemperature -= 20 - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(10)) - to_chat(affected_mob, "You feel stiff.") \ No newline at end of file +/datum/disease/cold9 + name = "The Cold" + max_stages = 3 + spread_text = "On contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Common Cold Anti-bodies & Spaceacillin" + cures = list("spaceacillin") + agent = "ICE9-rhinovirus" + viable_mobtypes = list(/mob/living/carbon/human) + desc = "If left untreated the subject will slow, as if partly frozen." + severity = VIRUS_SEVERITY_HARMFUL + +/datum/disease/cold9/stage_act() + ..() + switch(stage) + if(2) + affected_mob.bodytemperature -= 10 + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(5)) + to_chat(affected_mob, "You feel stiff.") + if(3) + affected_mob.bodytemperature -= 20 + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(10)) + to_chat(affected_mob, "You feel stiff.") diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index c96a22d472..fefdabd9c8 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -2,7 +2,7 @@ name = "Space Retrovirus" max_stages = 4 spread_text = "On contact" - spread_flags = CONTACT_GENERAL + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS cure_text = "Mutadone" cures = list("mutadone") disease_flags = CAN_CARRY|CAN_RESIST|CURABLE @@ -11,7 +11,7 @@ var/datum/dna/original_dna = null var/transformed = 0 desc = "This disease transplants the genetic code of the initial vector into new hosts." - severity = MEDIUM + severity = VIRUS_SEVERITY_MEDIUM /datum/disease/dnaspread/stage_act() diff --git a/code/datums/diseases/fake_gbs.dm b/code/datums/diseases/fake_gbs.dm index 524bf8b4b2..e62a8b491d 100644 --- a/code/datums/diseases/fake_gbs.dm +++ b/code/datums/diseases/fake_gbs.dm @@ -1,32 +1,32 @@ -/datum/disease/fake_gbs - name = "GBS" - max_stages = 5 - spread_text = "On contact" - spread_flags = CONTACT_GENERAL - cure_text = "Synaptizine & Sulfur" - cures = list("synaptizine","sulfur") - agent = "Gravitokinetic Bipotential SADS-" +/datum/disease/fake_gbs + name = "GBS" + max_stages = 5 + spread_text = "On contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Synaptizine & Sulfur" + cures = list("synaptizine","sulfur") + agent = "Gravitokinetic Bipotential SADS-" viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - desc = "If left untreated death will occur." - severity = BIOHAZARD - -/datum/disease/fake_gbs/stage_act() - ..() - switch(stage) - if(2) - if(prob(1)) - affected_mob.emote("sneeze") - if(3) - if(prob(5)) - affected_mob.emote("cough") - else if(prob(5)) - affected_mob.emote("gasp") - if(prob(10)) - to_chat(affected_mob, "You're starting to feel very weak...") - if(4) - if(prob(10)) - affected_mob.emote("cough") - - if(5) - if(prob(10)) - affected_mob.emote("cough") + desc = "If left untreated death will occur." + severity = VIRUS_SEVERITY_BIOHAZARD + +/datum/disease/fake_gbs/stage_act() + ..() + switch(stage) + if(2) + if(prob(1)) + affected_mob.emote("sneeze") + if(3) + if(prob(5)) + affected_mob.emote("cough") + else if(prob(5)) + affected_mob.emote("gasp") + if(prob(10)) + to_chat(affected_mob, "You're starting to feel very weak...") + if(4) + if(prob(10)) + affected_mob.emote("cough") + + if(5) + if(prob(10)) + affected_mob.emote("cough") diff --git a/code/datums/diseases/flu.dm b/code/datums/diseases/flu.dm index 1f2596d2d3..206b61fb35 100644 --- a/code/datums/diseases/flu.dm +++ b/code/datums/diseases/flu.dm @@ -1,54 +1,54 @@ -/datum/disease/flu - name = "The Flu" - max_stages = 3 - spread_text = "Airborne" - cure_text = "Spaceacillin" - cures = list("spaceacillin") - cure_chance = 10 - agent = "H13N1 flu virion" +/datum/disease/flu + name = "The Flu" + max_stages = 3 + spread_text = "Airborne" + cure_text = "Spaceacillin" + cures = list("spaceacillin") + cure_chance = 10 + agent = "H13N1 flu virion" viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - permeability_mod = 0.75 - desc = "If left untreated the subject will feel quite unwell." - severity = MEDIUM - -/datum/disease/flu/stage_act() - ..() - switch(stage) - if(2) - if(affected_mob.lying && prob(20)) - to_chat(affected_mob, "You feel better.") - stage-- - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your muscles ache.") - if(prob(20)) - affected_mob.take_bodypart_damage(1) - if(prob(1)) - to_chat(affected_mob, "Your stomach hurts.") - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - - if(3) - if(affected_mob.lying && prob(15)) - to_chat(affected_mob, "You feel better.") - stage-- - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your muscles ache.") - if(prob(20)) - affected_mob.take_bodypart_damage(1) - if(prob(1)) - to_chat(affected_mob, "Your stomach hurts.") - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - return + permeability_mod = 0.75 + desc = "If left untreated the subject will feel quite unwell." + severity = VIRUS_SEVERITY_MINOR + +/datum/disease/flu/stage_act() + ..() + switch(stage) + if(2) + if(affected_mob.lying && prob(20)) + to_chat(affected_mob, "You feel better.") + stage-- + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your muscles ache.") + if(prob(20)) + affected_mob.take_bodypart_damage(1) + if(prob(1)) + to_chat(affected_mob, "Your stomach hurts.") + if(prob(20)) + affected_mob.adjustToxLoss(1) + affected_mob.updatehealth() + + if(3) + if(affected_mob.lying && prob(15)) + to_chat(affected_mob, "You feel better.") + stage-- + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your muscles ache.") + if(prob(20)) + affected_mob.take_bodypart_damage(1) + if(prob(1)) + to_chat(affected_mob, "Your stomach hurts.") + if(prob(20)) + affected_mob.adjustToxLoss(1) + affected_mob.updatehealth() + return diff --git a/code/datums/diseases/fluspanish.dm b/code/datums/diseases/fluspanish.dm index 99b6eb99e3..da75ef1db6 100644 --- a/code/datums/diseases/fluspanish.dm +++ b/code/datums/diseases/fluspanish.dm @@ -1,36 +1,36 @@ -/datum/disease/fluspanish - name = "Spanish inquisition Flu" - max_stages = 3 - spread_text = "Airborne" - cure_text = "Spaceacillin & Anti-bodies to the common flu" - cures = list("spaceacillin") - cure_chance = 10 - agent = "1nqu1s1t10n flu virion" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 0.75 - desc = "If left untreated the subject will burn to death for being a heretic." - severity = DANGEROUS - -/datum/disease/fluspanish/stage_act() - ..() - switch(stage) - if(2) - affected_mob.bodytemperature += 10 - if(prob(5)) - affected_mob.emote("sneeze") - if(prob(5)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "You're burning in your own skin!") - affected_mob.take_bodypart_damage(0,5) - - if(3) - affected_mob.bodytemperature += 20 - if(prob(5)) - affected_mob.emote("sneeze") - if(prob(5)) - affected_mob.emote("cough") - if(prob(5)) - to_chat(affected_mob, "You're burning in your own skin!") - affected_mob.take_bodypart_damage(0,5) - return +/datum/disease/fluspanish + name = "Spanish inquisition Flu" + max_stages = 3 + spread_text = "Airborne" + cure_text = "Spaceacillin & Anti-bodies to the common flu" + cures = list("spaceacillin") + cure_chance = 10 + agent = "1nqu1s1t10n flu virion" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 0.75 + desc = "If left untreated the subject will burn to death for being a heretic." + severity = VIRUS_SEVERITY_DANGEROUS + +/datum/disease/fluspanish/stage_act() + ..() + switch(stage) + if(2) + affected_mob.bodytemperature += 10 + if(prob(5)) + affected_mob.emote("sneeze") + if(prob(5)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "You're burning in your own skin!") + affected_mob.take_bodypart_damage(0,5) + + if(3) + affected_mob.bodytemperature += 20 + if(prob(5)) + affected_mob.emote("sneeze") + if(prob(5)) + affected_mob.emote("cough") + if(prob(5)) + to_chat(affected_mob, "You're burning in your own skin!") + affected_mob.take_bodypart_damage(0,5) + return diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index 20776d5f96..71e4064676 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -1,41 +1,41 @@ -/datum/disease/gbs - name = "GBS" - max_stages = 5 - spread_text = "On contact" - spread_flags = CONTACT_GENERAL - cure_text = "Synaptizine & Sulfur" - cures = list("synaptizine","sulfur") - cure_chance = 15//higher chance to cure, since two reagents are required - agent = "Gravitokinetic Bipotential SADS+" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 1 - severity = BIOHAZARD - -/datum/disease/gbs/stage_act() - ..() - switch(stage) - if(2) - if(prob(45)) - affected_mob.adjustToxLoss(5) - affected_mob.updatehealth() - if(prob(1)) - affected_mob.emote("sneeze") - if(3) - if(prob(5)) - affected_mob.emote("cough") - else if(prob(5)) - affected_mob.emote("gasp") - if(prob(10)) - to_chat(affected_mob, "You're starting to feel very weak...") - if(4) - if(prob(10)) - affected_mob.emote("cough") - affected_mob.adjustToxLoss(5) - affected_mob.updatehealth() - if(5) - to_chat(affected_mob, "Your body feels as if it's trying to rip itself open...") - if(prob(50)) - affected_mob.gib() - else - return \ No newline at end of file +/datum/disease/gbs + name = "GBS" + max_stages = 5 + spread_text = "On contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Synaptizine & Sulfur" + cures = list("synaptizine","sulfur") + cure_chance = 15//higher chance to cure, since two reagents are required + agent = "Gravitokinetic Bipotential SADS+" + viable_mobtypes = list(/mob/living/carbon/human) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + permeability_mod = 1 + severity = VIRUS_SEVERITY_BIOHAZARD + +/datum/disease/gbs/stage_act() + ..() + switch(stage) + if(2) + if(prob(45)) + affected_mob.adjustToxLoss(5) + affected_mob.updatehealth() + if(prob(1)) + affected_mob.emote("sneeze") + if(3) + if(prob(5)) + affected_mob.emote("cough") + else if(prob(5)) + affected_mob.emote("gasp") + if(prob(10)) + to_chat(affected_mob, "You're starting to feel very weak...") + if(4) + if(prob(10)) + affected_mob.emote("cough") + affected_mob.adjustToxLoss(5) + affected_mob.updatehealth() + if(5) + to_chat(affected_mob, "Your body feels as if it's trying to rip itself open...") + if(prob(50)) + affected_mob.gib() + else + return diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm index df7249c9c3..e82c24ba59 100644 --- a/code/datums/diseases/magnitis.dm +++ b/code/datums/diseases/magnitis.dm @@ -1,66 +1,66 @@ -/datum/disease/magnitis - name = "Magnitis" - max_stages = 4 - spread_text = "Airborne" - cure_text = "Iron" - cures = list("iron") - agent = "Fukkos Miracos" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 0.75 - desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field." - severity = MEDIUM - -/datum/disease/magnitis/stage_act() - ..() - switch(stage) - if(2) - if(prob(2)) - to_chat(affected_mob, "You feel a slight shock course through your body.") - if(prob(2)) - for(var/obj/M in orange(2,affected_mob)) +/datum/disease/magnitis + name = "Magnitis" + max_stages = 4 + spread_text = "Airborne" + cure_text = "Iron" + cures = list("iron") + agent = "Fukkos Miracos" + viable_mobtypes = list(/mob/living/carbon/human) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + permeability_mod = 0.75 + desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field." + severity = VIRUS_SEVERITY_MEDIUM + +/datum/disease/magnitis/stage_act() + ..() + switch(stage) + if(2) + if(prob(2)) + to_chat(affected_mob, "You feel a slight shock course through your body.") + if(prob(2)) + for(var/obj/M in orange(2,affected_mob)) if(!M.anchored && (M.flags_1 & CONDUCT_1)) - step_towards(M,affected_mob) - for(var/mob/living/silicon/S in orange(2,affected_mob)) - if(isAI(S)) - continue - step_towards(S,affected_mob) - if(3) - if(prob(2)) - to_chat(affected_mob, "You feel a strong shock course through your body.") - if(prob(2)) - to_chat(affected_mob, "You feel like clowning around.") - if(prob(4)) - for(var/obj/M in orange(4,affected_mob)) + step_towards(M,affected_mob) + for(var/mob/living/silicon/S in orange(2,affected_mob)) + if(isAI(S)) + continue + step_towards(S,affected_mob) + if(3) + if(prob(2)) + to_chat(affected_mob, "You feel a strong shock course through your body.") + if(prob(2)) + to_chat(affected_mob, "You feel like clowning around.") + if(prob(4)) + for(var/obj/M in orange(4,affected_mob)) if(!M.anchored && (M.flags_1 & CONDUCT_1)) - var/i - var/iter = rand(1,2) - for(i=0,iYou feel a powerful shock course through your body.") - if(prob(2)) - to_chat(affected_mob, "You query upon the nature of miracles.") - if(prob(8)) - for(var/obj/M in orange(6,affected_mob)) + var/i + var/iter = rand(1,2) + for(i=0,iYou feel a powerful shock course through your body.") + if(prob(2)) + to_chat(affected_mob, "You query upon the nature of miracles.") + if(prob(8)) + for(var/obj/M in orange(6,affected_mob)) if(!M.anchored && (M.flags_1 & CONDUCT_1)) - var/i - var/iter = rand(1,3) - for(i=0,iYou feel a little silly.") - if(2) - if(prob(10)) to_chat(affected_mob, "You start seeing rainbows.") - if(3) - if(prob(10)) to_chat(affected_mob, "Your thoughts are interrupted by a loud HONK!") - if(4) - if(prob(5)) affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) ) +/datum/disease/pierrot_throat + name = "Pierrot's Throat" + max_stages = 4 + spread_text = "Airborne" + cure_text = "Banana products, especially banana bread." + cures = list("banana") + cure_chance = 75 + agent = "H0NI<42 Virus" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 0.75 + desc = "If left untreated the subject will probably drive others to insanity." + severity = VIRUS_SEVERITY_MEDIUM + +/datum/disease/pierrot_throat/stage_act() + ..() + switch(stage) + if(1) + if(prob(10)) + to_chat(affected_mob, "You feel a little silly.") + if(2) + if(prob(10)) + to_chat(affected_mob, "You start seeing rainbows.") + if(3) + if(prob(10)) + to_chat(affected_mob, "Your thoughts are interrupted by a loud HONK!") + if(4) + if(prob(5)) + affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) ) diff --git a/code/datums/diseases/retrovirus.dm b/code/datums/diseases/retrovirus.dm index e962d51e32..303bc54b65 100644 --- a/code/datums/diseases/retrovirus.dm +++ b/code/datums/diseases/retrovirus.dm @@ -1,83 +1,83 @@ -/datum/disease/dna_retrovirus - name = "Retrovirus" - max_stages = 4 - spread_text = "Contact" - spread_flags = CONTACT_GENERAL - cure_text = "Rest or an injection of mutadone" - cure_chance = 6 - agent = "" - viable_mobtypes = list(/mob/living/carbon/human) - desc = "A DNA-altering retrovirus that scrambles the structural and unique enzymes of a host constantly." - severity = DANGEROUS - permeability_mod = 0.4 - stage_prob = 2 - var/SE - var/UI - var/restcure = 0 - - -/datum/disease/dna_retrovirus/New() - ..() - agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]" - if(prob(40)) - cures = list("mutadone") - else - restcure = 1 - - -/datum/disease/dna_retrovirus/stage_act() - ..() - switch(stage) - if(1) - if(restcure) - if(affected_mob.lying && prob(30)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(8)) - to_chat(affected_mob, "Your head hurts.") - if (prob(9)) - to_chat(affected_mob, "You feel a tingling sensation in your chest.") - if (prob(9)) - to_chat(affected_mob, "You feel angry.") - if(2) - if(restcure) - if(affected_mob.lying && prob(20)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(8)) - to_chat(affected_mob, "Your skin feels loose.") - if (prob(10)) - to_chat(affected_mob, "You feel very strange.") - if (prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head!") - affected_mob.Unconscious(40) - if (prob(4)) - to_chat(affected_mob, "Your stomach churns.") - if(3) - if(restcure) - if(affected_mob.lying && prob(20)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(10)) - to_chat(affected_mob, "Your entire body vibrates.") - - if (prob(35)) - if(prob(50)) - scramble_dna(affected_mob, 1, 0, rand(15,45)) - else - scramble_dna(affected_mob, 0, 1, rand(15,45)) - - if(4) - if(restcure) - if(affected_mob.lying && prob(5)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(60)) - if(prob(50)) - scramble_dna(affected_mob, 1, 0, rand(50,75)) - else - scramble_dna(affected_mob, 0, 1, rand(50,75)) \ No newline at end of file +/datum/disease/dna_retrovirus + name = "Retrovirus" + max_stages = 4 + spread_text = "Contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Rest or an injection of mutadone" + cure_chance = 6 + agent = "" + viable_mobtypes = list(/mob/living/carbon/human) + desc = "A DNA-altering retrovirus that scrambles the structural and unique enzymes of a host constantly." + severity = VIRUS_SEVERITY_HARMFUL + permeability_mod = 0.4 + stage_prob = 2 + var/SE + var/UI + var/restcure = 0 + + +/datum/disease/dna_retrovirus/New() + ..() + agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]" + if(prob(40)) + cures = list("mutadone") + else + restcure = 1 + + +/datum/disease/dna_retrovirus/stage_act() + ..() + switch(stage) + if(1) + if(restcure) + if(affected_mob.lying && prob(30)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(8)) + to_chat(affected_mob, "Your head hurts.") + if (prob(9)) + to_chat(affected_mob, "You feel a tingling sensation in your chest.") + if (prob(9)) + to_chat(affected_mob, "You feel angry.") + if(2) + if(restcure) + if(affected_mob.lying && prob(20)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(8)) + to_chat(affected_mob, "Your skin feels loose.") + if (prob(10)) + to_chat(affected_mob, "You feel very strange.") + if (prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head!") + affected_mob.Unconscious(40) + if (prob(4)) + to_chat(affected_mob, "Your stomach churns.") + if(3) + if(restcure) + if(affected_mob.lying && prob(20)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(10)) + to_chat(affected_mob, "Your entire body vibrates.") + + if (prob(35)) + if(prob(50)) + scramble_dna(affected_mob, 1, 0, rand(15,45)) + else + scramble_dna(affected_mob, 0, 1, rand(15,45)) + + if(4) + if(restcure) + if(affected_mob.lying && prob(5)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(60)) + if(prob(50)) + scramble_dna(affected_mob, 1, 0, rand(50,75)) + else + scramble_dna(affected_mob, 0, 1, rand(50,75)) diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm index 9cbb829061..855f1f44f0 100644 --- a/code/datums/diseases/rhumba_beat.dm +++ b/code/datums/diseases/rhumba_beat.dm @@ -1,44 +1,44 @@ -/datum/disease/rhumba_beat - name = "The Rhumba Beat" - max_stages = 5 - spread_text = "On contact" - spread_flags = CONTACT_GENERAL - cure_text = "Chick Chicky Boom!" - cures = list("plasma") - agent = "Unknown" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 1 - severity = BIOHAZARD - -/datum/disease/rhumba_beat/stage_act() - ..() - if(affected_mob.ckey == "rosham") +/datum/disease/rhumba_beat + name = "The Rhumba Beat" + max_stages = 5 + spread_text = "On contact" + spread_flags = VIRUS_SPREAD_BLOOD | VIRUS_SPREAD_CONTACT_SKIN | VIRUS_SPREAD_CONTACT_FLUIDS + cure_text = "Chick Chicky Boom!" + cures = list("plasma") + agent = "Unknown" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 1 + severity = VIRUS_SEVERITY_BIOHAZARD + +/datum/disease/rhumba_beat/stage_act() + ..() + if(affected_mob.ckey == "rosham") cure() - return - switch(stage) - if(2) - if(prob(45)) - affected_mob.adjustToxLoss(5) - affected_mob.updatehealth() - if(prob(1)) - to_chat(affected_mob, "You feel strange...") - if(3) - if(prob(5)) - to_chat(affected_mob, "You feel the urge to dance...") - else if(prob(5)) - affected_mob.emote("gasp") - else if(prob(10)) - to_chat(affected_mob, "You feel the need to chick chicky boom...") - if(4) - if(prob(10)) - affected_mob.emote("gasp") - to_chat(affected_mob, "You feel a burning beat inside...") - if(prob(20)) - affected_mob.adjustToxLoss(5) - affected_mob.updatehealth() - if(5) - to_chat(affected_mob, "Your body is unable to contain the Rhumba Beat...") - if(prob(50)) - affected_mob.gib() - else - return + return + switch(stage) + if(2) + if(prob(45)) + affected_mob.adjustToxLoss(5) + affected_mob.updatehealth() + if(prob(1)) + to_chat(affected_mob, "You feel strange...") + if(3) + if(prob(5)) + to_chat(affected_mob, "You feel the urge to dance...") + else if(prob(5)) + affected_mob.emote("gasp") + else if(prob(10)) + to_chat(affected_mob, "You feel the need to chick chicky boom...") + if(4) + if(prob(10)) + affected_mob.emote("gasp") + to_chat(affected_mob, "You feel a burning beat inside...") + if(prob(20)) + affected_mob.adjustToxLoss(5) + affected_mob.updatehealth() + if(5) + to_chat(affected_mob, "Your body is unable to contain the Rhumba Beat...") + if(prob(50)) + affected_mob.gib() + else + return diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index e5746c3f8b..0ff47f854d 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -1,241 +1,242 @@ -/datum/disease/transformation - name = "Transformation" - max_stages = 5 - spread_text = "Acute" - spread_flags = SPECIAL - cure_text = "A coder's love (theoretical)." - agent = "Shenanigans" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey, /mob/living/carbon/alien) - severity = HARMFUL - stage_prob = 10 - visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC - disease_flags = CURABLE - var/list/stage1 = list("You feel unremarkable.") - var/list/stage2 = list("You feel boring.") - var/list/stage3 = list("You feel utterly plain.") - var/list/stage4 = list("You feel white bread.") - var/list/stage5 = list("Oh the humanity!") - var/new_form = /mob/living/carbon/human - -/datum/disease/transformation/stage_act() - ..() - switch(stage) - if(1) - if (prob(stage_prob) && stage1) - to_chat(affected_mob, pick(stage1)) - if(2) - if (prob(stage_prob) && stage2) - to_chat(affected_mob, pick(stage2)) - if(3) - if (prob(stage_prob*2) && stage3) - to_chat(affected_mob, pick(stage3)) - if(4) - if (prob(stage_prob*2) && stage4) - to_chat(affected_mob, pick(stage4)) - if(5) - do_disease_transformation(affected_mob) - -/datum/disease/transformation/proc/do_disease_transformation(mob/living/affected_mob) - if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD) - if(stage5) - to_chat(affected_mob, pick(stage5)) - if(jobban_isbanned(affected_mob, new_form)) - affected_mob.death(1) - return - if(affected_mob.notransform) - return - affected_mob.notransform = 1 - for(var/obj/item/W in affected_mob.get_equipped_items()) - affected_mob.dropItemToGround(W) - for(var/obj/item/I in affected_mob.held_items) - affected_mob.dropItemToGround(I) - var/mob/living/new_mob = new new_form(affected_mob.loc) - if(istype(new_mob)) - new_mob.a_intent = INTENT_HARM - if(affected_mob.mind) - affected_mob.mind.transfer_to(new_mob) - else - new_mob.key = affected_mob.key - - new_mob.name = affected_mob.real_name - new_mob.real_name = new_mob.name - qdel(affected_mob) - - - -/datum/disease/transformation/jungle_fever - name = "Jungle Fever" - cure_text = "Bananas" - cures = list("banana") - spread_text = "Monkey Bites" - spread_flags = SPECIAL - viable_mobtypes = list(/mob/living/carbon/monkey, /mob/living/carbon/human) - permeability_mod = 1 - cure_chance = 1 - disease_flags = CAN_CARRY|CAN_RESIST - desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey." - severity = BIOHAZARD - stage_prob = 4 - visibility_flags = 0 - agent = "Kongey Vibrion M-909" - new_form = /mob/living/carbon/monkey - - stage1 = null - stage2 = null - stage3 = null - stage4 = list("Your back hurts.", "You breathe through your mouth.", - "You have a craving for bananas.", "Your mind feels clouded.") - stage5 = list("You feel like monkeying around.") - -/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob) - if(!ismonkey(affected_mob)) - SSticker.mode.add_monkey(affected_mob.mind) - affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) - -/datum/disease/transformation/jungle_fever/stage_act() - ..() - switch(stage) - if(2) - if(prob(2)) - to_chat(affected_mob, "Your [pick("back", "arm", "leg", "elbow", "head")] itches.") - if(3) - if(prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head.") - affected_mob.confused += 10 - if(4) - if(prob(3)) - affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh.")) - -/datum/disease/transformation/jungle_fever/cure() - SSticker.mode.remove_monkey(affected_mob.mind) - ..() - - -/datum/disease/transformation/robot - - name = "Robotic Transformation" - cure_text = "An injection of copper." - cures = list("copper") - cure_chance = 5 - agent = "R2D2 Nanomachines" - desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg." - severity = DANGEROUS - visibility_flags = 0 - stage1 = null - stage2 = list("Your joints feel stiff.", "Beep...boop..") - stage3 = list("Your joints feel very stiff.", "Your skin feels loose.", "You can feel something move...inside.") - stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.") - stage5 = list("Your skin feels as if it's about to burst off!") - new_form = /mob/living/silicon/robot - - -/datum/disease/transformation/robot/stage_act() - ..() - switch(stage) - if(3) - if (prob(8)) - affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop")) - if (prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head.") - affected_mob.Unconscious(40) - if(4) - if (prob(20)) - affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee...")) - - -/datum/disease/transformation/xeno - - name = "Xenomorph Transformation" - cure_text = "Spaceacillin & Glycerol" - cures = list("spaceacillin", "glycerol") - cure_chance = 5 - agent = "Rip-LEY Alien Microbes" - desc = "This disease changes the victim into a xenomorph." - severity = BIOHAZARD - visibility_flags = 0 - stage1 = null - stage2 = list("Your throat feels scratchy.", "Kill...") - stage3 = list("Your throat feels very scratchy.", "Your skin feels tight.", "You can feel something move...inside.") - stage4 = list("Your skin feels very tight.", "Your blood boils!", "You can feel... something...inside you.") - stage5 = list("Your skin feels as if it's about to burst off!") - new_form = /mob/living/carbon/alien/humanoid/hunter - -/datum/disease/transformation/xeno/stage_act() - ..() - switch(stage) - if(3) - if (prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head.") - affected_mob.Unconscious(40) - if(4) - if (prob(20)) - affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!")) - - -/datum/disease/transformation/slime - name = "Advanced Mutation Transformation" - cure_text = "frost oil" - cures = list("frostoil") - cure_chance = 80 - agent = "Advanced Mutation Toxin" - desc = "This highly concentrated extract converts anything into more of itself." - severity = BIOHAZARD - visibility_flags = 0 - stage1 = list("You don't feel very well.") - stage2 = list("Your skin feels a little slimy.") - stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") - stage4 = list("You are turning into a slime.") - stage5 = list("You have become a slime.") - new_form = /mob/living/simple_animal/slime/random - -/datum/disease/transformation/slime/stage_act() - ..() - switch(stage) - if(1) - if(ishuman(affected_mob) && affected_mob.dna && affected_mob.dna.species.id == "slime") - stage = 5 - if(3) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/human = affected_mob - if(human.dna.species.id != "slime") - human.set_species(/datum/species/jelly/slime) - -/datum/disease/transformation/corgi - name = "The Barkening" - cure_text = "Death" - cures = list("adminordrazine") - agent = "Fell Doge Majicks" - desc = "This disease transforms the victim into a corgi." - visibility_flags = 0 - stage1 = list("BARK.") - stage2 = list("You feel the need to wear silly hats.") - stage3 = list("Must... eat... chocolate....", "YAP") - stage4 = list("Visions of washing machines assail your mind!") - stage5 = list("AUUUUUU!!!") - new_form = /mob/living/simple_animal/pet/dog/corgi - -/datum/disease/transformation/corgi/stage_act() - ..() - switch(stage) - if(3) - if (prob(8)) - affected_mob.say(pick("YAP", "Woof!")) - if(4) - if (prob(20)) - affected_mob.say(pick("Bark!", "AUUUUUU")) - -/datum/disease/transformation/morph - name = "Gluttony's Blessing" - cure_text = "nothing" - cures = list("adminordrazine") - agent = "Gluttony's Blessing" - desc = "A 'gift' from somewhere terrible." - stage_prob = 20 - severity = BIOHAZARD - visibility_flags = 0 - stage1 = list("Your stomach rumbles.") - stage2 = list("Your skin feels saggy.") - stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") - stage4 = list("You're ravenous.") - stage5 = list("You have become a morph.") - new_form = /mob/living/simple_animal/hostile/morph +/datum/disease/transformation + name = "Transformation" + max_stages = 5 + spread_text = "Acute" + spread_flags = VIRUS_SPREAD_SPECIAL + cure_text = "A coder's love (theoretical)." + agent = "Shenanigans" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey, /mob/living/carbon/alien) + severity = VIRUS_SEVERITY_BIOHAZARD + stage_prob = 10 + visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC + disease_flags = CURABLE + var/list/stage1 = list("You feel unremarkable.") + var/list/stage2 = list("You feel boring.") + var/list/stage3 = list("You feel utterly plain.") + var/list/stage4 = list("You feel white bread.") + var/list/stage5 = list("Oh the humanity!") + var/new_form = /mob/living/carbon/human + +/datum/disease/transformation/stage_act() + ..() + switch(stage) + if(1) + if (prob(stage_prob) && stage1) + to_chat(affected_mob, pick(stage1)) + if(2) + if (prob(stage_prob) && stage2) + to_chat(affected_mob, pick(stage2)) + if(3) + if (prob(stage_prob*2) && stage3) + to_chat(affected_mob, pick(stage3)) + if(4) + if (prob(stage_prob*2) && stage4) + to_chat(affected_mob, pick(stage4)) + if(5) + do_disease_transformation(affected_mob) + +/datum/disease/transformation/proc/do_disease_transformation(mob/living/affected_mob) + if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD) + if(stage5) + to_chat(affected_mob, pick(stage5)) + if(jobban_isbanned(affected_mob, new_form)) + affected_mob.death(1) + return + if(affected_mob.notransform) + return + affected_mob.notransform = 1 + for(var/obj/item/W in affected_mob.get_equipped_items()) + affected_mob.dropItemToGround(W) + for(var/obj/item/I in affected_mob.held_items) + affected_mob.dropItemToGround(I) + var/mob/living/new_mob = new new_form(affected_mob.loc) + if(istype(new_mob)) + new_mob.a_intent = INTENT_HARM + if(affected_mob.mind) + affected_mob.mind.transfer_to(new_mob) + else + new_mob.key = affected_mob.key + + new_mob.name = affected_mob.real_name + new_mob.real_name = new_mob.name + qdel(affected_mob) + + + +/datum/disease/transformation/jungle_fever + name = "Jungle Fever" + cure_text = "Bananas" + cures = list("banana") + spread_text = "Monkey Bites" + spread_flags = VIRUS_SPREAD_SPECIAL + viable_mobtypes = list(/mob/living/carbon/monkey, /mob/living/carbon/human) + permeability_mod = 1 + cure_chance = 1 + disease_flags = CAN_CARRY|CAN_RESIST + desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey." + severity = VIRUS_SEVERITY_BIOHAZARD + stage_prob = 4 + visibility_flags = 0 + agent = "Kongey Vibrion M-909" + new_form = /mob/living/carbon/monkey + + stage1 = null + stage2 = null + stage3 = null + stage4 = list("Your back hurts.", "You breathe through your mouth.", + "You have a craving for bananas.", "Your mind feels clouded.") + stage5 = list("You feel like monkeying around.") + +/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob) + if(!ismonkey(affected_mob)) + SSticker.mode.add_monkey(affected_mob.mind) + affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) + +/datum/disease/transformation/jungle_fever/stage_act() + ..() + switch(stage) + if(2) + if(prob(2)) + to_chat(affected_mob, "Your [pick("back", "arm", "leg", "elbow", "head")] itches.") + if(3) + if(prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head.") + affected_mob.confused += 10 + if(4) + if(prob(3)) + affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh.")) + +/datum/disease/transformation/jungle_fever/cure() + SSticker.mode.remove_monkey(affected_mob.mind) + ..() + + +/datum/disease/transformation/robot + + name = "Robotic Transformation" + cure_text = "An injection of copper." + cures = list("copper") + cure_chance = 5 + agent = "R2D2 Nanomachines" + desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg." + severity = VIRUS_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = null + stage2 = list("Your joints feel stiff.", "Beep...boop..") + stage3 = list("Your joints feel very stiff.", "Your skin feels loose.", "You can feel something move...inside.") + stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.") + stage5 = list("Your skin feels as if it's about to burst off!") + new_form = /mob/living/silicon/robot + + +/datum/disease/transformation/robot/stage_act() + ..() + switch(stage) + if(3) + if (prob(8)) + affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop")) + if (prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head.") + affected_mob.Unconscious(40) + if(4) + if (prob(20)) + affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee...")) + + +/datum/disease/transformation/xeno + + name = "Xenomorph Transformation" + cure_text = "Spaceacillin & Glycerol" + cures = list("spaceacillin", "glycerol") + cure_chance = 5 + agent = "Rip-LEY Alien Microbes" + desc = "This disease changes the victim into a xenomorph." + severity = VIRUS_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = null + stage2 = list("Your throat feels scratchy.", "Kill...") + stage3 = list("Your throat feels very scratchy.", "Your skin feels tight.", "You can feel something move...inside.") + stage4 = list("Your skin feels very tight.", "Your blood boils!", "You can feel... something...inside you.") + stage5 = list("Your skin feels as if it's about to burst off!") + new_form = /mob/living/carbon/alien/humanoid/hunter + +/datum/disease/transformation/xeno/stage_act() + ..() + switch(stage) + if(3) + if (prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head.") + affected_mob.Unconscious(40) + if(4) + if (prob(20)) + affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!")) + + +/datum/disease/transformation/slime + name = "Advanced Mutation Transformation" + cure_text = "frost oil" + cures = list("frostoil") + cure_chance = 80 + agent = "Advanced Mutation Toxin" + desc = "This highly concentrated extract converts anything into more of itself." + severity = VIRUS_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("You don't feel very well.") + stage2 = list("Your skin feels a little slimy.") + stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") + stage4 = list("You are turning into a slime.") + stage5 = list("You have become a slime.") + new_form = /mob/living/simple_animal/slime/random + +/datum/disease/transformation/slime/stage_act() + ..() + switch(stage) + if(1) + if(ishuman(affected_mob) && affected_mob.dna && affected_mob.dna.species.id == "slime") + stage = 5 + if(3) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/human = affected_mob + if(human.dna.species.id != "slime") + human.set_species(/datum/species/jelly/slime) + +/datum/disease/transformation/corgi + name = "The Barkening" + cure_text = "Death" + cures = list("adminordrazine") + agent = "Fell Doge Majicks" + desc = "This disease transforms the victim into a corgi." + severity = VIRUS_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("BARK.") + stage2 = list("You feel the need to wear silly hats.") + stage3 = list("Must... eat... chocolate....", "YAP") + stage4 = list("Visions of washing machines assail your mind!") + stage5 = list("AUUUUUU!!!") + new_form = /mob/living/simple_animal/pet/dog/corgi + +/datum/disease/transformation/corgi/stage_act() + ..() + switch(stage) + if(3) + if (prob(8)) + affected_mob.say(pick("YAP", "Woof!")) + if(4) + if (prob(20)) + affected_mob.say(pick("Bark!", "AUUUUUU")) + +/datum/disease/transformation/morph + name = "Gluttony's Blessing" + cure_text = "nothing" + cures = list("adminordrazine") + agent = "Gluttony's Blessing" + desc = "A 'gift' from somewhere terrible." + stage_prob = 20 + severity = VIRUS_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("Your stomach rumbles.") + stage2 = list("Your skin feels saggy.") + stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") + stage4 = list("You're ravenous.") + stage5 = list("You have become a morph.") + new_form = /mob/living/simple_animal/hostile/morph diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm index c8e2a4609b..d8f1a41c76 100644 --- a/code/datums/diseases/tuberculosis.dm +++ b/code/datums/diseases/tuberculosis.dm @@ -10,7 +10,7 @@ cure_chance = 5//like hell are you getting out of hell desc = "A rare highly transmittable virulent virus. Few samples exist, rumoured to be carefully grown and cultured by clandestine bio-weapon specialists. Causes fever, blood vomiting, lung damage, weight loss, and fatigue." required_organs = list(/obj/item/organ/lungs) - severity = DANGEROUS + severity = VIRUS_SEVERITY_BIOHAZARD bypasses_immunity = TRUE // TB primarily impacts the lungs; it's also bacterial or fungal in nature; viral immunity should do nothing. /datum/disease/tuberculosis/stage_act() //it begins diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 66663162ee..cabf22b280 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -10,7 +10,7 @@ disease_flags = CAN_CARRY|CAN_RESIST|CURABLE permeability_mod = 0.75 desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." - severity = HARMFUL + severity = VIRUS_SEVERITY_HARMFUL required_organs = list(/obj/item/bodypart/head) /* diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index 9869b43d8f..b9ea00da22 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -61,14 +61,14 @@ GLOBAL_LIST_EMPTY(explosions) flash_range = min(GLOB.MAX_EX_FLASH_RANGE, flash_range) flame_range = min(GLOB.MAX_EX_FLAME_RANGE, flame_range) - //DO NOT REMOVE THIS SLEEP, IT BREAKS THINGS + //DO NOT REMOVE THIS STOPLAG, IT BREAKS THINGS //not sleeping causes us to ex_act() the thing that triggered the explosion //doing that might cause it to trigger another explosion //this is bad //I would make this not ex_act the thing that triggered the explosion, //but everything that explodes gives us their loc or a get_turf() //and somethings expect us to ex_act them so they can qdel() - sleep(1) //tldr, let the calling proc call qdel(src) before we explode + stoplag() //tldr, let the calling proc call qdel(src) before we explode EX_PREPROCESS_EXIT_CHECK diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm index 02e2d9614d..f489f99564 100644 --- a/code/datums/martial/wrestling.dm +++ b/code/datums/martial/wrestling.dm @@ -199,7 +199,7 @@ set waitfor = FALSE if (D) animate(D, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0) - sleep (15) + sleep(15) if (D) animate(D, transform = null, time = 1, loop = 0) @@ -258,7 +258,7 @@ D.pixel_y = 0 return 0 - sleep (1) + sleep(1) if (A && D) A.pixel_x = 0 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8f33465a57..3116be2ea1 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -551,11 +551,11 @@ text += "HEAD | not mindshielded | employee | headrev | rev" else if (src in SSticker.mode.head_revolutionaries) var/last_healthy_headrev = TRUE - for(var/I in SSticker.mode.head_revolutionaries) + for(var/datum/mind/I in SSticker.mode.head_revolutionaries) if(I == src) continue - var/mob/M = I - if((M.z in GLOB.station_z_levels) && !M.stat) + var/mob/M = I.current + if(M && (M.z in GLOB.station_z_levels) && !M.stat) last_healthy_headrev = FALSE break text += "head | not mindshielded | employee | [last_healthy_headrev ? "LAST " : ""]HEADREV | rev" @@ -1300,7 +1300,7 @@ if (istype(M)) for(var/datum/disease/transformation/jungle_fever/JF in M.viruses) JF.cure(0) - sleep(0) //because deleting of virus is doing throught spawn(0) //What + stoplag() //because deleting of virus is doing throught spawn(0) //What log_admin("[key_name(usr)] attempting to humanize [key_name(current)]") message_admins("[key_name_admin(usr)] attempting to humanize [key_name_admin(current)]") H = M.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index d1ca8b3890..82abe9b0b4 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -412,10 +412,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) . = ..() transfer_blood = rand(2, 4) -/turf/add_blood(list/blood_dna) +/turf/add_blood(list/blood_dna, list/datum/disease/diseases) var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src if(!B) - B = new /obj/effect/decal/cleanable/blood/splatter(src) + B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases) B.transfer_blood_dna(blood_dna) //give blood info to the blood decal. return 1 //we bloodied the floor @@ -524,7 +524,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = 0) if(isturf(src)) - var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src) + var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses()) // Make toxins vomit look different if(toxvomit) V.icon_state = "vomittox_[pick(1,4)]" diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index ab329dfd29..2cee1d595c 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -61,16 +61,12 @@ //called when a carbon changes virus /mob/living/carbon/proc/check_virus() - var/threat = 0 + var/threat for(var/thing in viruses) var/datum/disease/D = thing if(!(D.visibility_flags & HIDDEN_SCANNER)) - if (D.severity != NONTHREAT) //a buffing virus gets an icon - threat = 2 - return threat //harmful viruses have priority - else - threat = 1 //aka good virus - + if(!threat || D.severity > threat) //a buffing virus gets an icon + threat = D.severity return threat //helper for getting the appropriate health status @@ -162,21 +158,30 @@ /mob/living/carbon/med_hud_set_status() var/image/holder = hud_list[STATUS_HUD] var/icon/I = icon(icon, icon_state, dir) - var/virus_state = check_virus() - var/mob/living/simple_animal/borer/B = has_brain_worms() + var/virus_threat = check_virus() holder.pixel_y = I.Height() - world.icon_size if(status_flags & XENO_HOST) holder.icon_state = "hudxeno" else if(stat == DEAD || (status_flags & FAKEDEATH)) holder.icon_state = "huddead" - else if(has_brain_worms() && B != null && B.controlling) - holder.icon_state = "hudbrainworm" - else if(virus_state == 2) - holder.icon_state = "hudill" - else if(virus_state == 1) - holder.icon_state = "hudbuff" else - holder.icon_state = "hudhealthy" + switch(virus_threat) + if(VIRUS_SEVERITY_BIOHAZARD) + holder.icon_state = "hudill5" + if(VIRUS_SEVERITY_DANGEROUS) + holder.icon_state = "hudill4" + if(VIRUS_SEVERITY_HARMFUL) + holder.icon_state = "hudill3" + if(VIRUS_SEVERITY_MEDIUM) + holder.icon_state = "hudill2" + if(VIRUS_SEVERITY_MINOR) + holder.icon_state = "hudill1" + if(VIRUS_SEVERITY_NONTHREAT) + holder.icon_state = "hudill0" + if(VIRUS_SEVERITY_POSITIVE) + holder.icon_state = "hudbuff" + if(null) + holder.icon_state = "hudhealthy" /*********************************************** diff --git a/code/game/gamemodes/changeling/powers/glands.dm b/code/game/gamemodes/changeling/powers/glands.dm deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/code/game/gamemodes/changeling/powers/panacea.dm b/code/game/gamemodes/changeling/powers/panacea.dm index c961406810..4e8db74ac8 100644 --- a/code/game/gamemodes/changeling/powers/panacea.dm +++ b/code/game/gamemodes/changeling/powers/panacea.dm @@ -43,7 +43,7 @@ for(var/thing in user.viruses) var/datum/disease/D = thing - if(D.severity == NONTHREAT) + if(D.severity == VIRUS_SEVERITY_POSITIVE) continue D.cure() return TRUE diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 261a258101..2f877776d5 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -95,8 +95,8 @@ Credit where due: antag_flag = ROLE_SERVANT_OF_RATVAR false_report_weight = 10 required_players = 24 - required_enemies = 3 - recommended_enemies = 3 + required_enemies = 4 + recommended_enemies = 4 enemy_minimum_age = 14 protected_jobs = list("AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain") //Silicons can eventually be converted restricted_jobs = list("Chaplain", "Captain") @@ -146,6 +146,7 @@ Credit where due: var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar //that's a mouthful G.initial_activation_delay = ark_time * 60 G.seconds_until_activation = ark_time * 60 //60 seconds in a minute * number of minutes + SSshuttle.registerHostileEnvironment(GLOB.ark_of_the_clockwork_justiciar) ..() return 1 @@ -183,8 +184,14 @@ Credit where due: return TRUE return FALSE +/datum/game_mode/clockwork_cult/check_finished() + var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar + if(G && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed + return FALSE + . = ..() + /datum/game_mode/clockwork_cult/proc/check_clockwork_victory() - if(GLOB.clockwork_gateway_activated || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + if(GLOB.clockwork_gateway_activated) SSticker.news_report = CLOCK_SUMMON return TRUE else @@ -207,7 +214,7 @@ Credit where due: if(istype(SSticker.mode, /datum/game_mode/clockwork_cult)) //Possibly hacky? var/datum/game_mode/clockwork_cult/C = SSticker.mode if(C.check_clockwork_victory()) - text += "Ratvar's servants defended the Ark until its activation!" + text += "Ratvar's servants defended the Ark until its activation!" SSticker.mode_result = "win - servants completed their objective (summon ratvar)" else text += "The Ark was destroyed! Ratvar will rust away for all eternity!" diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index d5b9ce4401..3091d6071a 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -123,10 +123,9 @@ if(glow_type) glow = new glow_type(get_turf(src)) animate(glow, alpha = 255, time = convert_time) - var/I = 0 - while(I < convert_time && get_turf(L) == get_turf(src)) - I++ - sleep(1) + var/end_time = world.time+convert_time + while(world.time < end_time && get_turf(L) == get_turf(src)) + stoplag(1) if(get_turf(L) != get_turf(src)) if(glow) qdel(glow) diff --git a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm index 8f8a4bfcbf..731a8e1d7a 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm @@ -55,7 +55,7 @@ /obj/effect/clockwork/spatial_gateway/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) - to_chat(user, "It has [uses] uses remaining.") + to_chat(user, "It has [uses] use\s remaining.") /obj/effect/clockwork/spatial_gateway/attack_ghost(mob/user) if(linked_gateway) diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm index 563e83e9cd..3d2d646143 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -122,7 +122,7 @@ continue var/datum/clockwork_scripture/quickbind_slot = quickbound[i] to_chat(user, "Quickbind button: [initial(quickbind_slot.name)].") - to_chat(user, "Available Power: [DisplayPower(get_clockwork_power())]") + to_chat(user, "Available power: [DisplayPower(get_clockwork_power())].") //Slab actions; Hierophant, Quickbind /obj/item/clockwork/slab/ui_action_click(mob/user, action) diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index 8e8cd912e7..049a49f5f4 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -319,7 +319,7 @@ Applications: 8 servants, 3 caches, and 100 CV qdel(progbar) else progbar.update(end_time - world.time) - sleep(1) + stoplag(1) if(slab) if(slab.slab_ability) successful = slab.slab_ability.successful diff --git a/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm b/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm index 5e43749ac5..a1c75ed3da 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/heralds_beacon.dm @@ -104,6 +104,5 @@ if(is_servant_of_ratvar(H)) to_chat(H, "The beacon's power warps your body into a clockwork form! You are now immune to many hazards, and your body is more robust against damage!") H.set_species(/datum/species/golem/clockwork/no_scrap) - SSshuttle.registerHostileEnvironment(GLOB.ark_of_the_clockwork_justiciar) //no leaving when we need to purge you, heretics var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar G.grace_period = FALSE //no grace period if we've declared war diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index a3da1c6cbe..1b760617d0 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -503,7 +503,7 @@ /obj/item/device/cult_shift/examine(mob/user) ..() if(uses) - to_chat(user, "It has [uses] uses remaining.") + to_chat(user, "It has [uses] use\s remaining.") else to_chat(user, "It seems drained.") diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 60bbefb7fc..f518612223 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -38,11 +38,9 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event if(max_i<=0) return var/Me = pickweight(meteortypes) - var/obj/effect/meteor/M = new Me(pickedstart) + var/obj/effect/meteor/M = new Me(pickedstart, pickedgoal) M.dest = pickedgoal M.z_original = M.z - spawn(0) - walk_towards(M, M.dest, 1) /proc/spaceDebrisStartLoc(startSide, Z) var/starty @@ -124,12 +122,13 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event walk(src,0) //this cancels the walk_towards() proc . = ..() -/obj/effect/meteor/New() - ..() +/obj/effect/meteor/Initialize(mapload, target) + . = ..() GLOB.meteor_list += src SSaugury.register_doom(src, threat) SpinAnimation() QDEL_IN(src, lifetime) + chase_target(target) /obj/effect/meteor/Collide(atom/A) if(A) @@ -184,6 +183,11 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event var/thing_to_spawn = pick(meteordrop) new thing_to_spawn(get_turf(src)) +/obj/effect/meteor/proc/chase_target(atom/chasing, delay = 1) + set waitfor = FALSE + if(chasing) + walk_towards(src, chasing, delay) + /obj/effect/meteor/proc/meteor_effect() if(heavy) var/sound/meteor_sound = sound(meteorsound) diff --git a/code/game/gamemodes/miniantags/revenant/revenant_blight.dm b/code/game/gamemodes/miniantags/revenant/revenant_blight.dm index 913efb34ce..21bc534f27 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant_blight.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant_blight.dm @@ -2,7 +2,7 @@ name = "Unnatural Wasting" max_stages = 5 stage_prob = 10 - spread_flags = NON_CONTAGIOUS + spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS cure_text = "Holy water or extensive rest." spread_text = "A burst of unholy energy" cures = list("holywater") @@ -11,7 +11,7 @@ viable_mobtypes = list(/mob/living/carbon/human) disease_flags = CURABLE permeability_mod = 1 - severity = BIOHAZARD + severity = VIRUS_SEVERITY_HARMFUL var/stagedamage = 0 //Highest stage reached. var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects. diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index a24efbe3f5..ecfb6289ec 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -82,9 +82,7 @@ /datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - spawn(1) - nukeops_lastname = nukelastname(synd_mind.current) - NukeNameAssign(nukeops_lastname,syndicates) //allows time for the rest of the syndies to be chosen + addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) synd_mind.current.real_name = "[syndicate_name()] [leader_title]" to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") @@ -116,6 +114,9 @@ nuke_code = "code will be provided later" return +/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) + nukeops_lastname = nukelastname(synd_mind.current) + NukeNameAssign(nukeops_lastname, syndicates) /datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) @@ -136,7 +137,7 @@ synd_mob.equipOutfit(/datum/outfit/syndicate) else synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) - return 1 + return TRUE /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() @@ -147,25 +148,25 @@ /datum/game_mode/nuclear/check_win() if (nukes_left == 0) - return 1 + return TRUE return ..() /datum/game_mode/proc/are_operatives_dead() for(var/datum/mind/operative_mind in syndicates) if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) - return 0 - return 1 + return FALSE + return TRUE /datum/game_mode/nuclear/check_finished() //to be called by SSticker if(replacementmode && round_converted == 2) return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) - return 1 + return TRUE if(are_operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! - return 0 //its a static var btw + return FALSE //its a static var btw ..() /datum/game_mode/nuclear/declare_completion() @@ -278,7 +279,7 @@ if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) text += "[icon2html('icons/badass.dmi', world, "badass")]" to_chat(world, text) - return 1 + return TRUE /proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 461ef78ef3..2df573dc6d 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -16,7 +16,7 @@ to_chat(user, msg) for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines) if(bomb.timing) - to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()]") + to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()].") /obj/item/pinpointer/nuke/process() ..() diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index c1b6d13456..7840aff8a4 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -59,10 +59,9 @@ lenin.restricted_roles = restricted_jobs if(head_revolutionaries.len < required_enemies) - return 0 - - return 1 + return FALSE + return TRUE /datum/game_mode/revolution/post_setup() var/list/heads = get_living_heads() @@ -102,10 +101,7 @@ for(var/datum/mind/head_mind in heads) mark_for_death(rev_mind, head_mind) - spawn(rand(10,100)) - // equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO - // Removing revolutionary uplinks. -Pete - equip_revolutionary(rev_mind.current) + addtimer(CALLBACK(src, .proc/equip_revolutionary, rev_mind.current), rand(10, 100)) for(var/datum/mind/rev_mind in head_revolutionaries) greet_revolutionary(rev_mind) @@ -121,7 +117,7 @@ check_heads() SSticker.mode.check_win() check_counter = 0 - return 0 + return FALSE /datum/game_mode/proc/forge_revolutionary_objectives(datum/mind/rev_mind) @@ -169,7 +165,7 @@ to_chat(mob, "The Syndicate were unfortunately unable to get you a flash.") else to_chat(mob, "The flash in your [where] will help you to persuade the crew to join your cause.") - return 1 + return TRUE ///////////////////////////////// //Gives head revs their targets// @@ -235,7 +231,7 @@ SSshuttle.clearHostileEnvironment(src) return ..() if(finished != 0) - return 1 + return TRUE else return ..() @@ -321,9 +317,9 @@ for(var/datum/mind/rev_mind in head_revolutionaries) for(var/datum/objective/mutiny/objective in rev_mind.objectives) if(!(objective.check_completion())) - return 0 + return FALSE - return 1 + return TRUE ///////////////////////////// //Checks for a head victory// @@ -333,8 +329,8 @@ var/turf/T = get_turf(rev_mind.current) if(!considered_afk(rev_mind) && considered_alive(rev_mind) && (T.z in GLOB.station_z_levels)) if(ishuman(rev_mind.current)) - return 0 - return 1 + return FALSE + return TRUE ////////////////////////////////////////////////////////////////////// //Announces the end of the game with all relavent information stated// @@ -352,7 +348,7 @@ SSticker.news_report = REVS_LOSE ..() - return 1 + return TRUE /datum/game_mode/proc/auto_declare_completion_revolution() var/list/targets = list() diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 94025dae31..007ef41ac1 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -174,7 +174,7 @@ /obj/machinery/sleeper/emag_act(mob/user) scramble_chem_buttons() - to_chat(user, "You scramble the sleepers user interface!") + to_chat(user, "You scramble the sleeper's user interface!") /obj/machinery/sleeper/proc/inject_chem(chem) if((chem in available_chems) && chem_allowed(chem)) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 23b398605c..7858480f5c 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -443,14 +443,14 @@ Class Procs: return 0 /obj/machinery/proc/display_parts(mob/user) - to_chat(user, "Following parts detected in the machine:") + to_chat(user, "It contains the following parts:") for(var/obj/item/C in component_parts) - to_chat(user, "[icon2html(C, user)] [C.name]") + to_chat(user, "[icon2html(C, user)] \A [C].") /obj/machinery/examine(mob/user) ..() if(stat & BROKEN) - to_chat(user, "It looks broken and non functional.") + to_chat(user, "It looks broken and non-functional.") if(!(resistance_flags & INDESTRUCTIBLE)) if(resistance_flags & ON_FIRE) to_chat(user, "It's on fire!") diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 63c63ce120..c39c66f6fc 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -27,7 +27,7 @@ ..() to_chat(user, "There's [charging ? "a" : "no"] cell in the charger.") if(charging) - to_chat(user, "Current charge: [round(charging.percent(), 1)]%") + to_chat(user, "Current charge: [round(charging.percent(), 1)]%.") /obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/stock_parts/cell)) diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index f919bdbab8..4c90f3ae4e 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -381,7 +381,7 @@ initial_matrix = matrix(M.transform) initial_matrix.Translate(-3,0) animate(M, transform = initial_matrix, time = 1, loop = 0) - sleep (1) + sleep(1) M.lying_fix() @@ -428,7 +428,7 @@ initial_matrix = matrix(M.transform) initial_matrix.Translate(-3,0) animate(M, transform = initial_matrix, time = 1, loop = 0) - sleep (1) + sleep(1) M.lying_fix() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 99f174b94c..c3af2043ad 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -568,24 +568,24 @@ if(panel_open) switch(security_level) if(AIRLOCK_SECURITY_NONE) - to_chat(user, "Wires are exposed!") + to_chat(user, "Its wires are exposed!") if(AIRLOCK_SECURITY_METAL) - to_chat(user, "Wires are hidden behind welded metal cover") + to_chat(user, "Its wires are hidden behind a welded metal cover.") if(AIRLOCK_SECURITY_PLASTEEL_I_S) - to_chat(user, "There is some shredded plasteel inside") + to_chat(user, "There is some shredded plasteel inside.") if(AIRLOCK_SECURITY_PLASTEEL_I) - to_chat(user, "Wires are behind inner layer of plasteel") + to_chat(user, "Its wires are behind an inner layer of plasteel.") if(AIRLOCK_SECURITY_PLASTEEL_O_S) - to_chat(user, "There is some shredded plasteel inside") + to_chat(user, "There is some shredded plasteel inside.") if(AIRLOCK_SECURITY_PLASTEEL_O) - to_chat(user, "There is welded plasteel cover hiding wires") + to_chat(user, "There is a welded plasteel cover hiding its wires.") if(AIRLOCK_SECURITY_PLASTEEL) - to_chat(user, "There is protective grille over panel") + to_chat(user, "There is a protective grille over its panel.") else if(security_level) if(security_level == AIRLOCK_SECURITY_METAL) - to_chat(user, "It looks a bit stronger") + to_chat(user, "It looks a bit stronger.") else - to_chat(user, "It looks very robust") + to_chat(user, "It looks very robust.") /obj/machinery/door/airlock/attack_ai(mob/user) if(!src.canAIControl(user)) @@ -1015,7 +1015,7 @@ if(S.get_amount() < 2) to_chat(user, "You need at least 2 metal sheets to reinforce [src].") return - to_chat(user, "You start reinforcing [src]") + to_chat(user, "You start reinforcing [src].") if(do_after(user, 20, 1, target = src)) if(!panel_open || !S.use(2)) return diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 542989fa15..37500b2589 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -33,14 +33,12 @@ ..() if(!density) to_chat(user, "It is open, but could be pried closed.") + else if(!welded) + to_chat(user, "It is closed, but could be pried open. Deconstruction would require it to be welded shut.") + else if(boltslocked) + to_chat(user, "It is welded shut. The floor bolts have been locked by screws.") else - if(!welded) - to_chat(user, "It is closed, but could be pried open. Deconstruction would require it to be welded shut.") - else - if(boltslocked) - to_chat(user, "It is welded shut. The floor bolt have been locked by screws.") - else - to_chat(user, "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor.") + to_chat(user, "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor.") /obj/machinery/door/firedoor/proc/CalculateAffectingAreas() remove_from_areas() diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm index 5d7be7fbd8..54183c155e 100644 --- a/code/game/machinery/droneDispenser.dm +++ b/code/game/machinery/droneDispenser.dm @@ -4,9 +4,7 @@ /obj/machinery/droneDispenser //Most customizable machine 2015 name = "drone shell dispenser" - desc = "A hefty machine that, when supplied with metal and glass, \ - will periodically create a drone shell. \ - Does not need to be manually operated." + desc = "A hefty machine that, when supplied with metal and glass, will periodically create a drone shell. Does not need to be manually operated." icon = 'icons/obj/machines/droneDispenser.dmi' icon_state = "on" @@ -46,8 +44,7 @@ var/begin_create_message = "whirs to life!" var/end_create_message = "dispenses a drone shell." var/recharge_message = "pings." - var/recharging_text = "It is whirring and clicking. \ - It seems to be recharging." + var/recharging_text = "It is whirring and clicking. It seems to be recharging." var/break_message = "lets out a tinny alarm before falling dark." var/break_sound = 'sound/machines/warning-buzzer.ogg' @@ -56,6 +53,7 @@ . = ..() var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), MINERAL_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, TRUE) materials.insert_amount(starting_amount) + materials.precise_insertion = TRUE using_materials = list(MAT_METAL=metal_cost, MAT_GLASS=glass_cost) /obj/machinery/droneDispenser/preloaded @@ -72,18 +70,14 @@ /obj/machinery/droneDispenser/syndrone/badass //Please forgive me name = "badass syndrone shell dispenser" - desc = "A suspicious machine that will create Syndicate \ - exterminator drones when supplied with metal and glass. \ - Disgusting. This one seems ominous." + desc = "A suspicious machine that will create Syndicate exterminator drones when supplied with metal and glass. Disgusting. This one seems ominous." dispense_type = /obj/item/drone_shell/syndrone/badass end_create_message = "dispenses an ominous suspicious drone shell." // I don't need your forgiveness, this is awesome. /obj/machinery/droneDispenser/snowflake name = "snowflake drone shell dispenser" - desc = "A hefty machine that, when supplied with metal and glass, \ - will periodically create a snowflake drone shell. \ - Does not need to be manually operated." + desc = "A hefty machine that, when supplied with metal and glass, will periodically create a snowflake drone shell. Does not need to be manually operated." dispense_type = /obj/item/drone_shell/snowflake end_create_message = "dispenses a snowflake drone shell." // Those holoprojectors aren't cheap @@ -96,8 +90,7 @@ // This one requires no materials and creates basic hivebots /obj/machinery/droneDispenser/hivebot name = "hivebot fabricator" - desc = "A large, bulky machine that whirs with activity, \ - steam hissing from vents in its sides." + desc = "A large, bulky machine that whirs with activity, steam hissing from vents in its sides." icon = 'icons/obj/objects.dmi' icon_state = "hivebot_fab" icon_off = "hivebot_fab" @@ -110,14 +103,13 @@ cooldownTime = 10 //Only 1 second - hivebots are extremely weak dispense_type = /mob/living/simple_animal/hostile/hivebot begin_create_message = "closes and begins fabricating something within." - end_create_message = "slams open, revealing out a hivebot!" + end_create_message = "slams open, revealing a hivebot!" recharge_sound = null recharge_message = null /obj/machinery/droneDispenser/swarmer name = "swarmer fabricator" - desc = "An alien machine of unknown origin. \ - It whirs and hums with green-blue light, the air above it shimmering." + desc = "An alien machine of unknown origin. It whirs and hums with green-blue light, the air above it shimmering." icon = 'icons/obj/machines/gateway.dmi' icon_state = "toffcenter" icon_off = "toffcenter" @@ -129,10 +121,8 @@ cooldownTime = 300 //30 seconds maximum_idle = 0 // Swarmers have no restraint dispense_type = /obj/effect/mob_spawn/swarmer - begin_create_message = "hums softly as an interface appears above it, \ - scrolling by at unreadable speed." - end_create_message = "materializes a strange shell, which drops to the \ - ground." + begin_create_message = "hums softly as an interface appears above it, scrolling by at unreadable speed." + end_create_message = "materializes a strange shell, which drops to the ground." recharging_text = "Its lights are slowly increasing in brightness." work_sound = 'sound/effects/empulse.ogg' create_sound = 'sound/effects/phasein.ogg' @@ -171,8 +161,7 @@ if(maximum_idle && (count_shells() >= maximum_idle)) return // then do nothing; check again next tick if(begin_create_message) - visible_message("\ - [src] [begin_create_message]") + visible_message("[src] [begin_create_message]") if(work_sound) playsound(src, work_sound, 50, 1) mode = DRONE_PRODUCTION @@ -190,8 +179,7 @@ if(create_sound) playsound(src, create_sound, 50, 1) if(end_create_message) - visible_message("[src] \ - [end_create_message]") + visible_message("[src] [end_create_message]") mode = DRONE_RECHARGING timer = world.time + cooldownTime @@ -201,8 +189,7 @@ if(recharge_sound) playsound(src, recharge_sound, 50, 1) if(recharge_message) - visible_message("\ - [src] [recharge_message]") + visible_message("[src] [recharge_message]") mode = DRONE_READY update_icon() @@ -246,10 +233,8 @@ playsound(src, WT.usesound, 50, 1) user.visible_message( - "[user] begins patching up \ - [src] with [WT].", - "You begin restoring the \ - damage to [src]...") + "[user] begins patching up [src] with [WT].", + "You begin restoring the damage to [src]...") if(!do_after(user, 40*O.toolspeed, target = src)) return @@ -270,8 +255,7 @@ if(!(flags_1 & NODECONSTRUCT_1)) if(!(stat & BROKEN)) if(break_message) - audible_message("[src] \ - [break_message]") + audible_message("[src] [break_message]") if(break_sound) playsound(src, break_sound, 50, 1) stat |= BROKEN diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 5d6370188b..83681475fd 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -123,10 +123,37 @@ /obj/machinery/status_display/examine(mob/user) . = ..() switch(mode) - if(1,2,4,5) - to_chat(user, "The display says:
\t[message1]
\t[message2]") - if(mode == 1 && SSshuttle.emergency) - to_chat(user, "Current Shuttle: [SSshuttle.emergency.name]") + if(1,5) // Emergency or generic shuttle + var/obj/docking_port/mobile/shuttle + if(mode == 1) + shuttle = SSshuttle.emergency + else + shuttle = SSshuttle.getShuttle(shuttle_id) + + if (!shuttle) + to_chat(user, "The display says:
\tShuttle?") + else if (shuttle.timer) + to_chat(user, "The display says:
\t[shuttle.getModeStr()]: [shuttle.getTimerStr()]") + if (mode == 1 && shuttle) + to_chat(user, "Current shuttle: [shuttle.name].") + if(4) // Supply shuttle + var/obj/docking_port/mobile/shuttle = SSshuttle.supply + var/shuttleMsg = null + if (shuttle.mode == SHUTTLE_IDLE) + if (shuttle.z in GLOB.station_z_levels) + shuttleMsg = "Docked" + else + shuttleMsg = "[shuttle.getModeStr()]: [shuttle.getTimerStr()]" + if (shuttleMsg) + to_chat(user, "The display says:
\t[shuttleMsg]") + if(2) // Custom message + if (message1 || message2) + var/msg = "The display says:" + if (message1) + msg += "
\t[message1]" + if (message2) + msg += "
\t[message2]" + to_chat(user, msg) /obj/machinery/status_display/proc/set_message(m1, m2) diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 747647b1a5..524dc4e5b5 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -35,9 +35,10 @@ ) /obj/machinery/mecha_part_fabricator/Initialize() - AddComponent(/datum/component/material_container, + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) + materials.precise_insertion = TRUE . = ..() files = new /datum/research(src) //Setup the research data holder. diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index f06d355078..4a80d13215 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -276,7 +276,7 @@ if(equipment && equipment.len) to_chat(user, "It's equipped with:") for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - to_chat(user, "[icon2html(ME, user)] [ME]") + to_chat(user, "[icon2html(ME, user)] \A [ME].") //processing internal damage, temperature, air regulation, alert updates, lights power use. /obj/mecha/process() diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index 76208f54fa..ea5fc3a88f 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -20,7 +20,7 @@ /obj/effect/countdown/examine(mob/user) . = ..() - to_chat(user, "This countdown is displaying: [displayed_text]") + to_chat(user, "This countdown is displaying: [displayed_text].") /obj/effect/countdown/proc/attach(atom/A) attached_to = A diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 2aca5c534b..4a5ac2f60d 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -6,7 +6,7 @@ var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints var/mergeable_decal = 1 //when two of these are on a same tile or do we need to merge them into just one? -/obj/effect/decal/cleanable/Initialize(mapload) +/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases) if (random_icon_states && length(src.random_icon_states) > 0) src.icon_state = pick(src.random_icon_states) create_reagents(300) @@ -14,10 +14,15 @@ for(var/obj/effect/decal/cleanable/C in src.loc) if(C != src && C.type == src.type) replace_decal(C) + if(LAZYLEN(diseases)) + var/list/datum/disease/diseases_to_add = list() + for(var/datum/disease/D in diseases) + if(D.spread_flags & VIRUS_SPREAD_CONTACT_FLUIDS) + diseases_to_add += D + if(LAZYLEN(diseases_to_add)) + AddComponent(/datum/component/infective, diseases_to_add) . = ..() - - /obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) if(mergeable_decal) qdel(C) @@ -65,6 +70,7 @@ //Add "bloodiness" of this blood's type, to the human's shoes //This is on /cleanable because fuck this ancient mess /obj/effect/decal/cleanable/Crossed(atom/movable/O) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O if(H.shoes && blood_state && bloodiness) diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 5566a91d88..bd01f717da 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -18,7 +18,7 @@ desc = "Looks like it's been here a while. Eew." bloodiness = 0 -/obj/effect/decal/cleanable/blood/old/Initialize() +/obj/effect/decal/cleanable/blood/old/Initialize(mapload, list/datum/disease/diseases) . = ..() icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization. blood_DNA["Non-human DNA"] = "A+" @@ -39,7 +39,6 @@ var/list/existing_dirs = list() blood_DNA = list() - /obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in() return 1 @@ -53,7 +52,7 @@ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") mergeable_decal = 0 -/obj/effect/decal/cleanable/blood/gibs/Initialize() +/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases) . = ..() reagents.add_reagent("liquidgibs", 5) @@ -66,7 +65,11 @@ for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++) sleep(2) if(i > 0) - new /obj/effect/decal/cleanable/blood/splatter(loc) + var/list/datum/disease/diseases + GET_COMPONENT(infective, /datum/component/infective) + if(infective) + diseases = infective.diseases + new /obj/effect/decal/cleanable/blood/splatter(loc, diseases) if(!step_to(src, get_step(src, direction), 0)) break @@ -93,7 +96,7 @@ desc = "Space Jesus, why didn't anyone clean this up? It smells terrible." bloodiness = 0 -/obj/effect/decal/cleanable/blood/gibs/old/Initialize() +/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases) . = ..() setDir(pick(1,2,4,8)) icon_state += "-old" @@ -126,6 +129,7 @@ var/list/shoe_types = list() /obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes @@ -136,6 +140,7 @@ update_icon() /obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O) + ..() if(ishuman(O)) var/mob/living/carbon/human/H = O var/obj/item/clothing/shoes/S = H.shoes @@ -169,7 +174,7 @@ . += "You recognise the footprints as belonging to:\n" for(var/shoe in shoe_types) var/obj/item/clothing/shoes/S = shoe - . += "some [initial(S.name)] [icon2html(initial(S.icon), user)]\n" + . += "[icon2html(initial(S.icon), user)] Some [initial(S.name)].\n" to_chat(user, .) diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index 4be49d12f8..583f63af3a 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -101,7 +101,7 @@ name = "crusty dried vomit" desc = "You try not to look at the chunks, and fail." -/obj/effect/decal/cleanable/vomit/old/Initialize() +/obj/effect/decal/cleanable/vomit/old/Initialize(mapload, list/datum/disease/diseases) . = ..() icon_state += "-old" diff --git a/code/game/objects/effects/effect_system/effects_explosion.dm b/code/game/objects/effects/effect_system/effects_explosion.dm index 8e7f2dfd12..23895de9c5 100644 --- a/code/game/objects/effects/effect_system/effects_explosion.dm +++ b/code/game/objects/effects/effect_system/effects_explosion.dm @@ -13,13 +13,11 @@ /datum/effect_system/expl_particles/start() for(var/i in 1 to number) - spawn(0) - var/obj/effect/particle_effect/expl_particles/expl = new /obj/effect/particle_effect/expl_particles(location) - var/direct = pick(GLOB.alldirs) - var/steps_amt = pick(1;25,2;50,3,4;200) - for(var/j in 1 to steps_amt) - sleep(1) - step(expl,direct) + var/obj/effect/particle_effect/expl_particles/expl = new /obj/effect/particle_effect/expl_particles(location) + var/direct = pick(GLOB.alldirs) + var/steps_amt = pick(1;25,2;50,3,4;200) + for(var/j in 1 to steps_amt) + addtimer(CALLBACK(src, .proc/_step, expl, direct), j) /obj/effect/explosion name = "fire" @@ -51,9 +49,10 @@ /datum/effect_system/explosion/smoke +/datum/effect_system/explosion/smoke/proc/create_smoke() + var/datum/effect_system/smoke_spread/S = new + S.set_up(2, location) + S.start() /datum/effect_system/explosion/smoke/start() ..() - spawn(5) - var/datum/effect_system/smoke_spread/S = new - S.set_up(2, location) - S.start() + addtimer(CALLBACK(src, .proc/create_smoke), 5) diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 8d7a446248..303bcd7f33 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -6,7 +6,7 @@ var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn. var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards. -/obj/effect/gibspawner/Initialize(mapload, datum/dna/MobDNA) +/obj/effect/gibspawner/Initialize(mapload, datum/dna/MobDNA, list/datum/disease/diseases) . = ..() if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len) @@ -24,7 +24,7 @@ if(gibamounts[i]) for(var/j = 1, j<= gibamounts[i], j++) var/gibType = gibtypes[i] - gib = new gibType(loc) + gib = new gibType(loc, diseases) if(iscarbon(loc)) var/mob/living/carbon/digester = loc digester.stomach_contents += gib diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 76e1468751..e158c1f90a 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -344,7 +344,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/datum/progressbar/progress = new(user, len, loc) while (do_after(user, 10, TRUE, S, FALSE, CALLBACK(src, .proc/handle_mass_pickup, S, things, loc, rejections, progress))) - sleep(1) + stoplag(1) qdel(progress) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index d0dc220d4d..a7ebf8251d 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -36,7 +36,8 @@ /obj/item/bodybag/bluespace/examine(mob/user) ..() if(contents.len) - to_chat(user, "You can make out the shapes of [contents.len] objects through the fabric.") + var/s = contents.len == 1 ? "" : "s" + to_chat(user, "You can make out the shape[s] of [contents.len] object[s] through the fabric.") /obj/item/bodybag/bluespace/Destroy() for(var/atom/movable/A in contents) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 13fe778a38..5f90dd1b51 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -157,6 +157,10 @@ CIGARETTE PACKETS ARE IN FANCY.DM /obj/item/clothing/mask/cigarette/proc/light(flavor_text = null) if(lit) return + if(!initialized) + icon_state = icon_on + item_state = icon_on + return lit = TRUE name = "lit [name]" diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index cbbf1d0cb7..7576824747 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -598,6 +598,17 @@ /obj/item/stock_parts/cell = 1) def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) +/obj/item/circuitboard/machine/smoke_machine + name = "Smoke Machine (Machine Board)" + build_path = /obj/machinery/smoke_machine + origin_tech = "materials=4;engineering=3;biotech=3" + req_components = list( + /obj/item/stock_parts/matter_bin = 2, + /obj/item/stock_parts/capacitor = 1, + /obj/item/stock_parts/manipulator = 1, + /obj/item/stock_parts/console_screen = 1, + /obj/item/stock_parts/cell = 1) + /obj/item/circuitboard/machine/chem_heater name = "Chemical Heater (Machine Board)" build_path = /obj/machinery/chem_heater diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 882335d5e7..3b24626737 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -549,7 +549,7 @@ /obj/item/toy/crayon/spraycan/examine(mob/user) . = ..() if(charges_left) - to_chat(user, "It has [charges_left] uses left.") + to_chat(user, "It has [charges_left] use\s left.") else to_chat(user, "It is empty.") diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 513ffb8d2b..108c561fc1 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -162,8 +162,9 @@ Code: /obj/item/device/electropack/shockcollar/attack_hand(mob/user) if(loc == user) if(slot_flags == SLOT_NECK) - to_chat(user, "The collar is fastened tight! You'll need help taking this off!") - return + if(user.get_item_by_slot(slot_neck)) + to_chat(user, "The collar is fastened tight! You'll need help taking this off!") + return ..() /obj/item/device/electropack/shockcollar/receive_signal(datum/signal/signal) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 83d29457f6..ccf5e985c8 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -512,9 +512,9 @@ /obj/item/device/radio/examine(mob/user) ..() if (b_stat) - to_chat(user, "[name] can be attached and modified.") + to_chat(user, "It can be attached and modified.") else - to_chat(user, "[name] can not be modified or attached.") + to_chat(user, "It cannot be modified or attached.") /obj/item/device/radio/attackby(obj/item/W, mob/user, params) add_fingerprint(user) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index c42322044a..c6c8dbe749 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -68,7 +68,7 @@ /obj/item/extinguisher/examine(mob/user) ..() if(reagents.total_volume) - to_chat(user, "It contains [round(reagents.total_volume)] units.") + to_chat(user, "It contains [round(reagents.total_volume)] unit\s.") to_chat(user, "Alt-click to empty it.") else to_chat(user, "It is empty.") diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index 0757479868..720aacf619 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -144,7 +144,7 @@ /obj/item/flamethrower/examine(mob/user) ..() if(ptank) - to_chat(user, "\The [src] has \the [ptank] attached. Alt-click to remove it.") + to_chat(user, "\The [src] has \a [ptank] attached. Alt-click to remove it.") /obj/item/flamethrower/proc/toggle_igniter(mob/user) if(!ptank) diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index a0a493530b..d6f789a1b7 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -48,15 +48,15 @@ /obj/item/inducer/proc/cantbeused(mob/user) if(!user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to use \the [src]!") + to_chat(user, "You don't have the dexterity to use [src]!") return TRUE if(!cell) - to_chat(user, "\The [src] doesn't have a power cell installed!") + to_chat(user, "[src] doesn't have a power cell installed!") return TRUE if(!cell.charge) - to_chat(user, "\The [src]'s battery is dead!") + to_chat(user, "[src]'s battery is dead!") return TRUE return FALSE @@ -79,12 +79,12 @@ if(!cell) if(!user.transferItemToLoc(W, src)) return - to_chat(user, "You insert \the [W] into \the [src].") + to_chat(user, "You insert [W] into [src].") cell = W update_icon() return else - to_chat(user, "\The [src] already has \a [cell] installed!") + to_chat(user, "[src] already has \a [cell] installed!") return if(cantbeused(user)) @@ -110,15 +110,17 @@ if(istype(A, /obj)) O = A if(C) + var/done_any = FALSE if(C.charge >= C.maxcharge) - to_chat(user, "\The [A] is fully charged!") + to_chat(user, "[A] is fully charged!") recharging = FALSE return TRUE - user.visible_message("[user] starts recharging \the [A] with \the [src]","You start recharging [A] with \the [src]") + user.visible_message("[user] starts recharging [A] with [src].","You start recharging [A] with [src].") while(C.charge < C.maxcharge) if(E) E.chambered = null // Prevents someone from firing continuously while recharging the gun. if(do_after(user, 10, target = user) && cell.charge) + done_any = TRUE induce(C, coefficient) do_sparks(1, FALSE, A) if(O) @@ -127,7 +129,8 @@ break if(E) E.recharge_newshot() //We're done charging, so we'll let someone fire it now. - user.visible_message("[user] recharged \the [A]!","You recharged \the [A]!") + if(done_any) // Only show a message if we succeeded at least once + user.visible_message("[user] recharged [A]!","You recharged [A]!") recharging = FALSE return TRUE recharging = FALSE @@ -147,7 +150,7 @@ /obj/item/inducer/attack_self(mob/user) if(opened && cell) - user.visible_message("[user] removes \the [cell] from \the [src]!","You remove \the [cell].") + user.visible_message("[user] removes [cell] from [src]!","You remove [cell].") cell.update_icon() user.put_in_hands(cell) cell = null @@ -157,11 +160,11 @@ /obj/item/inducer/examine(mob/living/M) ..() if(cell) - to_chat(M, "It's display shows: [DisplayPower(cell.charge)]") + to_chat(M, "Its display shows: [DisplayPower(cell.charge)].") else - to_chat(M,"It's display is dark.") + to_chat(M,"Its display is dark.") if(opened) - to_chat(M,"It's battery compartment is open.") + to_chat(M,"Its battery compartment is open.") /obj/item/inducer/update_icon() cut_overlays() @@ -174,7 +177,7 @@ /obj/item/inducer/sci icon_state = "inducer-sci" item_state = "inducer-sci" - desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than it's engineering counterpart." + desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than its engineering counterpart." cell_type = null powertransfer = 500 opened = TRUE diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 9400303b84..6e9cbfa35f 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -38,10 +38,10 @@ out += "You'll need to get closer to see any more." return for(var/obj/item/I in loadedItems) - out += "[icon2html(I, user)] It has \the [I] loaded." + out += "[icon2html(I, user)] It has \a [I] loaded." CHECK_TICK if(tank) - out += "[icon2html(tank, user)] It has \the [tank] mounted onto it." + out += "[icon2html(tank, user)] It has \a [tank] mounted onto it." to_chat(user, out.Join("
")) /obj/item/pneumatic_cannon/attackby(obj/item/W, mob/user, params) diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index c40ba3c458..f2f0a8b3e5 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -26,7 +26,7 @@ to_chat(user, "You'll need to get closer to see any more.") return if(tank) - to_chat(user, "[icon2html(tank, user)] It has \the [tank] mounted onto it.") + to_chat(user, "[icon2html(tank, user)] It has \a [tank] mounted onto it.") /obj/item/melee/powerfist/attackby(obj/item/W, mob/user, params) diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index 309479dd86..cb9e6e2d63 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -88,7 +88,7 @@ var/list/things = src_object.contents.Copy() var/datum/progressbar/progress = new(user, things.len, src) while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(src, .proc/handle_mass_item_insertion, things, src_object, user, progress))) - sleep(1) + stoplag(1) qdel(progress) orient2hud(user) src_object.orient2hud(user) @@ -489,7 +489,7 @@ var/list/things = contents.Copy() var/datum/progressbar/progress = new(usr, things.len, T) while (do_after(usr, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress))) - sleep(1) + stoplag(1) qdel(progress) /obj/item/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 85f5de7526..0ed1a7c566 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -840,7 +840,7 @@ if(ishuman(user)) var/mob/living/carbon/human/cardUser = user if(cardUser.is_holding(src)) - cardUser.visible_message("[cardUser] checks [cardUser.p_their()] card.", "The card reads: [cardname]") + cardUser.visible_message("[cardUser] checks [cardUser.p_their()] card.", "The card reads: [cardname].") else to_chat(cardUser, "You need to have the card in your hand to check it!") diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 17bbb0a12f..5a4cd477e5 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -586,6 +586,31 @@ flags_1 = DROPDEL_1 | ABSTRACT_1 attack_verb = list("bopped") +/obj/item/slapper + name = "slapper" + desc = "This is how real men fight." + icon_state = "latexballon" + force = 1 + throwforce = 0 + flags_1 = DROPDEL_1 | ABSTRACT_1 + attack_verb = list("slapped") + hitsound = 'sound/effects/snap.ogg' + +/obj/item/slapper/attack(mob/M, mob/living/carbon/human/user) + if(ishuman(M)) + var/mob/living/carbon/human/L = M + L.endTailWag() + if(user.a_intent != INTENT_HARM) + var/aim_for_face = ((user.zone_selected == "mouth") || (user.zone_selected == "eyes") || (user.zone_selected == "head")) + user.do_attack_animation(M) + playsound(M, 'sound/weapons/slap.ogg', 50, 1, -1) + user.visible_message("[user] slaps [M] in the [(aim_for_face)?"face":user.zone_selected]!", + "You slap [M] in the [(aim_for_face)?"face":user.zone_selected]! ",\ + "You hear a slap.") + return + else + ..() + /obj/item/proc/can_trigger_gun(mob/living/user) if(!user.can_use_guns(src)) return FALSE diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 6845a1c9f0..a6cc3d0464 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -120,7 +120,7 @@ return emagged = TRUE to_chat(user, "You emag the barsign. Takeover in progress...") - sleep(100) //10 seconds + sleep(10 SECONDS) set_sign(new /datum/barsign/hiddensigns/syndibarsign) req_access = list(ACCESS_SYNDICATE) diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index 5c36c5a6ba..117695da84 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -144,7 +144,7 @@ /obj/item/roller/robo/examine(mob/user) ..() - to_chat(user, "The dock is [loaded ? "loaded" : "empty"]") + to_chat(user, "The dock is [loaded ? "loaded" : "empty"].") /obj/item/roller/robo/deploy_roller(mob/user, atom/location) if(loaded) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4e3056f39a..6357578bc3 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/closet.dmi' icon_state = "generic" density = TRUE + layer = BELOW_OBJ_LAYER var/icon_door = null var/icon_door_override = FALSE //override to have open overlay use icon different to its base's var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights @@ -53,6 +54,7 @@ /obj/structure/closet/update_icon() cut_overlays() if(!opened) + layer = OBJ_LAYER if(icon_door) add_overlay("[icon_door]_door") else @@ -69,6 +71,7 @@ add_overlay("off") else + layer = BELOW_OBJ_LAYER if(icon_door_override) add_overlay("[icon_door]_open") else diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 66406b88be..77ef696714 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -330,7 +330,7 @@ var/list/things = src_object.contents.Copy() var/datum/progressbar/progress = new(user, things.len, src) while (do_after(usr, 10, TRUE, src, FALSE, CALLBACK(src_object, /obj/item/storage.proc/mass_remove_from_storage, src, things, progress))) - sleep(1) + stoplag(1) qdel(progress) return TRUE diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index 37762520a8..7176ac726c 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -142,9 +142,6 @@ /proc/_sin(X) return sin(X) -/proc/_step(Ref, Dir, Speed = 0) - return step(Ref, Dir, Speed) - /proc/_list_add(list/L, ...) if (args.len < 2) return @@ -179,4 +176,34 @@ /proc/_list_swap(list/L, Index1, Index2) L.Swap(Index1, Index2) +/proc/_walk(ref, dir, lag) + walk(ref, dir, lag) + +/proc/_walk_towards(ref, trg, lag) + walk_towards(ref, trg, lag) + +/proc/_walk_to(ref, trg, min, lag) + walk_to(ref, trg, min, lag) + +/proc/_walk_away(ref, trg, max, lag) + walk_away(ref, trg, max, lag) + +/proc/_walk_rand(ref, lag) + walk_rand(ref, lag) + +/proc/_step(ref, dir) + step(ref, dir) + +/proc/_step_rand(ref) + step_rand(ref) + +/proc/_step_to(ref, trg, min) + step_to(ref, trg, min) + +/proc/_step_towards(ref, trg) + step_towards(ref, trg) + +/proc/_step_away(ref, trg, max) + step_away(ref, trg, max) + diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index efc6a8e899..ee7228fdca 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -20,7 +20,7 @@ var/sleep_factor = 750 var/unconscious_factor = 1000 var/heat_capacity = 20000 - var/conduction_coefficient = 0.30 + var/conduction_coefficient = 0.3 var/obj/item/reagent_containers/glass/beaker = null var/reagent_transfer = 0 @@ -29,7 +29,7 @@ var/radio_key = /obj/item/device/encryptionkey/headset_med var/radio_channel = "Medical" - var/running_bob_anim = FALSE + var/running_anim = FALSE var/escape_in_progress = FALSE var/message_cooldown @@ -83,46 +83,51 @@ /obj/machinery/atmospherics/components/unary/cryo_cell/update_icon() cut_overlays() + if(panel_open) + add_overlay("pod-panel") + if(state_open) icon_state = "pod-open" - else if(occupant) + return + + if(occupant) var/image/occupant_overlay - if(ismonkey(occupant)) // Monkey - occupant_overlay = mutable_appearance(CRYOMOBS, "monkey") - - else if(isalienadult(occupant)) - - if(isalienroyal(occupant)) // Queen and prae - occupant_overlay = image(CRYOMOBS, "alienq") - - else if(isalienhunter(occupant)) // Hunter - occupant_overlay = image(CRYOMOBS, "alienh") - - else if(isaliensentinel(occupant)) // Sentinel - occupant_overlay = image(CRYOMOBS, "aliens") - - else // Drone (or any other alien that isn't any of the above) - occupant_overlay = image(CRYOMOBS, "aliend") - - else if(ishuman(occupant) || islarva(occupant) || (isanimal(occupant) && !ismegafauna(occupant))) // Mobs that are smaller than cryotube + if(ishuman(occupant) || islarva(occupant) || (isanimal(occupant) && !ismegafauna(occupant))) // Mobs that are smaller than cryotube occupant_overlay = image(occupant.icon, occupant.icon_state) occupant_overlay.copy_overlays(occupant) - else // Anything else + else if(ismonkey(occupant)) // Monkey + occupant_overlay = image(CRYOMOBS, "monkey") + occupant_overlay.copy_overlays(occupant) + + else if(!isalienadult(occupant)) occupant_overlay = image(CRYOMOBS, "generic") + else if(isalienroyal(occupant)) // Queen and prae + occupant_overlay = image(CRYOMOBS, "alienq") + + else if(isalienhunter(occupant)) // Hunter + occupant_overlay = image(CRYOMOBS, "alienh") + + else if(isaliensentinel(occupant)) // Sentinel + occupant_overlay = image(CRYOMOBS, "aliens") + + else // Drone or other + occupant_overlay = image(CRYOMOBS, "aliend") + occupant_overlay.dir = SOUTH occupant_overlay.pixel_y = 22 - if(on && !running_bob_anim && is_operational()) + if(on && !running_anim && is_operational()) icon_state = "pod-on" - running_bob_anim = TRUE - run_bob_anim(TRUE, occupant_overlay) + running_anim = TRUE + run_anim(TRUE, occupant_overlay) else icon_state = "pod-off" add_overlay(occupant_overlay) add_overlay("cover-off") + else if(on && is_operational()) icon_state = "pod-on" add_overlay("cover-on") @@ -130,12 +135,9 @@ icon_state = "pod-off" add_overlay("cover-off") - if(panel_open) - add_overlay("pod-panel") - -/obj/machinery/atmospherics/components/unary/cryo_cell/proc/run_bob_anim(anim_up, image/occupant_overlay) +/obj/machinery/atmospherics/components/unary/cryo_cell/proc/run_anim(anim_up, image/occupant_overlay) if(!on || !occupant || !is_operational()) - running_bob_anim = FALSE + running_anim = FALSE return cut_overlays() if(occupant_overlay.pixel_y != 23) // Same effect as occupant_overlay.pixel_y == 22 || occupant_overlay.pixel_y == 24 @@ -146,7 +148,7 @@ occupant_overlay.pixel_y-- add_overlay(occupant_overlay) add_overlay("cover-on") - addtimer(CALLBACK(src, .proc/run_bob_anim, anim_up, occupant_overlay), 7, TIMER_UNIQUE) + addtimer(CALLBACK(src, .proc/run_anim, anim_up, occupant_overlay), 7, TIMER_UNIQUE) /obj/machinery/atmospherics/components/unary/cryo_cell/process() ..() @@ -157,60 +159,65 @@ on = FALSE update_icon() return - var/datum/gas_mixture/air1 = AIR1 - var/turf/T = get_turf(src) - if(occupant) - var/mob/living/mob_occupant = occupant - if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people. - on = FALSE - update_icon() - playsound(T, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. - radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language()) - if(autoeject) // Eject if configured. - radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language()) - open_machine() - return - else if(mob_occupant.stat == DEAD) // We don't bother with dead people. - return - if(autoeject) // Eject if configured. - open_machine() - return - if(air1.gases.len) - if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. - mob_occupant.Sleeping((mob_occupant.bodytemperature / sleep_factor) * 2000) - mob_occupant.Unconscious((mob_occupant.bodytemperature / unconscious_factor) * 2000) + if(!occupant) + return + + var/mob/living/mob_occupant = occupant + + if(mob_occupant.stat == DEAD) // We don't bother with dead people. + return + + if(mob_occupant.health >= mob_occupant.getMaxHealth()) // Don't bother with fully healed people. + on = FALSE + update_icon() + playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. + radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language()) + if(autoeject) // Eject if configured. + radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language()) + open_machine() + return + + var/datum/gas_mixture/air1 = AIR1 + + if(air1.gases.len) + if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. + mob_occupant.Sleeping((mob_occupant.bodytemperature / sleep_factor) * 2000) + mob_occupant.Unconscious((mob_occupant.bodytemperature / unconscious_factor) * 2000) + if(beaker) + if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. + beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic. + beaker.reagents.reaction(occupant, VAPOR) + air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this. + if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). + reagent_transfer = 0 - if(beaker) - if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. - beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic. - beaker.reagents.reaction(occupant, VAPOR) - air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this. - if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). - reagent_transfer = 0 return 1 /obj/machinery/atmospherics/components/unary/cryo_cell/process_atmos() ..() + if(!on) return + var/datum/gas_mixture/air1 = AIR1 + if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases["o2"][MOLES] < 5) // Turn off if the machine won't work. on = FALSE update_icon() return + if(occupant) var/mob/living/mob_occupant = occupant var/cold_protection = 0 - var/mob/living/carbon/human/H = occupant - if(istype(H)) + var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant. + + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant cold_protection = H.get_cold_protection(air1.temperature) - var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant. if(abs(temperature_delta) > 1) var/air_heat_capacity = air1.heat_capacity() - var/heat = ((1 - cold_protection) / 10 + conduction_coefficient) \ - * temperature_delta * \ - (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity)) + var/heat = ((1 - cold_protection) * 0.1 + conduction_coefficient) * temperature_delta * (1 / air_heat_capacity + 1 / heat_capacity) air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB) mob_occupant.bodytemperature = max(mob_occupant.bodytemperature + heat / heat_capacity, TCMB) @@ -248,7 +255,7 @@ user.visible_message("You see [user] kicking against the glass of [src]!", \ "You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)", \ "You hear a thump from [src].") - if(do_after(user,(breakout_time), target = src)) + if(do_after(user, breakout_time, target = src)) if(!user || user.stat != CONSCIOUS || user.loc != src ) return user.visible_message("[user] successfully broke out of [src]!", \ @@ -284,16 +291,10 @@ var/reagentlist = pretty_string_from_reagent_list(I.reagents.reagent_list) log_game("[key_name(user)] added an [I] to cyro containing [reagentlist]") return - if(!on && !occupant && !state_open) - if(default_deconstruction_screwdriver(user, "pod-off", "pod-off", I)) - return - if(exchange_parts(user, I)) - return - if(default_change_direction_wrench(user, I)) - return - if(default_pry_open(I)) - return - if(default_deconstruction_crowbar(I)) + if(!on && !occupant && !state_open && (default_deconstruction_screwdriver(user, "pod-o", "pod-off", I) || exchange_parts(user, I)) \ + || default_change_direction_wrench(user, I) \ + || default_pry_open(I) \ + || default_deconstruction_crowbar(I)) return return ..() @@ -384,16 +385,16 @@ update_icon() /obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user) - return //we don't see the pipe network while inside cryo. + return // we don't see the pipe network while inside cryo. /obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user) user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1) /obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through() - return //can't ventcrawl in or out of cryo. + return // can't ventcrawl in or out of cryo. /obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes() - return 0 //you can't see the pipe network when inside a cryo cell. + return 0 // you can't see the pipe network when inside a cryo cell. /obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature() var/datum/gas_mixture/G = AIR1 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index d46d5b47a0..215ee77572 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -45,6 +45,7 @@ /obj/machinery/atmospherics/components/unary/outlet_injector/process_atmos() ..() + injecting = 0 if(!on || !is_operational()) @@ -63,6 +64,7 @@ update_parents() /obj/machinery/atmospherics/components/unary/outlet_injector/proc/inject() + if(on || injecting || !is_operational()) return @@ -72,11 +74,8 @@ if(air_contents.temperature > 0) var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) - loc.assume_air(removed) - update_parents() flick("inje_inject", src) @@ -88,6 +87,7 @@ radio_connection = SSradio.add_object(src, frequency) /obj/machinery/atmospherics/components/unary/outlet_injector/proc/broadcast_status() + if(!radio_connection) return @@ -112,6 +112,7 @@ ..() /obj/machinery/atmospherics/components/unary/outlet_injector/receive_signal(datum/signal/signal) + if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command")) return @@ -137,6 +138,7 @@ spawn(2) broadcast_status() + update_icon() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm index 0be10fecf0..c0a887e3aa 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm @@ -33,7 +33,9 @@ AIR1 = air_contents /obj/machinery/atmospherics/components/unary/oxygen_generator/process_atmos() + ..() + if(!on) return 0 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 17fa3b2cdf..dc482eda02 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -128,8 +128,10 @@ return data /obj/machinery/atmospherics/components/unary/thermomachine/ui_act(action, params) + if(..()) return + switch(action) if("power") on = !on @@ -141,7 +143,7 @@ var/adjust = text2num(params["adjust"]) if(target == "input") target = input("Set new target ([min_temperature]-[max_temperature] K):", name, target_temperature) as num|null - if(!isnull(target) && !..()) + if(!isnull(target)) . = TRUE else if(adjust) target = target_temperature + adjust @@ -152,6 +154,7 @@ if(.) target_temperature = Clamp(target, min_temperature, max_temperature) investigate_log("was set to [target_temperature] K by [key_name(usr)]", INVESTIGATE_ATMOS) + update_icon() /obj/machinery/atmospherics/components/unary/thermomachine/freezer diff --git a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm index 32076d82e1..a6ac9760e8 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/unary_devices.dm @@ -7,14 +7,10 @@ /obj/machinery/atmospherics/components/unary/SetInitDirections() initialize_directions = dir -/* -Iconnery -*/ /obj/machinery/atmospherics/components/unary/on_construction() ..() update_icon() /obj/machinery/atmospherics/components/unary/hide(intact) update_icon() - ..(intact) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index df44b4ca9e..aa6c12a006 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -22,9 +22,9 @@ var/pressure_checks = EXT_BOUND var/external_pressure_bound = ONE_ATMOSPHERE var/internal_pressure_bound = 0 - //EXT_BOUND: Do not pass external_pressure_bound - //INT_BOUND: Do not pass internal_pressure_bound - //NO_BOUND: Do not pass either + // EXT_BOUND: Do not pass external_pressure_bound + // INT_BOUND: Do not pass internal_pressure_bound + // NO_BOUND: Do not pass either var/frequency = 1439 var/datum/radio_frequency/radio_connection @@ -98,7 +98,7 @@ if(pump_direction & RELEASING) icon_state = "vent_out" - else //pump_direction == SIPHONING + else // pump_direction == SIPHONING icon_state = "vent_in" /obj/machinery/atmospherics/components/unary/vent_pump/process_atmos() @@ -114,7 +114,7 @@ var/datum/gas_mixture/environment = loc.return_air() var/environment_pressure = environment.return_pressure() - if(pump_direction & RELEASING) //internal -> external + if(pump_direction & RELEASING) // internal -> external var/pressure_delta = 10000 if(pressure_checks&EXT_BOUND) @@ -131,23 +131,22 @@ loc.assume_air(removed) air_update_turf() - else //external -> internal + else // external -> internal var/pressure_delta = 10000 if(pressure_checks&EXT_BOUND) pressure_delta = min(pressure_delta, (environment_pressure - external_pressure_bound)) if(pressure_checks&INT_BOUND) pressure_delta = min(pressure_delta, (internal_pressure_bound - air_contents.return_pressure())) - if(pressure_delta > 0) - if(environment.temperature > 0) - var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION) + if(pressure_delta > 0 && environment.temperature > 0) + var/transfer_moles = pressure_delta * air_contents.volume / (environment.temperature * R_IDEAL_GAS_EQUATION) - var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) - if (isnull(removed)) //in space - return + var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) + if (isnull(removed)) // in space + return - air_contents.merge(removed) - air_update_turf() + air_contents.merge(removed) + air_update_turf() update_parents() //Radio remote control @@ -163,7 +162,7 @@ return var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal + signal.transmission_method = 1 // radio signal signal.source = src signal.data = list( @@ -200,7 +199,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/receive_signal(datum/signal/signal) if(!is_operational()) return - //log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/atmospherics/components/unary/vent_pump/receive_signal([signal.debug_print()])") + // log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/atmospherics/components/unary/vent_pump/receive_signal([signal.debug_print()])") if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) return @@ -248,20 +247,20 @@ if("status" in signal.data) broadcast_status() - return //do not update_icon + return // do not update_icon - //log_admin("DEBUG \[[world.timeofday]\]: vent_pump/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]") + // log_admin("DEBUG \[[world.timeofday]\]: vent_pump/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]") broadcast_status() update_icon() /obj/machinery/atmospherics/components/unary/vent_pump/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weldingtool)) var/obj/item/weldingtool/WT = W - if (WT.remove_fuel(0,user)) + if (WT.remove_fuel(0, user)) playsound(loc, WT.usesound, 40, 1) to_chat(user, "You begin welding the vent...") - if(do_after(user, 20*W.toolspeed, target = src)) - if(!src || !WT.isOn()) + if(do_after(user, W.toolspeed * 20, target = src)) + if(!src || !WT.isOn()) return playsound(src.loc, 'sound/items/welder2.ogg', 50, 1) if(!welded) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 1abf84df10..e1365e5a7e 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -152,11 +152,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/process_atmos() ..() - if(!is_operational()) + if(welded || !is_operational()) return FALSE - if(!NODE1) + if(!NODE1 || !on) on = FALSE - if(!on || welded) return FALSE scrub(loc) if(widenet) @@ -257,7 +256,7 @@ //There is no easy way for an object to be notified of changes to atmos can pass flags_1 // So we check every machinery process (2 seconds) /obj/machinery/atmospherics/components/unary/vent_scrubber/process() - if (widenet) + if(widenet) check_turfs() //we populate a list of turfs with nonatmos-blocked cardinal turfs AND @@ -270,9 +269,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/receive_signal(datum/signal/signal) - if(!is_operational()) - return - if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) + if(!is_operational() || !signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command")) return 0 if("power" in signal.data) diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index bcb6305344..124caa23be 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -75,16 +75,14 @@ radio_connection.post_signal(src, signal) /obj/machinery/meter/proc/status() - var/t = "" if (src.target) var/datum/gas_mixture/environment = target.return_air() if(environment) - t += "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)] K ([round(environment.temperature-T0C,0.01)]°C)" + . = "The pressure gauge reads [round(environment.return_pressure(), 0.01)] kPa; [round(environment.temperature,0.01)] K ([round(environment.temperature-T0C,0.01)]°C)." else - t += "The sensor error light is blinking." + . = "The sensor error light is blinking." else - t += "The connect error light is blinking." - return t + . = "The connect error light is blinking." /obj/machinery/meter/examine(mob/user) ..() diff --git a/code/modules/atmospherics/machinery/other/miner.dm b/code/modules/atmospherics/machinery/other/miner.dm index 1db4c5edd3..75e6807fa5 100644 --- a/code/modules/atmospherics/machinery/other/miner.dm +++ b/code/modules/atmospherics/machinery/other/miner.dm @@ -36,7 +36,7 @@ /obj/machinery/atmospherics/miner/examine(mob/user) ..() if(broken) - to_chat(user, "Its debug output is printing \"[broken_message]\"") + to_chat(user, "Its debug output is printing \"[broken_message]\".") /obj/machinery/atmospherics/miner/proc/check_operation() if(!active) diff --git a/code/modules/cargo/export_scanner.dm b/code/modules/cargo/export_scanner.dm index 2a9cd4a891..79f6b9dfaf 100644 --- a/code/modules/cargo/export_scanner.dm +++ b/code/modules/cargo/export_scanner.dm @@ -13,7 +13,7 @@ /obj/item/device/export_scanner/examine(user) ..() if(!cargo_console) - to_chat(user, "The [src] is currently not linked to a cargo console.") + to_chat(user, "[src] is not currently linked to a cargo console.") /obj/item/device/export_scanner/afterattack(obj/O, mob/user, proximity) if(!istype(O) || !proximity) diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index d5cf3aaf2c..7ea6c60000 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -61,7 +61,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the var/t = 0 var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic() - sleep(1) // Lock up the caller until this is received. + stoplag(1) // Lock up the caller until this is received. t++ if(client) @@ -112,7 +112,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the var/t = 0 var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic() - sleep(1) // Lock up the caller until this is received. + stoplag(1) // Lock up the caller until this is received. t++ if(client) @@ -131,7 +131,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the if (register_asset) register_asset(file,files[file]) send_asset(client,file) - sleep(0) //queuing calls like this too quickly can cause issues in some client versions + stoplag(0) //queuing calls like this too quickly can cause issues in some client versions //This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up. //if it's an icon or something be careful, you'll have to copy it before further use. diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index e755ff28ac..9b694d58b7 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -631,10 +631,9 @@ GLOBAL_LIST(external_rsc_urls) /client/Stat() . = ..() if (holder) - sleep(1) + stoplag(1) else - sleep(5) - stoplag() + stoplag(5) //send resources to the client. It's here in its own proc so we can move it around easiliy if need be /client/proc/send_resources() diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 2f6b632ae8..02d3b8e094 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -147,7 +147,7 @@ how_cool_are_your_threads += "[src]'s storage opens when clicked.\n" else how_cool_are_your_threads += "[src]'s storage opens when dragged to yourself.\n" - how_cool_are_your_threads += "[src] can store [pockets.storage_slots] item[pockets.storage_slots > 1 ? "s" : ""].\n" + how_cool_are_your_threads += "[src] can store [pockets.storage_slots] item\s.\n" how_cool_are_your_threads += "[src] can store items that are [weightclass2text(pockets.max_w_class)] or smaller.\n" if(pockets.quickdraw) how_cool_are_your_threads += "You can quickly remove an item from [src] using Alt-Click.\n" diff --git a/code/modules/clothing/outfits/event.dm b/code/modules/clothing/outfits/event.dm new file mode 100644 index 0000000000..72edf7a358 --- /dev/null +++ b/code/modules/clothing/outfits/event.dm @@ -0,0 +1,31 @@ +/datum/outfit/santa //ho ho ho! + name = "Santa Claus" + + uniform = /obj/item/clothing/under/color/red + shoes = /obj/item/clothing/shoes/sneakers/red + suit = /obj/item/clothing/suit/space/santa + head = /obj/item/clothing/head/santa + back = /obj/item/storage/backpack/santabag + mask = /obj/item/clothing/mask/breath + r_pocket = /obj/item/device/flashlight + gloves = /obj/item/clothing/gloves/color/red + belt = /obj/item/tank/internals/emergency_oxygen/double + id = /obj/item/card/id/gold + +/datum/outfit/santa/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + if(visualsOnly) + return + H.fully_replace_character_name(H.real_name, "Santa Claus") + H.mind.assigned_role = "Santa" + H.mind.special_role = "Santa" + + H.hair_style = "Long Hair" + H.facial_hair_style = "Full Beard" + H.hair_color = "FFF" + H.facial_hair_color = "FFF" + + var/obj/item/storage/backpack/bag = H.back + var/obj/item/a_gift/gift = new(H) + while(bag.can_be_inserted(gift, 1)) + bag.handle_item_insertion(gift, 1) + gift = new(H) diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm index bf3a1f28e0..561b0c15d7 100644 --- a/code/modules/clothing/shoes/bananashoes.dm +++ b/code/modules/clothing/shoes/bananashoes.dm @@ -34,7 +34,7 @@ /obj/item/clothing/shoes/clown_shoes/banana_shoes/examine(mob/user) ..() - to_chat(user, "The shoes are [on ? "enabled" : "disabled"]") + to_chat(user, "The shoes are [on ? "enabled" : "disabled"].") /obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user) GET_COMPONENT(bananium, /datum/component/material_container) diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 9e89176f72..27b5462b56 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -5,6 +5,7 @@ var/magboot_state = "magboots" var/magpulse = 0 var/slowdown_active = 2 + permeability_coefficient = 0.05 actions_types = list(/datum/action/item_action/toggle) strip_delay = 70 equip_delay_other = 70 diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 026b011e39..ab2763f62e 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -23,6 +23,7 @@ armor = list(melee = 25, bullet = 25, laser = 25, energy = 25, bomb = 50, bio = 10, rad = 0, fire = 70, acid = 50) strip_delay = 70 resistance_flags = 0 + permeability_coefficient = 0.05 //Thick soles, and covers the ankle pockets = /obj/item/storage/internal/pocket/shoes /obj/item/clothing/shoes/combat/swat //overpowered boots for death squads @@ -38,6 +39,7 @@ icon_state = "wizard" strip_delay = 50 equip_delay_other = 50 + permeability_coefficient = 0.9 /obj/item/clothing/shoes/sandal/marisa desc = "A pair of magic black shoes." @@ -54,7 +56,7 @@ desc = "A pair of yellow rubber boots, designed to prevent slipping on wet surfaces." name = "galoshes" icon_state = "galoshes" - permeability_coefficient = 0.05 + permeability_coefficient = 0.01 flags_1 = NOSLIP_1 slowdown = SHOES_SLOWDOWN+1 strip_delay = 50 @@ -102,6 +104,7 @@ strip_delay = 50 equip_delay_other = 50 resistance_flags = 0 + permeability_coefficient = 0.05 //Thick soles, and covers the ankle pockets = /obj/item/storage/internal/pocket/shoes /obj/item/clothing/shoes/jackboots/fast @@ -112,6 +115,7 @@ desc = "Boots lined with 'synthetic' animal fur." icon_state = "winterboots" item_state = "winterboots" + permeability_coefficient = 0.15 cold_protection = FEET|LEGS min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET|LEGS @@ -125,6 +129,7 @@ item_state = "jackboots" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + permeability_coefficient = 0.15 strip_delay = 40 equip_delay_other = 40 pockets = /obj/item/storage/internal/pocket/shoes @@ -171,6 +176,7 @@ item_state = "roman" strip_delay = 100 equip_delay_other = 100 + permeability_coefficient = 0.9 /obj/item/clothing/shoes/griffin name = "griffon boots" @@ -188,6 +194,7 @@ resistance_flags = FIRE_PROOF pockets = /obj/item/storage/internal/pocket/shoes actions_types = list(/datum/action/item_action/bhop) + permeability_coefficient = 0.05 var/jumpdistance = 5 //-1 from to see the actual distance, e.g 4 goes over 3 tiles var/jumpspeed = 3 var/recharging_rate = 60 //default 6 seconds between each dash diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 0c16a2b764..d6094d1c1f 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -869,7 +869,8 @@ var/obj/item/device/flightpack/pack = null var/mob/living/carbon/human/wearer = null var/active = FALSE - resistance_flags = FIRE_PROOF + permeability_coefficient = 0.01 + resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/flightshoes/Destroy() pack = null diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index b42562e8ff..a3b68dc151 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -16,7 +16,7 @@ /obj/item/clothing/suit/space/eva/plasmaman/examine(mob/user) ..() - to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit.") + to_chat(user, "There [extinguishes_left == 1 ? "is" : "are"] [extinguishes_left] extinguisher charge\s left in this suit.") /obj/item/clothing/suit/space/eva/plasmaman/proc/Extinguish(mob/living/carbon/human/H) diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm index bc2b3c2666..df3fc518d0 100644 --- a/code/modules/events/holiday/xmas.dm +++ b/code/modules/events/holiday/xmas.dm @@ -109,58 +109,24 @@ priority_announce("Santa is coming to town!", "Unknown Transmission") /datum/round_event/santa/start() - for(var/mob/M in GLOB.dead_mob_list) - spawn(0) - var/response = alert(M, "Santa is coming to town! Do you want to be santa?", "Ho ho ho!", "Yes", "No") - if(response == "Yes" && M && M.client && M.stat == DEAD && !santa) - santa = new /mob/living/carbon/human(pick(GLOB.blobstart)) - santa.key = M.key - qdel(M) + var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be santa?", poll_time=150) + if(LAZYLEN(candidates)) + var/mob/dead/observer/Z = pick(candidates) + santa = new /mob/living/carbon/human(pick(GLOB.blobstart)) + santa.key = Z.key + qdel(Z) - santa.real_name = "Santa Claus" - santa.name = "Santa Claus" - santa.mind.name = "Santa Claus" - santa.mind.assigned_role = "Santa" - santa.mind.special_role = "Santa" + santa.equipOutfit(/datum/outfit/santa) + santa.update_icons() - santa.hair_style = "Long Hair" - santa.facial_hair_style = "Full Beard" - santa.hair_color = "FFF" - santa.facial_hair_color = "FFF" + var/datum/objective/santa_objective = new() + santa_objective.explanation_text = "Bring joy and presents to the station!" + santa_objective.completed = 1 //lets cut our santas some slack. + santa_objective.owner = santa.mind + santa.mind.objectives += santa_objective + santa.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents) + var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new(santa) + telespell.clothes_req = 0 //santa robes aren't actually magical. + santa.mind.AddSpell(telespell) //does the station have chimneys? WHO KNOWS! - santa.equip_to_slot_or_del(new /obj/item/clothing/under/color/red, slot_w_uniform) - santa.equip_to_slot_or_del(new /obj/item/clothing/suit/space/santa, slot_wear_suit) - santa.equip_to_slot_or_del(new /obj/item/clothing/head/santa, slot_head) - santa.equip_to_slot_or_del(new /obj/item/clothing/mask/breath, slot_wear_mask) - santa.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/red, slot_gloves) - santa.equip_to_slot_or_del(new /obj/item/clothing/shoes/sneakers/red, slot_shoes) - santa.equip_to_slot_or_del(new /obj/item/tank/internals/emergency_oxygen/double, slot_belt) - santa.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain, slot_ears) - santa.equip_to_slot_or_del(new /obj/item/storage/backpack/santabag, slot_back) - santa.equip_to_slot_or_del(new /obj/item/device/flashlight, slot_r_store) //most blob spawn locations are really dark. - - var/obj/item/card/id/gold/santacard = new(santa) - santacard.update_label("Santa Claus", "Santa") - var/datum/job/captain/J = new/datum/job/captain - santacard.access = J.get_access() - santa.equip_to_slot_or_del(santacard, slot_wear_id) - - santa.update_icons() - - var/obj/item/storage/backpack/bag = santa.back - var/obj/item/a_gift/gift = new(santa) - while(bag.can_be_inserted(gift, 1)) - bag.handle_item_insertion(gift, 1) - gift = new(santa) - - var/datum/objective/santa_objective = new() - santa_objective.explanation_text = "Bring joy and presents to the station!" - santa_objective.completed = 1 //lets cut our santas some slack. - santa_objective.owner = santa.mind - santa.mind.objectives += santa_objective - santa.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents) - var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new(santa) - telespell.clothes_req = 0 //santa robes aren't actually magical. - santa.mind.AddSpell(telespell) //does the station have chimneys? WHO KNOWS! - - to_chat(santa, "You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag.") + to_chat(santa, "You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag.") diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index df323a99ff..a9d3d3489d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -40,7 +40,7 @@ insert ascii eagle on american flag background here /obj/machinery/deepfryer/examine() ..() if(frying) - to_chat(usr, "You can make out [frying] in the oil.") + to_chat(usr, "You can make out \a [frying] in the oil.") /obj/machinery/deepfryer/attackby(obj/item/I, mob/user) if(!reagents.total_volume) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index b1eb0f2f72..372c085adb 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -147,6 +147,7 @@ var/obj/item/reagent_containers/food/snacks/meat/slab/allmeat[meat_produced] var/obj/item/stack/sheet/animalhide/skin + var/list/datum/disease/diseases = mob_occupant.get_static_viruses() if(ishuman(occupant)) var/mob/living/carbon/human/gibee = occupant @@ -180,26 +181,28 @@ mob_occupant.death(1) mob_occupant.ghostize() qdel(src.occupant) - spawn(src.gibtime) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - operating = FALSE - var/turf/T = get_turf(src) - var/list/turf/nearby_turfs = RANGE_TURFS(3,T) - T - if(skin) - skin.forceMove(loc) - skin.throw_at(pick(nearby_turfs),meat_produced,3) - for (var/i=1 to meat_produced) - var/obj/item/meatslab = allmeat[i] - meatslab.forceMove(loc) - meatslab.throw_at(pick(nearby_turfs),i,3) - for (var/turfs=1 to meat_produced) - var/turf/gibturf = pick(nearby_turfs) - if (!gibturf.density && src in view(gibturf)) - new gibtype(gibturf,i) + addtimer(CALLBACK(src, .proc/make_meat, skin, allmeat, meat_produced, gibtype, diseases), gibtime) - pixel_x = initial(pixel_x) //return to its spot after shaking - operating = FALSE - update_icon() +/obj/machinery/gibber/proc/make_meat(obj/item/stack/sheet/animalhide/skin, list/obj/item/reagent_containers/food/snacks/meat/slab/allmeat, meat_produced, gibtype, list/datum/disease/diseases) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + operating = FALSE + var/turf/T = get_turf(src) + var/list/turf/nearby_turfs = RANGE_TURFS(3,T) - T + if(skin) + skin.forceMove(loc) + skin.throw_at(pick(nearby_turfs),meat_produced,3) + for (var/i=1 to meat_produced) + var/obj/item/meatslab = allmeat[i] + meatslab.forceMove(loc) + meatslab.throw_at(pick(nearby_turfs),i,3) + for (var/turfs=1 to meat_produced) + var/turf/gibturf = pick(nearby_turfs) + if (!gibturf.density && src in view(gibturf)) + new gibtype(gibturf,i,diseases) + + pixel_x = initial(pixel_x) //return to its spot after shaking + operating = FALSE + update_icon() //auto-gibs anything that bumps into it /obj/machinery/gibber/autogibber diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index fb871f2c3a..0699e22547 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -135,7 +135,7 @@ for(var/thing in O.viruses) var/datum/disease/D = thing - if(!(D.spread_flags & SPECIAL)) + if(!(D.spread_flags & VIRUS_SPREAD_SPECIAL)) B.data["viruses"] += D.Copy() if(O.has_dna()) B.data["blood_DNA"] = O.dna.unique_enzymes diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 316b2298ca..141336cf5d 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -136,7 +136,7 @@ to_chat(user, "There [plural? "are" : "is"] [honeycombs.len] uncollected honeycomb[plural ? "s":""] in the apiary.") if(honeycombs.len >= get_max_honeycomb()) - to_chat(user, "there's no room for more honeycomb!") + to_chat(user, "There's no room for more honeycomb!") /obj/structure/beebox/attackby(obj/item/I, mob/user, params) diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index de881a0611..9235bb83d7 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -80,7 +80,7 @@ if(seed) to_chat(user, "A sample is already loaded into the machine!") else - if(!user.temporarilyRemoveItemFromInventory()) + if(!user.temporarilyRemoveItemFromInventory(I)) return insert_seed(I) to_chat(user, "You add [I] to the machine.") diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 4f5f9cbaf7..a0b26718d5 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -313,11 +313,11 @@ else if (plant_health <= (myseed.endurance / 2)) to_chat(user, "It looks unhealthy.") else - to_chat(user, "[src] is empty.") + to_chat(user, "It's empty.") if(!self_sustaining) - to_chat(user, "Water: [waterlevel]/[maxwater]") - to_chat(user, "Nutrient: [nutrilevel]/[maxnutri]") + to_chat(user, "Water: [waterlevel]/[maxwater].") + to_chat(user, "Nutrient: [nutrilevel]/[maxnutri].") if(self_sufficiency_progress > 0) var/percent_progress = round(self_sufficiency_progress * 100 / self_sufficiency_req) to_chat(user, "Treatment for self-sustenance are [percent_progress]% complete.") @@ -325,9 +325,9 @@ to_chat(user, "It doesn't require any water or nutrients.") if(weedlevel >= 5) - to_chat(user, "[src] is filled with weeds!") + to_chat(user, "It's filled with weeds!") if(pestlevel >= 5) - to_chat(user, "[src] is filled with tiny worms!") + to_chat(user, "It's filled with tiny worms!") to_chat(user, "" ) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index c02737a2fd..20e292eaa2 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -36,7 +36,7 @@ to_chat(user, "Does 80 damage if the target is backstabbed, instead of 50.") for(var/t in trophies) var/obj/item/crusher_trophy/T = t - to_chat(user, "It has \a [T] attached, which cause [T.effect_desc()].") + to_chat(user, "It has \a [T] attached, which causes [T.effect_desc()].") /obj/item/twohanded/required/kinetic_crusher/attackby(obj/item/A, mob/living/user) if(istype(A, /obj/item/crowbar)) @@ -220,7 +220,7 @@ bonus_value = 8 /obj/item/crusher_trophy/watcher_wing/effect_desc() - return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second[bonus_value*0.1 == 1 ? "":"s"]" + return "mark detonation to prevent certain creatures from using certain attacks for [bonus_value*0.1] second\s" /obj/item/crusher_trophy/watcher_wing/on_mark_detonation(mob/living/target, mob/living/user) if(ishostile(target)) @@ -265,7 +265,7 @@ bonus_value = 3 /obj/item/crusher_trophy/legion_skull/effect_desc() - return "a kinetic crusher to recharge [bonus_value*0.1] second[bonus_value*0.1 == 1 ? "":"s"] faster" + return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster" /obj/item/crusher_trophy/legion_skull/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user) . = ..() diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index d76278a410..ecbd8a4135 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -14,7 +14,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) /obj/item/extraction_pack/examine() . = ..() - usr.show_message("It has [uses_left] uses remaining.", 1) + usr.show_message("It has [uses_left] use\s remaining.", 1) /obj/item/extraction_pack/attack_self(mob/user) var/list/possible_beacons = list() diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index efc46faa31..9424db47e1 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -846,7 +846,7 @@ agent = "dragon's blood" desc = "What do dragons have to do with Space Station 13?" stage_prob = 20 - severity = BIOHAZARD + severity = VIRUS_SEVERITY_BIOHAZARD visibility_flags = 0 stage1 = list("Your bones ache.") stage2 = list("Your skin feels scaly.") diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 8e547eeb12..30d5652ab4 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -139,7 +139,7 @@ if(blood_data["viruses"]) for(var/thing in blood_data["viruses"]) var/datum/disease/D = thing - if((D.spread_flags & SPECIAL) || (D.spread_flags & NON_CONTAGIOUS)) + if((D.spread_flags & VIRUS_SPREAD_SPECIAL) || (D.spread_flags & VIRUS_SPREAD_NON_CONTAGIOUS)) continue C.ForceContractDisease(D) if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type))) @@ -258,14 +258,14 @@ temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter qdel(drop)//the drip is replaced by a bigger splatter else - drop = new(T) + drop = new(T, get_static_viruses()) drop.transfer_mob_blood_dna(src) return // Find a blood decal or create a new one. var/obj/effect/decal/cleanable/blood/B = locate() in T if(!B) - B = new /obj/effect/decal/cleanable/blood/splatter(T) + B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses()) B.transfer_mob_blood_dna(src) //give blood info to the blood decal. if(temp_blood_DNA) B.blood_DNA |= temp_blood_DNA diff --git a/code/modules/mob/living/brain/emote.dm b/code/modules/mob/living/brain/emote.dm index aaee807402..a2182c605a 100644 --- a/code/modules/mob/living/brain/emote.dm +++ b/code/modules/mob/living/brain/emote.dm @@ -2,7 +2,7 @@ mob_type_allowed_typecache = list(/mob/living/brain) mob_type_blacklist_typecache = list() -/datum/emote/brain/can_run_emote(mob/user) +/datum/emote/brain/can_run_emote(mob/user, status_check = TRUE) . = ..() var/mob/living/brain/B = user if(!istype(B) || (!(B.container && istype(B.container, /obj/item/device/mmi)))) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 80c6d836a0..75b53d11cb 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -756,7 +756,7 @@ B.damaged_brain = 0 for(var/thing in viruses) var/datum/disease/D = thing - if(D.severity != NONTHREAT) + if(D.severity != VIRUS_SEVERITY_POSITIVE) D.cure(0) if(admin_revive) regenerate_limbs() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index d90db23679..66f4fc8fb2 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -113,13 +113,13 @@ for(var/thing in viruses) var/datum/disease/D = thing - if(D.IsSpreadByTouch()) - user.ContractDisease(D) + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + user.ContactContractDisease(D) for(var/thing in user.viruses) var/datum/disease/D = thing - if(D.IsSpreadByTouch()) - ContractDisease(D) + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + ContactContractDisease(D) if(lying && surgeries.len) if(user.a_intent == INTENT_HELP) @@ -132,13 +132,13 @@ /mob/living/carbon/attack_paw(mob/living/carbon/monkey/M) for(var/thing in viruses) var/datum/disease/D = thing - if(D.IsSpreadByTouch()) - M.ContractDisease(D) + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + M.ContactContractDisease(D) for(var/thing in M.viruses) var/datum/disease/D = thing - if(D.IsSpreadByTouch()) - ContractDisease(D) + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + ContactContractDisease(D) if(M.a_intent == INTENT_HELP) help_shake_act(M) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 282de04ede..c3ae5c39c3 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -6,9 +6,9 @@ /mob/living/carbon/human/spawn_gibs(with_bodyparts) if(with_bodyparts) - new /obj/effect/gibspawner/human(get_turf(src), dna) + new /obj/effect/gibspawner/human(get_turf(src), dna, get_static_viruses()) else - new /obj/effect/gibspawner/humanbodypartless(get_turf(src), dna) + new /obj/effect/gibspawner/humanbodypartless(get_turf(src), dna, get_static_viruses()) /mob/living/carbon/human/spawn_dust(just_ash = FALSE) if(just_ash) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 6fb2ab25f5..89a30f0733 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -80,7 +80,7 @@ else H.endTailWag() -/datum/emote/living/carbon/human/wag/can_run_emote(mob/user) +/datum/emote/living/carbon/human/wag/can_run_emote(mob/user, status_check = TRUE) if(!..()) return FALSE var/mob/living/carbon/human/H = user @@ -115,7 +115,7 @@ else . = "closes " + message -/datum/emote/living/carbon/human/wing/can_run_emote(mob/user) +/datum/emote/living/carbon/human/wing/can_run_emote(mob/user, status_check = TRUE) if(!..()) return FALSE var/mob/living/carbon/human/H = user diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0d5007c05a..62cf6a535a 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -265,6 +265,11 @@ C.dropItemToGround(I) else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand C.put_in_hands(new mutanthands()) + + if(VIRUSIMMUNE in species_traits) + for(var/datum/disease/A in C.viruses) + A.cure(FALSE) + if(NOAROUSAL in species_traits) C.canbearoused = FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 619175d779..5f1591b996 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -593,7 +593,7 @@ limbs_id = "clockgolem" info_text = "As a clockwork golem, you are faster than \ other types of golem (being a machine), and are immune to electric shocks." - species_traits = list(NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, VIRUSIMMUNE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE) + species_traits = list(NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, VIRUSIMMUNE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE, PIERCEIMMUNE) armor = 40 //Reinforced, but also slim to allow for fast movement attack_verb = "smash" attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg' diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 8cd7dd5643..2bf605de9c 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -408,6 +408,8 @@ /mob/living/carbon/proc/handle_liver() var/obj/item/organ/liver/liver = getorganslot("liver") + if((!dna && !liver) || (NOLIVER in dna.species.species_traits)) + return if(liver) if(liver.damage >= 100) liver.failing = TRUE @@ -415,8 +417,6 @@ else liver.failing = FALSE else - if((dna && dna.species && (NOLIVER in dna.species.species_traits))) - return liver_failure() /mob/living/carbon/proc/undergoing_liver_failure() diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 40219161c6..c38ab397c8 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -18,7 +18,7 @@ return /mob/living/proc/spawn_gibs() - new /obj/effect/gibspawner/generic(get_turf(src)) + new /obj/effect/gibspawner/generic(get_turf(src), null, get_static_viruses()) /mob/living/proc/spill_organs() return diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index bbe02a3f8e..816e639306 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -220,7 +220,7 @@ message = "laughs." emote_type = EMOTE_AUDIBLE -/datum/emote/living/laugh/can_run_emote(mob/living/user) +/datum/emote/living/laugh/can_run_emote(mob/living/user, status_check = TRUE) . = ..() if(. && iscarbon(user)) var/mob/living/carbon/C = user @@ -513,3 +513,16 @@ else qdel(N) to_chat(user, "You don't have any free hands to make a circle with.") + +/datum/emote/living/slap + key = "slap" + key_third_person = "slaps" + restraint_check = TRUE + +/datum/emote/living/slap/run_emote(mob/user, params) + . = ..() + var/obj/item/slapper/N = new(user) + if(user.put_in_hands(N)) + to_chat(user, "You ready your slapping hand.") + else + to_chat(user, "You're incapable of slapping in your current state.") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 2fc6f79ec3..eae437caf6 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -108,6 +108,17 @@ //Even if we don't push/swap places, we "touched" them, so spread fire spreadFire(M) + //Also diseases + for(var/thing in viruses) + var/datum/disease/D = thing + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + M.ContactContractDisease(D) + + for(var/thing in M.viruses) + var/datum/disease/D = thing + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + ContactContractDisease(D) + if(now_pushing) return 1 @@ -507,7 +518,7 @@ if((newdir in GLOB.cardinals) && (prob(50))) newdir = turn(get_dir(target_turf, start), 180) if(!blood_exists) - new /obj/effect/decal/cleanable/trail_holder(start) + new /obj/effect/decal/cleanable/trail_holder(start, get_static_viruses()) for(var/obj/effect/decal/cleanable/trail_holder/TH in start) if((!(newdir in TH.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && TH.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled) diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 519118744c..8f50599c39 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,177 +1,172 @@ -#define UPDATE_BUFFER 25 // 2.5 seconds - -// CAMERA CHUNK -// -// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. -// Allows the AI Eye to stream these chunks and know what it can and cannot see. - -/datum/camerachunk - var/list/obscuredTurfs = list() - var/list/visibleTurfs = list() - var/list/obscured = list() - var/list/cameras = list() - var/list/turfs = list() - var/list/seenby = list() +#define UPDATE_BUFFER 25 // 2.5 seconds + +// CAMERA CHUNK +// +// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. +// Allows the AI Eye to stream these chunks and know what it can and cannot see. + +/datum/camerachunk + var/list/obscuredTurfs = list() + var/list/visibleTurfs = list() + var/list/obscured = list() + var/list/cameras = list() + var/list/turfs = list() + var/list/seenby = list() var/visible = FALSE - var/changed = 0 - var/updating = 0 - var/x = 0 - var/y = 0 - var/z = 0 - -// Add an AI eye to the chunk, then update if changed. - -/datum/camerachunk/proc/add(mob/camera/aiEye/eye) - var/client/client = eye.GetViewerClient() - if(client) - client.images += obscured - eye.visibleCameraChunks += src - visible++ - seenby += eye - if(changed && !updating) - update() - -// Remove an AI eye from the chunk, then update if changed. - -/datum/camerachunk/proc/remove(mob/camera/aiEye/eye) - var/client/client = eye.GetViewerClient() - if(client) - client.images -= obscured - eye.visibleCameraChunks -= src - seenby -= eye - if(visible > 0) - visible-- - -// Called when a chunk has changed. I.E: A wall was deleted. - -/datum/camerachunk/proc/visibilityChanged(turf/loc) - if(!visibleTurfs[loc]) - return - hasChanged() - -// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will -// instead be flagged to update the next time an AI Eye moves near it. - -/datum/camerachunk/proc/hasChanged(update_now = 0) - if(visible || update_now) - if(!updating) - updating = 1 - spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once - update() - updating = 0 - else - changed = 1 - -// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. - -/datum/camerachunk/proc/update() - - set background = BACKGROUND_ENABLED - - var/list/newVisibleTurfs = list() - - for(var/camera in cameras) - var/obj/machinery/camera/c = camera - - if(!c) - continue - - if(!c.can_use()) - continue - - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) - if(get_dist(point, c) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue - - for(var/turf/t in c.can_see()) - // Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards. - // List associations use a tree or hashmap of some sort (alongside the list itself) - // so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing) - newVisibleTurfs[t] = t - - // Removes turf that isn't in turfs. - newVisibleTurfs &= turfs - - var/list/visAdded = newVisibleTurfs - visibleTurfs - var/list/visRemoved = visibleTurfs - newVisibleTurfs - - visibleTurfs = newVisibleTurfs - obscuredTurfs = turfs - newVisibleTurfs - - for(var/turf in visAdded) - var/turf/t = turf - if(t.obscured) - obscured -= t.obscured - for(var/eye in seenby) - var/mob/camera/aiEye/m = eye - if(!m) - continue - var/client/client = m.GetViewerClient() - if(client) - client.images -= t.obscured - - for(var/turf in visRemoved) - var/turf/t = turf - if(obscuredTurfs[t]) - if(!t.obscured) - t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1) - t.obscured.plane = LIGHTING_PLANE+1 - obscured += t.obscured - for(var/eye in seenby) - var/mob/camera/aiEye/m = eye - if(!m) - seenby -= m - continue - var/client/client = m.GetViewerClient() - if(client) - client.images += t.obscured - - changed = 0 - -// Create a new camera chunk, since the chunks are made as they are needed. - -/datum/camerachunk/New(loc, x, y, z) - - // 0xf = 15 - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) - - src.x = x - src.y = y - src.z = z - - for(var/obj/machinery/camera/c in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) - if(c.can_use()) - cameras += c - - for(var/turf/t in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) - turfs[t] = t - - for(var/camera in cameras) - var/obj/machinery/camera/c = camera - if(!c) - continue - - if(!c.can_use()) - continue - - for(var/turf/t in c.can_see()) - // Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards. - // List associations use a tree or hashmap of some sort (alongside the list itself) - // so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing) - visibleTurfs[t] = t - - // Removes turf that isn't in turfs. - visibleTurfs &= turfs - - obscuredTurfs = turfs - visibleTurfs - - for(var/turf in obscuredTurfs) - var/turf/t = turf - if(!t.obscured) - t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1) - t.obscured.plane = LIGHTING_PLANE+1 - obscured += t.obscured - -#undef UPDATE_BUFFER -#undef CHUNK_SIZE \ No newline at end of file + var/changed = 0 + var/x = 0 + var/y = 0 + var/z = 0 + +// Add an AI eye to the chunk, then update if changed. + +/datum/camerachunk/proc/add(mob/camera/aiEye/eye) + var/client/client = eye.GetViewerClient() + if(client) + client.images += obscured + eye.visibleCameraChunks += src + visible++ + seenby += eye + if(changed) + update() + +// Remove an AI eye from the chunk, then update if changed. + +/datum/camerachunk/proc/remove(mob/camera/aiEye/eye) + var/client/client = eye.GetViewerClient() + if(client) + client.images -= obscured + eye.visibleCameraChunks -= src + seenby -= eye + if(visible > 0) + visible-- + +// Called when a chunk has changed. I.E: A wall was deleted. + +/datum/camerachunk/proc/visibilityChanged(turf/loc) + if(!visibleTurfs[loc]) + return + hasChanged() + +// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will +// instead be flagged to update the next time an AI Eye moves near it. + +/datum/camerachunk/proc/hasChanged(update_now = 0) + if(visible || update_now) + addtimer(CALLBACK(src, .proc/update), UPDATE_BUFFER, TIMER_UNIQUE) + else + changed = 1 + +// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. + +/datum/camerachunk/proc/update() + + set background = BACKGROUND_ENABLED + + var/list/newVisibleTurfs = list() + + for(var/camera in cameras) + var/obj/machinery/camera/c = camera + + if(!c) + continue + + if(!c.can_use()) + continue + + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) + if(get_dist(point, c) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue + + for(var/turf/t in c.can_see()) + // Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards. + // List associations use a tree or hashmap of some sort (alongside the list itself) + // so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing) + newVisibleTurfs[t] = t + + // Removes turf that isn't in turfs. + newVisibleTurfs &= turfs + + var/list/visAdded = newVisibleTurfs - visibleTurfs + var/list/visRemoved = visibleTurfs - newVisibleTurfs + + visibleTurfs = newVisibleTurfs + obscuredTurfs = turfs - newVisibleTurfs + + for(var/turf in visAdded) + var/turf/t = turf + if(t.obscured) + obscured -= t.obscured + for(var/eye in seenby) + var/mob/camera/aiEye/m = eye + if(!m) + continue + var/client/client = m.GetViewerClient() + if(client) + client.images -= t.obscured + + for(var/turf in visRemoved) + var/turf/t = turf + if(obscuredTurfs[t]) + if(!t.obscured) + t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1) + t.obscured.plane = LIGHTING_PLANE+1 + obscured += t.obscured + for(var/eye in seenby) + var/mob/camera/aiEye/m = eye + if(!m) + seenby -= m + continue + var/client/client = m.GetViewerClient() + if(client) + client.images += t.obscured + + changed = 0 + +// Create a new camera chunk, since the chunks are made as they are needed. + +/datum/camerachunk/New(loc, x, y, z) + + // 0xf = 15 + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) + + src.x = x + src.y = y + src.z = z + + for(var/obj/machinery/camera/c in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) + if(c.can_use()) + cameras += c + + for(var/turf/t in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) + turfs[t] = t + + for(var/camera in cameras) + var/obj/machinery/camera/c = camera + if(!c) + continue + + if(!c.can_use()) + continue + + for(var/turf/t in c.can_see()) + // Possible optimization: if(turfs[t]) here, rather than &= turfs afterwards. + // List associations use a tree or hashmap of some sort (alongside the list itself) + // so are surprisingly fast. (significantly faster than var/thingy/x in list, in testing) + visibleTurfs[t] = t + + // Removes turf that isn't in turfs. + visibleTurfs &= turfs + + obscuredTurfs = turfs - visibleTurfs + + for(var/turf in obscuredTurfs) + var/turf/t = turf + if(!t.obscured) + t.obscured = image('icons/effects/cameravis.dmi', t, null, LIGHTING_LAYER+1) + t.obscured.plane = LIGHTING_PLANE+1 + obscured += t.obscured + +#undef UPDATE_BUFFER +#undef CHUNK_SIZE diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index 3a46e46beb..8f8e574de5 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -376,8 +376,8 @@ var/datum/disease/D = thing //the medibot can't detect viruses that are undetectable to Health Analyzers or Pandemic machines. if(!(D.visibility_flags & HIDDEN_SCANNER || D.visibility_flags & HIDDEN_PANDEMIC) \ - && D.severity != NONTHREAT \ - && (D.stage > 1 || (D.spread_flags & AIRBORNE))) // medibot can't detect a virus in its initial stage unless it spreads airborne. + && D.severity != VIRUS_SEVERITY_POSITIVE \ + && (D.stage > 1 || (D.spread_flags & VIRUS_SPREAD_AIRBORNE))) // medibot can't detect a virus in its initial stage unless it spreads airborne. return 1 //STOP DISEASE FOREVER return 0 @@ -428,8 +428,8 @@ var/datum/disease/D = thing //detectable virus if((!(D.visibility_flags & HIDDEN_SCANNER)) || (!(D.visibility_flags & HIDDEN_PANDEMIC))) - if(D.severity != NONTHREAT) //virus is harmful - if((D.stage > 1) || (D.spread_flags & AIRBORNE)) + if(D.severity != VIRUS_SEVERITY_POSITIVE) //virus is harmful + if((D.stage > 1) || (D.spread_flags & VIRUS_SPREAD_AIRBORNE)) virus = 1 if(!reagent_id && (virus)) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 815b20c0c5..1980e57dbe 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -161,7 +161,7 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/proc/quick_attack_loop() if(next_move <= world.time) - sleep(1) + stoplag(1) .() //retry return sleep((next_move - world.time) * 1.5) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 7ceffa198b..16e09b59c8 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -125,7 +125,7 @@ /mob/living/simple_animal/parrot/examine(mob/user) ..() if(stat) - to_chat(user, pick("This parrot is no more", "This is a late parrot", "This is an ex-parrot")) + to_chat(user, pick("This parrot is no more.", "This is a late parrot.", "This is an ex-parrot.")) /mob/living/simple_animal/parrot/death(gibbed) if(held_item) @@ -1000,7 +1000,7 @@ var/datum/disease/parrot_possession/P = new P.parrot = src loc = H - H.ContractDisease(P) + H.ForceContractDisease(P) parrot_interest = null H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4165651dbd..02c1fa4b44 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -336,6 +336,18 @@ if(ismob(AM)) var/mob/M = AM + + //Share diseases that are spread by touch + for(var/thing in viruses) + var/datum/disease/D = thing + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + M.ContactContractDisease(D) + + for(var/thing in M.viruses) + var/datum/disease/D = thing + if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) + ContactContractDisease(D) + add_logs(src, M, "grabbed", addition="passive grab") if(!supress_message) visible_message("[src] has grabbed [M] passively!") @@ -941,6 +953,16 @@ /mob/proc/get_idcard() return +/mob/proc/get_static_viruses() //used when creating blood and other infective objects + if(!LAZYLEN(viruses)) + return + var/list/datum/disease/diseases = list() + for(var/datum/disease/D in viruses) + var/static_virus = D.Copy() + diseases += static_virus + return diseases + + /mob/vv_get_dropdown() . = ..() . += "---" diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index b36780d6e7..edd78839c3 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -14,7 +14,7 @@ /obj/item/computer_hardware/ai_slot/examine(mob/user) ..() if(stored_card) - to_chat(user, "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it") + to_chat(user, "There appears to be an intelliCard loaded. There appears to be a pinhole protecting a manual eject button. A screwdriver could probably press it.") /obj/item/computer_hardware/ai_slot/on_install(obj/item/device/modular_computer/M, mob/living/user = null) M.add_verb(device_type) diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm index 699ba1587a..27eb050655 100644 --- a/code/modules/modular_computers/hardware/printer.dm +++ b/code/modules/modular_computers/hardware/printer.dm @@ -11,11 +11,11 @@ /obj/item/computer_hardware/printer/diagnostics(mob/living/user) ..() - to_chat(user, "Paper level: [stored_paper]/[max_paper]") + to_chat(user, "Paper level: [stored_paper]/[max_paper].") /obj/item/computer_hardware/printer/examine(mob/user) ..() - to_chat(user, "Paper level: [stored_paper]/[max_paper]") + to_chat(user, "Paper level: [stored_paper]/[max_paper].") /obj/item/computer_hardware/printer/proc/print_text(var/text_to_print, var/paper_title = "") diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index 8eaaa40097..54ed7b4983 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -78,4 +78,4 @@ /obj/item/clothing/gloves/space_ninja/examine(mob/user) ..() if(flags_1 & NODROP_1) - to_chat(user, "The energy drain mechanism is: [candrain?"active":"inactive"].") + to_chat(user, "The energy drain mechanism is [candrain?"active":"inactive"].") diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 1cb8295df3..2693b5e5cf 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -185,7 +185,7 @@ /obj/item/device/camera/examine(mob/user) ..() - to_chat(user, "It has [pictures_left] photos left.") + to_chat(user, "It has [pictures_left] photo\s left.") /obj/item/device/camera/proc/camera_get_icon(list/turfs, turf/center) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 8634e5af5b..dc4296f262 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -315,7 +315,7 @@ src.add_fingerprint(user) var/obj/item/light/L = W if(istype(L, light_type)) - if(!user.temporarilyRemoveItemFromInventory()) + if(!user.temporarilyRemoveItemFromInventory(L)) return src.add_fingerprint(user) diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index 54d27d04c0..e1c80913e9 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -40,11 +40,11 @@ switch(construction_state) if(PA_CONSTRUCTION_UNSECURED) - to_chat(user, "Looks like it's not attached to the flooring") + to_chat(user, "Looks like it's not attached to the flooring.") if(PA_CONSTRUCTION_UNWIRED) - to_chat(user, "It is missing some cables") + to_chat(user, "It is missing some cables.") if(PA_CONSTRUCTION_PANEL_OPEN) - to_chat(user, "The panel is open") + to_chat(user, "The panel is open.") to_chat(user, "Alt-click to rotate it clockwise.") diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index d0f17c5210..dd98f092ea 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -257,11 +257,11 @@ ..() switch(construction_state) if(PA_CONSTRUCTION_UNSECURED) - to_chat(user, "Looks like it's not attached to the flooring") + to_chat(user, "Looks like it's not attached to the flooring.") if(PA_CONSTRUCTION_UNWIRED) - to_chat(user, "It is missing some cables") + to_chat(user, "It is missing some cables.") if(PA_CONSTRUCTION_PANEL_OPEN) - to_chat(user, "The panel is open") + to_chat(user, "The panel is open.") /obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 564bcd04d8..5933046064 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -87,7 +87,7 @@ /obj/item/gun/examine(mob/user) ..() if(pin) - to_chat(user, "It has [pin] installed.") + to_chat(user, "It has \a [pin] installed.") else to_chat(user, "It doesn't have a firing pin installed, and won't fire.") diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 58ff061e9d..0b6a9f1de7 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -126,7 +126,7 @@ /obj/item/gun/ballistic/examine(mob/user) ..() - to_chat(user, "Has [get_ammo()] round\s remaining.") + to_chat(user, "It has [get_ammo()] round\s remaining.") /obj/item/gun/ballistic/proc/get_ammo(countchambered = 1) var/boolets = 0 //mature var names for mature people diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 96777a050a..c333cbd6f9 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -32,7 +32,7 @@ to_chat(user, "[get_remaining_mod_capacity()]% mod capacity remaining.") for(var/A in get_modkits()) var/obj/item/borg/upgrade/modkit/M = A - to_chat(user, "There is a [M.name] mod installed, using [M.cost]% capacity.") + to_chat(user, "There is \a [M] installed, using [M.cost]% capacity.") /obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/A, mob/user) if(istype(A, /obj/item/crowbar)) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 937326a60b..5a6116bf66 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -161,27 +161,42 @@ if(forcedodge) loc = target_turf return FALSE - var/permutation = A.bullet_act(src, def_zone) // searches for return value, could be deleted after run so check A isn't null + var/permutation = select_target(A,target_turf) // searches for return value, could be deleted after run so check A isn't null if(permutation == -1 || forcedodge)// the bullet passes through a dense object! loc = target_turf if(A) permutated.Add(A) return FALSE - else - if(A && A.density && !ismob(A) && !(A.flags_1 & ON_BORDER_1)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile. - var/list/mobs_list = list() - for(var/mob/living/L in target_turf) - mobs_list += L - if(mobs_list.len) - var/mob/living/picked_mob = pick(mobs_list) - if(!prehit(picked_mob)) - return FALSE - if(ismob(picked_mob.buckled)) - picked_mob = picked_mob.buckled - picked_mob.bullet_act(src, def_zone) qdel(src) return TRUE +/obj/item/projectile/proc/select_target(atom/A,target_turf) + if((A && A.density && !(A.flags_1 & ON_BORDER_1)) && (istype(A,/obj/machinery) || isturf(A))) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile. + var/list/mobs_list = list() + var/list/machine_list = list() + for(var/mob/living/L in target_turf) + mobs_list += L + for(var/obj/machinery/m in target_turf) + if(m.density) + machine_list += m + var/permutationbackup + if(isturf(A)) + permutationbackup = A.bullet_act(src, def_zone) // Just in case the turf can deflect bullets + if(mobs_list.len || machine_list.len) + var/atom/movable/selected_target + if(mobs_list.Find(original) || machine_list.Find(original)) + selected_target = original + else if(mobs_list.len) + selected_target = pick(mobs_list) + else + selected_target = pick(machine_list) + if(!prehit(selected_target)) + return FALSE + return selected_target.bullet_act(src, def_zone) + return permutationbackup + else + return A.bullet_act(src, def_zone) + /obj/item/projectile/proc/check_ricochet() if(prob(ricochet_chance)) return TRUE @@ -213,7 +228,7 @@ while(loc) if(paused) next_run = world.time - sleep(1) + stoplag(1) continue if((!( current ) || loc == current)) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index ec4a1f58f8..6acc9926c6 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -393,4 +393,4 @@ "cryoxadone", "ammonia", "ash", - "diethylamine") + "diethylamine") \ No newline at end of file diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 64f0eae564..64731319b6 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -159,14 +159,17 @@ return switch(action) if("eject_beaker") - eject_beaker() + if(beaker) + eject_beaker() . = TRUE if("empty_beaker") - beaker.reagents.clear_reagents() + if(beaker) + beaker.reagents.clear_reagents() . = TRUE if("empty_eject_beaker") - beaker.reagents.clear_reagents() - eject_beaker() + if(beaker) + beaker.reagents.clear_reagents() + eject_beaker() . = TRUE if("rename_disease") var/id = get_virus_id_by_index(text2num(params["index"])) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 311efd0140..a341121390 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -1,94 +1,99 @@ + +#define MILK_TO_BUTTER_COEFF 15 + /obj/machinery/reagentgrinder - name = "All-In-One Grinder" - desc = "From BlenderTech. Will It Blend? Let's test it out!" - icon = 'icons/obj/kitchen.dmi' - icon_state = "juicer1" - layer = BELOW_OBJ_LAYER - anchored = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 5 - active_power_usage = 100 - pass_flags = PASSTABLE - resistance_flags = ACID_PROOF - var/operating = FALSE - var/obj/item/reagent_containers/beaker = null - var/limit = 10 + name = "All-In-One Grinder" + desc = "From BlenderTech. Will It Blend? Let's test it out!" + icon = 'icons/obj/kitchen.dmi' + icon_state = "juicer1" + layer = BELOW_OBJ_LAYER + anchored = TRUE + use_power = IDLE_POWER_USE + idle_power_usage = 5 + active_power_usage = 100 + pass_flags = PASSTABLE + resistance_flags = ACID_PROOF + var/operating = FALSE + var/obj/item/reagent_containers/beaker = null + var/limit = 10 - var/static/list/blend_items = list( - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20), - /obj/item/stack/sheet/metal = list("iron" = 20), - /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20), - /obj/item/stack/sheet/mineral/wood = list("carbon" = 20), - /obj/item/stack/sheet/glass = list("silicon" = 20), - /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20), - /obj/item/ore/bluespace_crystal = list("bluespace" = 20), - /obj/item/grown/nettle/basic = list("sacid" = 0), - /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0), - /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), - //Blender Stuff - /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), - /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), - /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5), - //Grinder stuff, but only if dry - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/slime_extract = list(), - /obj/item/reagent_containers/pill = list(), - /obj/item/reagent_containers/food = list(), - /obj/item/reagent_containers/honeycomb = list(), - /obj/item/toy/crayon = list()) + var/static/list/blend_items = list( + //Sheets + /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20), + /obj/item/stack/sheet/metal = list("iron" = 20), + /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20), + /obj/item/stack/sheet/mineral/wood = list("carbon" = 20), + /obj/item/stack/sheet/glass = list("silicon" = 20), + /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), + /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), + /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), + /obj/item/stack/sheet/mineral/silver = list("silver" = 20), + /obj/item/stack/sheet/mineral/gold = list("gold" = 20), + /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20), + /obj/item/ore/bluespace_crystal = list("bluespace" = 20), + /obj/item/grown/nettle/basic = list("sacid" = 0), + /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0), + /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), + //Blender Stuff + /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), + /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), + /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), + /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5), + /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5), + /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), + /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), + /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), + /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5), + //Grinder stuff, but only if dry + /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), + /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), + /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), + /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), + //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! + /obj/item/slime_extract = list(), + /obj/item/reagent_containers/pill = list(), + /obj/item/reagent_containers/food = list(), + /obj/item/reagent_containers/honeycomb = list(), + /obj/item/toy/crayon = list()) - var/static/list/juice_items = list( - //Juicer Stuff - /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0), - /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0)) + var/static/list/juice_items = list( + //Juicer Stuff + /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), + /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0), + /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0), + /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), + /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), + /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0)) - var/static/list/dried_items = list( - //Grinder stuff, but only if dry, - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)) + var/static/list/dried_items = list( + //Grinder stuff, but only if dry, + /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), + /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), + /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), + /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)) - var/list/holdingitems = list() + var/list/holdingitems /obj/machinery/reagentgrinder/Initialize() . = ..() + holdingitems = list() beaker = new /obj/item/reagent_containers/glass/beaker/large(src) beaker.desc += " May contain blended dust. Don't breathe this in!" /obj/machinery/reagentgrinder/Destroy() QDEL_NULL(beaker) + drop_all_items() return ..() /obj/machinery/reagentgrinder/contents_explosion(severity, target) @@ -96,14 +101,22 @@ beaker.ex_act(severity, target) /obj/machinery/reagentgrinder/handle_atom_del(atom/A) - ..() + . = ..() if(A == beaker) beaker = null update_icon() updateUsrDialog() + if(holdingitems[A]) + holdingitems -= A + +/obj/machinery/reagentgrinder/proc/drop_all_items() + for(var/i in holdingitems) + var/atom/movable/AM = i + AM.forceMove(drop_location()) + holdingitems = list() /obj/machinery/reagentgrinder/deconstruct(disassembled = TRUE) - new /obj/item/stack/sheet/metal (loc, 3) + new /obj/item/stack/sheet/metal (drop_location(), 3) qdel(src) /obj/machinery/reagentgrinder/update_icon() @@ -113,380 +126,344 @@ icon_state = "juicer0" /obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) - if(default_unfasten_wrench(user, I)) - return + if(default_unfasten_wrench(user, I)) + return - if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) ) - if (!beaker) - if(!user.transferItemToLoc(I, src)) - return 1 - beaker = I - update_icon() - src.updateUsrDialog() - else - to_chat(user, "There's already a container inside [src].") - return 1 //no afterattack + if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) ) + if (!beaker) + if(!user.transferItemToLoc(I, src)) + to_chat(user, "[I] is stuck to your hand!") + return TRUE + beaker = I + update_icon() + updateUsrDialog() + else + to_chat(user, "There's already a container inside [src].") + return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry [G] first!") - return 1 + if(is_type_in_list(I, dried_items)) + if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) + var/obj/item/reagent_containers/food/snacks/grown/G = I + if(!G.dry) + to_chat(user, "You must dry [G] first!") + return TRUE - if(holdingitems && holdingitems.len >= limit) - to_chat(usr, "The machine cannot hold anymore items.") - return 1 + if(length(holdingitems) >= limit) + to_chat(user, "The machine cannot hold anymore items.") + return TRUE - //Fill machine with a bag! - if(istype(I, /obj/item/storage/bag)) - var/obj/item/storage/bag/B = I - for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents) - B.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill - to_chat(user, "You fill [src] to the brim.") - break + //Fill machine with a bag! + if(istype(I, /obj/item/storage/bag)) + var/obj/item/storage/bag/B = I + for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents) + B.remove_from_storage(G, src) + holdingitems[G] = TRUE + if(length(holdingitems) >= limit) //Sanity checking so the blender doesn't overfill + to_chat(user, "You fill [src] to the brim.") + break - if(!I.contents.len) - to_chat(user, "You empty [I] into [src].") + if(!I.contents.len) + to_chat(user, "You empty [I] into [src].") - src.updateUsrDialog() - return 1 + updateUsrDialog() + return TRUE - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) - if(user.a_intent == INTENT_HARM) - return ..() - else - to_chat(user, "Cannot refine into a reagent!") - return 1 + if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(user.a_intent == INTENT_HARM) + return ..() + else + to_chat(user, "Cannot refine into a reagent!") + return TRUE - if(user.transferItemToLoc(I, src)) - holdingitems += I - src.updateUsrDialog() - return 0 + if(user.transferItemToLoc(I, src)) + holdingitems[I] = TRUE + updateUsrDialog() + return FALSE /obj/machinery/reagentgrinder/attack_paw(mob/user) - return src.attack_hand(user) + return attack_hand(user) /obj/machinery/reagentgrinder/attack_ai(mob/user) - return 0 + return FALSE /obj/machinery/reagentgrinder/attack_hand(mob/user) - user.set_machine(src) - interact(user) + user.set_machine(src) + interact(user) /obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu - var/is_chamber_empty = 0 - var/is_beaker_ready = 0 - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" + var/is_chamber_empty = FALSE + var/is_beaker_ready = FALSE + var/processing_chamber = "" + var/beaker_contents = "" + var/dat = "" - if(!operating) - for (var/obj/item/O in holdingitems) - processing_chamber += "\A [O.name]
" + if(!operating) + for (var/i in holdingitems) + var/obj/item/O = i + processing_chamber += "\A [O.name]
" - if (!processing_chamber) - is_chamber_empty = 1 - processing_chamber = "Nothing." - if (!beaker) - beaker_contents = "No beaker attached.
" - else - is_beaker_ready = 1 - beaker_contents = "The beaker contains:
" - var/anything = 0 - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = 1 - beaker_contents += "[R.volume] - [R.name]
" - if(!anything) - beaker_contents += "Nothing
" - - - dat = {" - Processing chamber contains:
- [processing_chamber]
- [beaker_contents]
- "} - if (is_beaker_ready) - if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
" - dat += "Juice the reagents

" - else if (beaker.reagents.total_volume) - dat += "Mix the reagents

" - if(holdingitems && holdingitems.len > 0) - dat += "Eject the reagents
" - if (beaker) - dat += "Detach the beaker
" + if (!processing_chamber) + is_chamber_empty = TRUE + processing_chamber = "Nothing." + if (!beaker) + beaker_contents = "No beaker attached.
" else - dat += "Please wait..." + is_beaker_ready = TRUE + beaker_contents = "The beaker contains:
" + var/anything = FALSE + for(var/datum/reagent/R in beaker.reagents.reagent_list) + anything = TRUE + beaker_contents += "[R.volume] - [R.name]
" + if(!anything) + beaker_contents += "Nothing
" - var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open(1) - return + dat = {" + Processing chamber contains:
+ [processing_chamber]
+ [beaker_contents]
+ "} + if (is_beaker_ready) + if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN))) + dat += "Grind the reagents
" + dat += "Juice the reagents

" + else if (beaker.reagents.total_volume) + dat += "Mix the reagents

" + if(length(holdingitems)) + dat += "Eject the reagents
" + if(beaker) + dat += "Detach the beaker
" + else + dat += "Please wait..." + + var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open(1) + return /obj/machinery/reagentgrinder/Topic(href, href_list) if(..()) return - usr.set_machine(src) + var/mob/user = usr + if(!user.canUseTopic(src)) + return + if(stat & (NOPOWER|BROKEN)) + return + user.set_machine(src) if(operating) updateUsrDialog() return switch(href_list["action"]) if ("grind") - grind() + grind(user) if("juice") - juice() + juice(user) if("mix") - mix() + mix(user) if("eject") - eject() - if ("detach") - detach() + eject(user) + if("detach") + detach(user) + updateUsrDialog() -/obj/machinery/reagentgrinder/proc/detach() +/obj/machinery/reagentgrinder/proc/detach(mob/user) + if(!beaker) + return + beaker.forceMove(drop_location()) + beaker = null + update_icon() + updateUsrDialog() - if (usr.stat != 0) - return - if (!beaker) - return - beaker.loc = src.loc - beaker = null - update_icon() - updateUsrDialog() +/obj/machinery/reagentgrinder/proc/eject(mob/user) + if(!length(holdingitems)) + return + for(var/i in holdingitems) + var/obj/item/O = i + O.forceMove(drop_location()) + holdingitems -= O + updateUsrDialog() -/obj/machinery/reagentgrinder/proc/eject() +/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O) + return blend_items[O.type] - if (usr.stat != 0) - return - if (holdingitems && holdingitems.len == 0) - return - - for(var/obj/item/O in holdingitems) - O.loc = src.loc - holdingitems -= O - holdingitems = list() - updateUsrDialog() - -/obj/machinery/reagentgrinder/proc/is_allowed(obj/item/reagent_containers/O) - for (var/i in blend_items) - if(istype(O, i)) - return 1 - return 0 - -/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/O) - for (var/i in blend_items) - if (istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(obj/item/reagent_containers/food/snacks/O) - for(var/i in blend_items) - if(istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(obj/item/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] +/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O) + for(var/i in juice_items) + if(istype(O, i)) + return juice_items[i] /obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(O.seed.potency) + if (!istype(O) || !O.seed) + return 5 + else if (O.seed.potency == -1) + return 5 + else + return round(O.seed.potency) /obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(5*sqrt(O.seed.potency)) + if (!istype(O) || !O.seed) + return 5 + else if (O.seed.potency == -1) + return 5 + else + return round(5*sqrt(O.seed.potency)) /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) - holdingitems -= O - qdel(O) + holdingitems -= O + qdel(O) /obj/machinery/reagentgrinder/proc/juice() - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking - operating = TRUE - updateUsrDialog() - spawn(50) - pixel_x = initial(pixel_x) //return to its spot after shaking - operating = FALSE - updateUsrDialog() + power_change() + if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + return + operate_for(50, juicing = TRUE) - //Snacks - for (var/obj/item/reagent_containers/food/snacks/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break + //Snacks + for(var/obj/item/i in holdingitems) + var/obj/item/I = i + if(istype(I, /obj/item/reagent_containers/food/snacks)) + var/obj/item/reagent_containers/food/snacks/O = I + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/list/allowed = get_allowed_juice_by_obj(O) + if(isnull(allowed)) + break + for(var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = get_juice_amount(O) + beaker.reagents.add_reagent(r_id, min(amount, space)) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + remove_object(O) - var/allowed = get_allowed_juice_by_id(O) - if(isnull(allowed)) - break +/obj/machinery/reagentgrinder/proc/shake_for(duration) + var/offset = prob(50) ? -2 : 2 + var/old_pixel_x = pixel_x + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = -1) //start shaking + addtimer(CALLBACK(src, .proc/stop_shaking, old_pixel_x), duration) - for (var/r_id in allowed) +/obj/machinery/reagentgrinder/proc/stop_shaking(old_px) + animate(src) + pixel_x = old_px - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) +/obj/machinery/reagentgrinder/proc/operate_for(time, silent = FALSE, juicing = FALSE) + shake_for(time) + updateUsrDialog() + operating = TRUE + if(!silent) + if(!juicing) + playsound(src, 'sound/machines/blender.ogg', 50, 1) + else + playsound(src, 'sound/machines/juicer.ogg', 20, 1) + addtimer(CALLBACK(src, .proc/stop_operating), time) - beaker.reagents.add_reagent(r_id, min(amount, space)) - - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - remove_object(O) +/obj/machinery/reagentgrinder/proc/stop_operating() + operating = FALSE + updateUsrDialog() /obj/machinery/reagentgrinder/proc/grind() - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking - operating = TRUE - updateUsrDialog() - spawn(60) - pixel_x = initial(pixel_x) //return to its spot after shaking - operating = FALSE - updateUsrDialog() - - //Snacks and Plants - for (var/obj/item/reagent_containers/food/snacks/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - var/allowed = get_allowed_snack_by_id(O) - if(isnull(allowed)) - break - - for (var/r_id in allowed) - - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) - if(amount == 0) - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - if(O.reagents.reagent_list.len == 0) - remove_object(O) - - //Sheets - for (var/obj/item/stack/sheet/O in holdingitems) - var/allowed = get_allowed_by_id(O) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - for(var/i = 1; i <= round(O.amount, 1); i++) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (space < amount) - break - if (i == round(O.amount, 1)) - remove_object(O) - break - //Plants - for (var/obj/item/grown/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if (amount == 0) - if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - - //Slime Extractis - for (var/obj/item/slime_extract/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break + power_change() + if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + operate_for(60) + for(var/i in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/obj/item/I = i + //Snacks + if(istype(I, /obj/item/reagent_containers/food/snacks)) + var/obj/item/reagent_containers/food/snacks/O = I + var/list/allowed = get_allowed_by_obj(O) + if(isnull(allowed)) + continue + for(var/r_id in allowed) var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if (O.reagents != null) - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, min(amount, space)) - if (O.Uses > 0) - beaker.reagents.add_reagent("slimejelly",min(20, space)) + var/amount = allowed[r_id] + if(amount <= 0) + if(amount == 0) + if (O.reagents != null && O.reagents.has_reagent("nutriment")) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) + O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + else + if (O.reagents != null && O.reagents.has_reagent("nutriment")) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) + O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + else + O.reagents.trans_id_to(beaker, r_id, min(amount, space)) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + if(O.reagents.reagent_list.len == 0) + remove_object(O) + //Sheets + else if(istype(I, /obj/item/stack/sheet)) + var/obj/item/stack/sheet/O = I + var/list/allowed = get_allowed_by_obj(O) + for(var/t in 1 to round(O.amount, 1)) + for(var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + beaker.reagents.add_reagent(r_id,min(amount, space)) + if (space < amount) + break + if(t == round(O.amount, 1)) + remove_object(O) + break + //Plants + else if(istype(I, /obj/item/grown)) + var/obj/item/grown/O = I + var/list/allowed = get_allowed_by_obj(O) + for (var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + if (amount == 0) + if (O.reagents != null && O.reagents.has_reagent(r_id)) + beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) + else + beaker.reagents.add_reagent(r_id,min(amount, space)) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + remove_object(O) + else if(istype(I, /obj/item/slime_extract)) + var/obj/item/slime_extract/O = I + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + if (O.reagents != null) + var/amount = O.reagents.total_volume + O.reagents.trans_to(beaker, min(amount, space)) + if (O.Uses > 0) + beaker.reagents.add_reagent("slimejelly",min(20, space)) + remove_object(O) + else if(istype(I, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/O = I + var/amount = O.reagents.total_volume + O.reagents.trans_to(beaker, amount) + if(!O.reagents.total_volume) + remove_object(O) + else if(istype(I, /obj/item/toy/crayon)) + var/obj/item/toy/crayon/O = I + for (var/r_id in O.reagent_contents) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + if(!space) + break + beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) remove_object(O) - //Everything else - Transfers reagents from it into beaker - for (var/obj/item/reagent_containers/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) - - for (var/obj/item/toy/crayon/O in holdingitems) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - for (var/r_id in O.reagent_contents) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if (space == 0) - break - beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) - remove_object(O) - -/obj/machinery/reagentgrinder/proc/mix() - - //For butter and other things that would change upon shaking or mixing - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if (!beaker) - return - playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking - operating = TRUE - updateUsrDialog() - addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50) +/obj/machinery/reagentgrinder/proc/mix(mob/user) + //For butter and other things that would change upon shaking or mixing + power_change() + if(!beaker) + return + operate_for(50, juicing = TRUE) + addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50) /obj/machinery/reagentgrinder/proc/mix_complete() - pixel_x = initial(pixel_x) //return to its spot after shaking - operating = FALSE - updateUsrDialog() - if (beaker.reagents.total_volume) - //Recipe to make Butter - while(beaker.reagents.get_reagent_amount("milk") >= 15) - beaker.reagents.remove_reagent("milk", 15) - new /obj/item/reagent_containers/food/snacks/butter(src.loc) - //Recipe to make Mayonnaise - if (beaker.reagents.has_reagent("eggyolk")) - var/amount = beaker.reagents.get_reagent_amount("eggyolk") - beaker.reagents.remove_reagent("eggyolk", amount) - beaker.reagents.add_reagent("mayonnaise", amount) + if(beaker && beaker.reagents.total_volume) + //Recipe to make Butter + var/butter_amt = Floor(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF) + beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt) + for(var/i in 1 to butter_amt) + new /obj/item/reagent_containers/food/snacks/butter(drop_location()) + //Recipe to make Mayonnaise + if (beaker.reagents.has_reagent("eggyolk")) + var/amount = beaker.reagents.get_reagent_amount("eggyolk") + beaker.reagents.remove_reagent("eggyolk", amount) + beaker.reagents.add_reagent("mayonnaise", amount) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm new file mode 100644 index 0000000000..381487450c --- /dev/null +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -0,0 +1,113 @@ +/obj/machinery/smoke_machine + name = "Smoke Machine" + icon = 'icons/obj/chemical.dmi' + icon_state = "smoke0" + density = TRUE + anchored = TRUE + circuit = /obj/item/circuitboard/machine/smoke_machine + var/efficiency = 10 + var/on = FALSE + var/cooldown = 0 + var/screen = "home" + var/useramount = 30 // Last used amount + var/volume = 1000 + var/setting = 3 + var/list/possible_settings = list(3,6,9,12,15) + +/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting = 3, efficiency = 10, loc) + amount = setting + carry.copy_to(chemholder, 20) + carry.remove_any(setting * 16 / efficiency) + location = loc + +/obj/machinery/smoke_machine/Initialize() + . = ..() + create_reagents(volume) + +/obj/machinery/smoke_machine/update_icon() + if((!is_operational()) || (!on) || (reagents.total_volume == 0)) + icon_state = "smoke0" + else + icon_state = "smoke1" + . = ..() + +/obj/machinery/smoke_machine/RefreshParts() + efficiency = 6 + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + efficiency += B.rating + for(var/obj/item/stock_parts/capacitor/C in component_parts) + efficiency += C.rating + for(var/obj/item/stock_parts/manipulator/M in component_parts) + efficiency += M.rating + +/obj/machinery/smoke_machine/process() + ..() + update_icon() + if(!is_operational()) + return + if(reagents.total_volume == 0) + on = FALSE + return + var/turf/T = get_turf(src) + var/smoke_test = locate(/obj/effect/particle_effect/smoke) in T + if(on && !smoke_test) + var/datum/effect_system/smoke_spread/chem/smoke_machine/smoke = new() + smoke.set_up(reagents, setting, efficiency, T) + smoke.start() + +/obj/machinery/smoke_machine/attackby(obj/item/I, mob/user, params) + add_fingerprint(user) + if(istype(I, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/RC = I + var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this) + if(units) + to_chat(user, "You transfer [units] units of the solution to [src].") + add_logs(usr, src, "has added [english_list(RC.reagents.reagent_list)] to [src]") + return + if(default_unfasten_wrench(user, I)) + return + return ..() + +/obj/machinery/smoke_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "smoke_machine", name, 450, 350, master_ui, state) + ui.open() + +/obj/machinery/smoke_machine/ui_data(mob/user) + var/data = list() + var/TankContents[0] + var/TankCurrentVolume = 0 + for(var/datum/reagent/R in reagents.reagent_list) + TankContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list... + TankCurrentVolume += R.volume + data["TankContents"] = TankContents + data["isTankLoaded"] = reagents.total_volume ? TRUE : FALSE + data["TankCurrentVolume"] = reagents.total_volume ? reagents.total_volume : null + data["TankMaxVolume"] = reagents.maximum_volume + data["active"] = on + data["setting"] = setting + data["screen"] = screen + return data + +/obj/machinery/smoke_machine/ui_act(action, params) + if(..() || !anchored) + return + switch(action) + if("purge") + reagents.clear_reagents() + . = TRUE + if("setting") + var/amount = text2num(params["amount"]) + if (locate(amount) in possible_settings) + setting = amount + . = TRUE + if("power") + on = !on + if(on) + log_admin("[key_name(usr)] activated a smoke machine that contains [english_list(reagents.reagent_list)] at [COORD(src)].") + add_logs(usr, src, "has activated [src] which contains [english_list(reagents.reagent_list)].") + if("goScreen") + screen = params["screen"] + . = TRUE diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 01d50fb606..06f77361c3 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -61,7 +61,7 @@ M.jitteriness = 0 for(var/thing in M.viruses) var/datum/disease/D = thing - if(D.severity == NONTHREAT) + if(D.severity == VIRUS_SEVERITY_POSITIVE) continue D.cure() ..() diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 6e02cc5696..8ce843e26b 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -16,11 +16,11 @@ for(var/thing in data["viruses"]) var/datum/disease/D = thing - if((D.spread_flags & SPECIAL) || (D.spread_flags & NON_CONTAGIOUS)) + if((D.spread_flags & VIRUS_SPREAD_SPECIAL) || (D.spread_flags & VIRUS_SPREAD_NON_CONTAGIOUS)) continue - if(method == TOUCH || method == VAPOR) - M.ContractDisease(D) + if((method == TOUCH || method == VAPOR) && (D.spread_flags & VIRUS_SPREAD_CONTACT_FLUIDS)) + M.ContactContractDisease(D) else //ingest, patch or inject M.ForceContractDisease(D) @@ -1058,7 +1058,7 @@ /datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) - M.ContractDisease(new /datum/disease/transformation/xeno(0)) + M.ForceContractDisease(new /datum/disease/transformation/xeno(0)) /datum/reagent/fungalspores name = "Tubercle bacillus Cosmosis microbes" diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 67d15f7240..1f4dd47734 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -31,7 +31,7 @@ /obj/structure/reagent_dispensers/examine(mob/user) ..() if(reagents.total_volume) - to_chat(user, "It has [reagents.total_volume] units left.") + to_chat(user, "It has [reagents.total_volume] unit\s left.") else to_chat(user, "It's empty.") @@ -146,7 +146,12 @@ /obj/structure/reagent_dispensers/water_cooler/examine(mob/user) ..() - to_chat(user, "There are [paper_cups ? paper_cups : "no"] paper cups left.") + if (paper_cups > 1) + to_chat(user, "There are [paper_cups] paper cups left.") + else if (paper_cups == 1) + to_chat(user, "There is one paper cup left.") + else + to_chat(user, "There are no paper cups left.") /obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user) if(!paper_cups) diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm index 2fe36972e0..9b57c41826 100644 --- a/code/modules/recycling/disposal-structures.dm +++ b/code/modules/recycling/disposal-structures.dm @@ -422,7 +422,7 @@ if(sortTypes.len>0) to_chat(user, "It is tagged with the following tags:") for(var/t in sortTypes) - to_chat(user, GLOB.TAGGERLOCATIONS[t]) + to_chat(user, "\t[GLOB.TAGGERLOCATIONS[t]].") else to_chat(user, "It has no sorting tags set.") diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index f9a2c0d63c..ebeb869d9c 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -28,8 +28,9 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). ) /obj/machinery/r_n_d/circuit_imprinter/Initialize() - AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) + materials.precise_insertion = TRUE create_reagents(0) return ..() diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index bb2887e2a1..2fe94933d7 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -154,6 +154,14 @@ build_path = /obj/item/circuitboard/machine/chem_heater category = list ("Medical Machinery") +/datum/design/board/smoke_machine + name = "Machine Design (Smoke Machine)" + desc = "The circuit board for a smoke machine." + id = "smoke_machine" + req_tech = list("materials" = 4, "biotech" = 3, "engineering" = 3) + build_path = /obj/item/circuitboard/machine/smoke_machine + category = list ("Medical Machinery") + /datum/design/board/clonecontrol name = "Computer Design (Cloning Machine Console)" desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console." diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 88c902a70d..9df4946ed2 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -33,9 +33,10 @@ Note: Must be placed west/left of and R&D console to function. /obj/machinery/r_n_d/protolathe/Initialize() create_reagents(0) - AddComponent(/datum/component/material_container, + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready)) + materials.precise_insertion = TRUE return ..() /obj/machinery/r_n_d/protolathe/RefreshParts() diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index ebc684ee15..ad21c9e6ba 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -160,15 +160,11 @@ All ShuttleMove procs go here /obj/machinery/camera/beforeShuttleMove(turf/newT, rotation, move_mode) . = ..() GLOB.cameranet.removeCamera(src) - GLOB.cameranet.updateChunk() . |= MOVE_CONTENTS /obj/machinery/camera/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() - if(can_use()) - GLOB.cameranet.addCamera(src) - var/datum/camerachunk/chunk = GLOB.cameranet.getCameraChunk(x, y, z) - chunk.hasChanged(TRUE) + GLOB.cameranet.addCamera(src) /obj/machinery/telecomms/afterShuttleMove(list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir) . = ..() diff --git a/code/modules/spells/spell_types/touch_attacks.dm b/code/modules/spells/spell_types/touch_attacks.dm index 06a699e54f..46563da53d 100644 --- a/code/modules/spells/spell_types/touch_attacks.dm +++ b/code/modules/spells/spell_types/touch_attacks.dm @@ -21,7 +21,7 @@ return 0 while(attached_hand) //hibernate untill the spell is actually used charge_counter = 0 - sleep(1) + stoplag(1) /obj/effect/proc_holder/spell/targeted/touch/proc/ChargeHand(mob/living/carbon/user) attached_hand = new hand_path(src) diff --git a/html/changelogs/AutoChangeLog-pr-3248.yml b/html/changelogs/AutoChangeLog-pr-3248.yml new file mode 100644 index 0000000000..26b6c965e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3248.yml @@ -0,0 +1,9 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Blood and vomit pools can now spread the diseases of the mob that made them! Cover your feet properly to avoid infection." + - rscadd: "Virus severity now changes the color of the disease HUD icon, scaling from green to red to flashing black-red." + - tweak: "Contact-based diseases no longer spread by simply standing near other people; it requires interaction like touching or attacking. Bumping against people/swapping with help intent still counts as touching." + - tweak: "Advanced viruses now have another infection type, \"Fluids\"; it's between blood and skin contact, and will only be transmitted through fluid contact." + - rscdel: "Two \"hidden\" infection types have been removed. Overall this means that making a virus airborne is a little bit easier." + - bugfix: "Species who cannot breathe can no longer be infected by breathing." diff --git a/html/changelogs/AutoChangeLog-pr-3264.yml b/html/changelogs/AutoChangeLog-pr-3264.yml new file mode 100644 index 0000000000..15269a81a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3264.yml @@ -0,0 +1,4 @@ +author: "Neri/Kevak" +delete-after: True +changes: + - bugfix: "Fixes shockcollar pocketstick bug." diff --git a/html/changelogs/AutoChangeLog-pr-3265.yml b/html/changelogs/AutoChangeLog-pr-3265.yml new file mode 100644 index 0000000000..bd6ef58236 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3265.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - tweak: "The asteroid escape shuttle has no stabilizers and throws you around when it moves" diff --git a/html/changelogs/AutoChangeLog-pr-3266.yml b/html/changelogs/AutoChangeLog-pr-3266.yml new file mode 100644 index 0000000000..c3f826a07a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3266.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - spellcheck: "Grammar when examining objects has been improved." diff --git a/html/changelogs/AutoChangeLog-pr-3268.yml b/html/changelogs/AutoChangeLog-pr-3268.yml new file mode 100644 index 0000000000..791d6cb443 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3268.yml @@ -0,0 +1,4 @@ +author: "Armhulen" +delete-after: True +changes: + - bugfix: "Clockwork golems no longer slip and slide on glass!" diff --git a/html/changelogs/AutoChangeLog-pr-3269.yml b/html/changelogs/AutoChangeLog-pr-3269.yml new file mode 100644 index 0000000000..cd96ba9112 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3269.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - bugfix: "2 Years later and cameras work on shuttles now, probably." diff --git a/html/changelogs/AutoChangeLog-pr-3270.yml b/html/changelogs/AutoChangeLog-pr-3270.yml new file mode 100644 index 0000000000..c3c989d438 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3270.yml @@ -0,0 +1,4 @@ +author: "More Robust Than You" +delete-after: True +changes: + - bugfix: "Makes the santa event properly poll ghosts" diff --git a/html/changelogs/AutoChangeLog-pr-3277.yml b/html/changelogs/AutoChangeLog-pr-3277.yml new file mode 100644 index 0000000000..69451cf455 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3277.yml @@ -0,0 +1,4 @@ +author: "GLACoding" +delete-after: True +changes: + - bugfix: "Syndicate turrets and other machines in walls can now be hit by projectiles" diff --git a/html/changelogs/AutoChangeLog-pr-3283.yml b/html/changelogs/AutoChangeLog-pr-3283.yml new file mode 100644 index 0000000000..3ff6b2f72a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3283.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "Clock Cult mode will no longer end if all the cultists die. The round will not end until the Ark is destroyed or completed." diff --git a/html/changelogs/AutoChangeLog-pr-3284.yml b/html/changelogs/AutoChangeLog-pr-3284.yml new file mode 100644 index 0000000000..2b32e98e20 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3284.yml @@ -0,0 +1,4 @@ +author: "More Robust Than You" +delete-after: True +changes: + - bugfix: "Diseases will now cure if species is changed" diff --git a/html/changelogs/AutoChangeLog-pr-3287.yml b/html/changelogs/AutoChangeLog-pr-3287.yml new file mode 100644 index 0000000000..513ad987b3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3287.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - rscadd: "The Chemistry Smoke Machine! Chemist offices will have a board available should they choose to construct a smoke machine. The smoke machine will regularly produce smoke from whatever chemicals have been inserted into the machine. Designs for the circuitboard are also available at RND." diff --git a/html/changelogs/AutoChangeLog-pr-3296.yml b/html/changelogs/AutoChangeLog-pr-3296.yml new file mode 100644 index 0000000000..05adafd5f0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3296.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixed trying to clear beaker in pandemic when the beaker is already removed causing a runtime." diff --git a/html/changelogs/AutoChangeLog-pr-3297.yml b/html/changelogs/AutoChangeLog-pr-3297.yml new file mode 100644 index 0000000000..28b1e698b3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3297.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "The Ark of the Clockwork Justiciar is now registered as a hostile environment." diff --git a/html/changelogs/AutoChangeLog-pr-3300.yml b/html/changelogs/AutoChangeLog-pr-3300.yml new file mode 100644 index 0000000000..2a8f289744 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3300.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - rscadd: "*slap" diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi index 5850b22d47..ddfc782467 100644 Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ diff --git a/tgstation.dme b/tgstation.dme index ab5b26b120..c63b893b69 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -37,6 +37,7 @@ #include "code\__DEFINES\construction.dm" #include "code\__DEFINES\contracts.dm" #include "code\__DEFINES\cult.dm" +#include "code\__DEFINES\diseases.dm" #include "code\__DEFINES\DNA.dm" #include "code\__DEFINES\events.dm" #include "code\__DEFINES\flags.dm" @@ -301,6 +302,7 @@ #include "code\datums\antagonists\ninja.dm" #include "code\datums\components\_component.dm" #include "code\datums\components\archaeology.dm" +#include "code\datums\components\infective.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\paintable.dm" #include "code\datums\components\slippery.dm" @@ -456,7 +458,6 @@ #include "code\game\gamemodes\changeling\powers\digitalcamo.dm" #include "code\game\gamemodes\changeling\powers\fakedeath.dm" #include "code\game\gamemodes\changeling\powers\fleshmend.dm" -#include "code\game\gamemodes\changeling\powers\glands.dm" #include "code\game\gamemodes\changeling\powers\headcrab.dm" #include "code\game\gamemodes\changeling\powers\hivemind.dm" #include "code\game\gamemodes\changeling\powers\humanform.dm" @@ -1273,6 +1274,7 @@ #include "code\modules\clothing\masks\vg_masks.dm" #include "code\modules\clothing\neck\neck.dm" #include "code\modules\clothing\outfits\ert.dm" +#include "code\modules\clothing\outfits\event.dm" #include "code\modules\clothing\outfits\standard.dm" #include "code\modules\clothing\shoes\bananashoes.dm" #include "code\modules\clothing\shoes\colour.dm" @@ -2072,6 +2074,7 @@ #include "code\modules\reagents\chemistry\machinery\chem_master.dm" #include "code\modules\reagents\chemistry\machinery\pandemic.dm" #include "code\modules\reagents\chemistry\machinery\reagentgrinder.dm" +#include "code\modules\reagents\chemistry\machinery\smoke_machine.dm" #include "code\modules\reagents\chemistry\reagents\alcohol_reagents.dm" #include "code\modules\reagents\chemistry\reagents\blob_reagents.dm" #include "code\modules\reagents\chemistry\reagents\drink_reagents.dm" diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 8168ac8eff..43cc3133c8 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,16 +1,17 @@ -require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(i)return i(o,!0);var p=Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o2?p[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-u,o-s),f=1;for(s>u&&u+l>s&&(f=-1,u+=l-1,s+=l-1);l-- >0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},{76:76,79:79,80:80}],6:[function(t,e,n){"use strict";var a=t(80),r=t(76),i=t(79);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,u=r(s>1?o[1]:void 0,n),p=s>2?o[2]:void 0,c=void 0===p?n:r(p,n);c>u;)e[u++]=t;return e}},{76:76,79:79,80:80}],7:[function(t,e,n){var a=t(78),r=t(79),i=t(76);e.exports=function(t){return function(e,n,o){var s,u=a(e),p=r(u.length),c=i(o,p);if(t&&n!=n){for(;p>c;)if(s=u[c++],s!=s)return!0}else for(;p>c;c++)if((t||c in u)&&u[c]===n)return t||c;return!t&&-1}}},{76:76,78:78,79:79}],8:[function(t,e,n){var a=t(17),r=t(34),i=t(80),o=t(79),s=t(9);e.exports=function(t){var e=1==t,n=2==t,u=3==t,p=4==t,c=6==t,l=5==t||c;return function(f,d,h){for(var m,v,g=i(f),b=r(g),y=a(d,h,3),x=o(b.length),_=0,w=e?s(f,x):n?s(f,0):void 0;x>_;_++)if((l||_ in b)&&(m=b[_],v=y(m,_,g),t))if(e)w[_]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return _;case 2:w.push(m)}else if(p)return!1;return c?-1:u||p?p:w}}},{17:17,34:34,79:79,80:80,9:9}],9:[function(t,e,n){var a=t(38),r=t(36),i=t(83)("species");e.exports=function(t,e){var n;return r(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!r(n.prototype)||(n=void 0),a(n)&&(n=n[i],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{36:36,38:38,83:83}],10:[function(t,e,n){var a=t(11),r=t(83)("toStringTag"),i="Arguments"==a(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[r])?n:i?a(e):"Object"==(o=a(e))&&"function"==typeof e.callee?"Arguments":o}},{11:11,83:83}],11:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],12:[function(t,e,n){"use strict";var a=t(46),r=t(31),i=t(60),o=t(17),s=t(69),u=t(18),p=t(27),c=t(42),l=t(44),f=t(82)("id"),d=t(30),h=t(38),m=t(65),v=t(19),g=Object.isExtensible||h,b=v?"_s":"size",y=0,x=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";r(t,f,++y)}return"O"+t[f]},_=function(t,e){var n,a=x(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,r){var c=t(function(t,i){s(t,c,e),t._i=a.create(null),t._f=void 0,t._l=void 0,t[b]=0,void 0!=i&&p(i,n,t[r],t)});return i(c.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[b]=0},"delete":function(t){var e=this,n=_(e,t);if(n){var a=n.n,r=n.p;delete e._i[n.i],n.r=!0,r&&(r.n=a),a&&(a.p=r),e._f==n&&(e._f=a),e._l==n&&(e._l=r),e[b]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!_(this,t)}}),v&&a.setDesc(c.prototype,"size",{get:function(){return u(this[b])}}),c},def:function(t,e,n){var a,r,i=_(t,e);return i?i.v=n:(t._l=i={i:r=x(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[b]++,"F"!==r&&(t._i[r]=i)),t},getEntry:_,setStrong:function(t,e,n){c(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?l(0,n.k):"values"==e?l(0,n.v):l(0,[n.k,n.v]):(t._t=void 0,l(1))},n?"entries":"values",!n,!0),m(e)}}},{17:17,18:18,19:19,27:27,30:30,31:31,38:38,42:42,44:44,46:46,60:60,65:65,69:69,82:82}],13:[function(t,e,n){var a=t(27),r=t(10);e.exports=function(t){return function(){if(r(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return a(this,!1,e.push,e),e}}},{10:10,27:27}],14:[function(t,e,n){"use strict";var a=t(31),r=t(60),i=t(4),o=t(38),s=t(69),u=t(27),p=t(8),c=t(30),l=t(82)("weak"),f=Object.isExtensible||o,d=p(5),h=p(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},b=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=b(this,t);return e?e[1]:void 0},has:function(t){return!!b(this,t)},set:function(t,e){var n=b(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,a){var i=t(function(t,r){s(t,i,e),t._i=m++,t._l=void 0,void 0!=r&&u(r,n,t[a],t)});return r(i.prototype,{"delete":function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i)&&delete t[l][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i):v(this).has(t):!1}}),i},def:function(t,e,n){return f(i(e))?(c(e,l)||a(e,l,{}),e[l][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:l}},{27:27,30:30,31:31,38:38,4:4,60:60,69:69,8:8,82:82}],15:[function(t,e,n){"use strict";var a=t(29),r=t(22),i=t(61),o=t(60),s=t(27),u=t(69),p=t(38),c=t(24),l=t(43),f=t(66);e.exports=function(t,e,n,d,h,m){var v=a[t],g=v,b=h?"set":"add",y=g&&g.prototype,x={},_=function(t){var e=y[t];i(y,t,"delete"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!p(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||y.forEach&&!c(function(){(new g).entries().next()}))){var w,k=new g,E=k[b](m?{}:-0,1)!=k,S=c(function(){k.has(1)}),C=l(function(t){new g(t)});C||(g=e(function(e,n){u(e,g,t);var a=new v;return void 0!=n&&s(n,h,a[b],a),a}),g.prototype=y,y.constructor=g),m||k.forEach(function(t,e){w=1/e===-(1/0)}),(S||w)&&(_("delete"),_("has"),h&&_("get")),(w||E)&&_(b),m&&y.clear&&delete y.clear}else g=d.getConstructor(e,t,h,b),o(g.prototype,n);return f(g,t),x[t]=g,r(r.G+r.W+r.F*(g!=v),x),m||d.setStrong(g,t,h),g}},{22:22,24:24,27:27,29:29,38:38,43:43,60:60,61:61,66:66,69:69}],16:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],17:[function(t,e,n){var a=t(2);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{2:2}],18:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],19:[function(t,e,n){e.exports=!t(24)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{24:24}],20:[function(t,e,n){var a=t(38),r=t(29).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{29:29,38:38}],21:[function(t,e,n){var a=t(46);e.exports=function(t){var e=a.getKeys(t),n=a.getSymbols;if(n)for(var r,i=n(t),o=a.isEnum,s=0;i.length>s;)o.call(t,r=i[s++])&&e.push(r);return e}},{46:46}],22:[function(t,e,n){var a=t(29),r=t(16),i=t(31),o=t(61),s=t(17),u="prototype",p=function(t,e,n){var c,l,f,d,h=t&p.F,m=t&p.G,v=t&p.S,g=t&p.P,b=t&p.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[u],x=m?r:r[e]||(r[e]={}),_=x[u]||(x[u]={});m&&(n=e);for(c in n)l=!h&&y&&c in y,f=(l?y:n)[c],d=b&&l?s(f,a):g&&"function"==typeof f?s(Function.call,f):f,y&&!l&&o(y,c,f),x[c]!=f&&i(x,c,d),g&&_[c]!=f&&(_[c]=f)};a.core=r,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,e.exports=p},{16:16,17:17,29:29,31:31,61:61}],23:[function(t,e,n){var a=t(83)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{83:83}],24:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],25:[function(t,e,n){"use strict";var a=t(31),r=t(61),i=t(24),o=t(18),s=t(83);e.exports=function(t,e,n){var u=s(t),p=""[t];i(function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,u,p)),a(RegExp.prototype,u,2==e?function(t,e){return p.call(t,this,e)}:function(t){return p.call(t,this)}))}},{18:18,24:24,31:31,61:61,83:83}],26:[function(t,e,n){"use strict";var a=t(4);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{4:4}],27:[function(t,e,n){var a=t(17),r=t(40),i=t(35),o=t(4),s=t(79),u=t(84);e.exports=function(t,e,n,p){var c,l,f,d=u(t),h=a(n,p,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(i(d))for(c=s(t.length);c>m;m++)e?h(o(l=t[m])[0],l[1]):h(t[m]);else for(f=d.call(t);!(l=f.next()).done;)r(f,h,l.value,e)}},{17:17,35:35,4:4,40:40,79:79,84:84}],28:[function(t,e,n){var a=t(78),r=t(46).getNames,i={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{46:46,78:78}],29:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],30:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],31:[function(t,e,n){var a=t(46),r=t(59);e.exports=t(19)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{19:19,46:46,59:59}],32:[function(t,e,n){e.exports=t(29).document&&document.documentElement},{29:29}],33:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],34:[function(t,e,n){var a=t(11);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{11:11}],35:[function(t,e,n){var a=t(45),r=t(83)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{45:45,83:83}],36:[function(t,e,n){var a=t(11);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{11:11}],37:[function(t,e,n){var a=t(38),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{38:38}],38:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],39:[function(t,e,n){var a=t(38),r=t(11),i=t(83)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{11:11,38:38,83:83}],40:[function(t,e,n){var a=t(4);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{4:4}],41:[function(t,e,n){"use strict";var a=t(46),r=t(59),i=t(66),o={};t(31)(o,t(83)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{31:31,46:46,59:59,66:66,83:83}],42:[function(t,e,n){"use strict";var a=t(48),r=t(22),i=t(61),o=t(31),s=t(30),u=t(45),p=t(41),c=t(66),l=t(46).getProto,f=t(83)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,b,y,x,_){p(n,e,b);var w,k,E=function(t){if(!d&&t in A)return A[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",C=y==v,P=!1,A=t.prototype,O=A[f]||A[h]||y&&A[y],T=O||E(y);if(O){var R=l(T.call(new t));c(R,S,!0),!a&&s(A,h)&&o(R,f,g),C&&O.name!==v&&(P=!0,T=function(){return O.call(this)})}if(a&&!_||!d&&!P&&A[f]||o(A,f,T),u[e]=T,u[S]=g,y)if(w={values:C?T:E(v),keys:x?T:E(m),entries:C?E("entries"):T},_)for(k in w)k in A||i(A,k,w[k]);else r(r.P+r.F*(d||P),e,w);return w}},{22:22,30:30,31:31,41:41,45:45,46:46,48:48,61:61,66:66,83:83}],43:[function(t,e,n){var a=t(83)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){return{done:n=!0}},i[a]=function(){return o},t(i)}catch(s){}return n}},{83:83}],44:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],45:[function(t,e,n){e.exports={}},{}],46:[function(t,e,n){var a=Object;e.exports={create:a.create,getProto:a.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:a.getOwnPropertyDescriptor,setDesc:a.defineProperty,setDescs:a.defineProperties,getKeys:a.keys,getNames:a.getOwnPropertyNames,getSymbols:a.getOwnPropertySymbols,each:[].forEach}},{}],47:[function(t,e,n){var a=t(46),r=t(78);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,u=0;s>u;)if(i[n=o[u++]]===e)return n}},{46:46,78:78}],48:[function(t,e,n){e.exports=!1},{}],49:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],50:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],51:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],52:[function(t,e,n){var a,r,i,o=t(29),s=t(75).set,u=o.MutationObserver||o.WebKitMutationObserver,p=o.process,c=o.Promise,l="process"==t(11)(p),f=function(){var t,e,n;for(l&&(t=p.domain)&&(p.domain=null,t.exit());a;)e=a.domain,n=a.fn,e&&e.enter(),n(),e&&e.exit(),a=a.next;r=void 0,t&&t.enter()};if(l)i=function(){p.nextTick(f)};else if(u){var d=1,h=document.createTextNode("");new u(f).observe(h,{characterData:!0}),i=function(){h.data=d=-d}}else i=c&&c.resolve?function(){c.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:l&&p.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{11:11,29:29,75:75}],53:[function(t,e,n){var a=t(46),r=t(80),i=t(34);e.exports=t(24)(function(){var t=Object.assign,e={},n={},a=Symbol(),r="abcdefghijklmnopqrst";return e[a]=7,r.split("").forEach(function(t){n[t]=t}),7!=t({},e)[a]||Object.keys(t({},n)).join("")!=r})?function(t,e){for(var n=r(t),o=arguments,s=o.length,u=1,p=a.getKeys,c=a.getSymbols,l=a.isEnum;s>u;)for(var f,d=i(o[u++]),h=c?p(d).concat(c(d)):p(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{24:24,34:34,46:46,80:80}],54:[function(t,e,n){var a=t(22),r=t(16),i=t(24);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{16:16,22:22,24:24}],55:[function(t,e,n){var a=t(46),r=t(78),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),u=s.length,p=0,c=[];u>p;)i.call(o,n=s[p++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{46:46,78:78}],56:[function(t,e,n){var a=t(46),r=t(4),i=t(29).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{29:29,4:4,46:46}],57:[function(t,e,n){"use strict";var a=t(58),r=t(33),i=t(2);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,u=!1;e>o;)(n[o]=arguments[o++])===s&&(u=!0);return function(){var a,i=this,o=arguments,p=o.length,c=0,l=0;if(!u&&!p)return r(t,n,i);if(a=n.slice(),u)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;p>l;)a.push(o[l++]);return r(t,a,i)}}},{2:2,33:33,58:58}],58:[function(t,e,n){e.exports=t(29)},{29:29}],59:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],60:[function(t,e,n){var a=t(61);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{61:61}],61:[function(t,e,n){var a=t(29),r=t(31),i=t(82)("src"),o="toString",s=Function[o],u=(""+s).split(o);t(16).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(i)||r(n,i,t[e]?""+t[e]:u.join(e+"")),n.hasOwnProperty("name")||r(n,"name",e)),t===a?t[e]=n:(o||delete t[e],r(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||s.call(this)})},{16:16,29:29,31:31,82:82}],62:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],63:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],64:[function(t,e,n){var a=t(46).getDesc,r=t(38),i=t(4),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,r){try{r=t(17)(Function.call,a(Object.prototype,"__proto__").set,2),r(e,[]),n=!(e instanceof Array)}catch(i){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},{17:17,38:38,4:4,46:46}],65:[function(t,e,n){"use strict";var a=t(29),r=t(46),i=t(19),o=t(83)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{19:19,29:29,46:46,83:83}],66:[function(t,e,n){var a=t(46).setDesc,r=t(30),i=t(83)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{30:30,46:46,83:83}],67:[function(t,e,n){var a=t(29),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{29:29}],68:[function(t,e,n){var a=t(4),r=t(2),i=t(83)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{2:2,4:4,83:83}],69:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],70:[function(t,e,n){var a=t(77),r=t(18);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",u=a(n),p=s.length;return 0>u||u>=p?t?"":void 0:(i=s.charCodeAt(u),55296>i||i>56319||u+1===p||(o=s.charCodeAt(u+1))<56320||o>57343?t?s.charAt(u):i:t?s.slice(u,u+2):(i-55296<<10)+(o-56320)+65536)}}},{18:18,77:77}],71:[function(t,e,n){var a=t(39),r=t(18);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{18:18,39:39}],72:[function(t,e,n){var a=t(79),r=t(73),i=t(18);e.exports=function(t,e,n,o){var s=i(t)+"",u=s.length,p=void 0===n?" ":n+"",c=a(e);if(u>=c)return s;""==p&&(p=" ");var l=c-u,f=r.call(p,Math.ceil(l/p.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{18:18,73:73,79:79}],73:[function(t,e,n){"use strict";var a=t(77),r=t(18);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{18:18,77:77}],74:[function(t,e,n){var a=t(22),r=t(18),i=t(24),o=" \n\x0B\f\r   ᠎              \u2028\u2029\ufeff",s="["+o+"]",u="​…",p=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e){var n={};n[t]=e(f),a(a.P+a.F*i(function(){return!!o[t]()||u[t]()!=u}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(p,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{18:18,22:22,24:24}],75:[function(t,e,n){var a,r,i,o=t(17),s=t(33),u=t(32),p=t(20),c=t(29),l=c.process,f=c.setImmediate,d=c.clearImmediate,h=c.MessageChannel,m=0,v={},g="onreadystatechange",b=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},y=function(t){b.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},a(m),m},d=function(t){delete v[t]},"process"==t(11)(l)?a=function(t){l.nextTick(o(b,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=y,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",y,!1)):a=g in p("script")?function(t){u.appendChild(p("script"))[g]=function(){u.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{11:11,17:17,20:20,29:29,32:32,33:33}],76:[function(t,e,n){var a=t(77),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{77:77}],77:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],78:[function(t,e,n){var a=t(34),r=t(18);e.exports=function(t){return a(r(t))}},{18:18,34:34}],79:[function(t,e,n){var a=t(77),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{77:77}],80:[function(t,e,n){var a=t(18);e.exports=function(t){return Object(a(t))}},{18:18}],81:[function(t,e,n){var a=t(38);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{38:38}],82:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],83:[function(t,e,n){var a=t(67)("wks"),r=t(82),i=t(29).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{29:29,67:67,82:82}],84:[function(t,e,n){var a=t(10),r=t(83)("iterator"),i=t(45);e.exports=t(16).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{10:10,16:16,45:45,83:83}],85:[function(t,e,n){"use strict";var a,r=t(46),i=t(22),o=t(19),s=t(59),u=t(32),p=t(20),c=t(30),l=t(11),f=t(33),d=t(24),h=t(4),m=t(2),v=t(38),g=t(80),b=t(78),y=t(77),x=t(76),_=t(79),w=t(34),k=t(82)("__proto__"),E=t(8),S=t(7)(!1),C=Object.prototype,P=Array.prototype,A=P.slice,O=P.join,T=r.setDesc,R=r.getDesc,j=r.setDescs,M={};o||(a=!d(function(){return 7!=T(p("div"),"a",{get:function(){return 7}}).a}),r.setDesc=function(t,e,n){if(a)try{return T(t,e,n)}catch(r){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},r.getDesc=function(t,e){if(a)try{return R(t,e)}catch(n){}return c(t,e)?s(!C.propertyIsEnumerable.call(t,e),t[e]):void 0},r.setDescs=j=function(t,e){h(t);for(var n,a=r.getKeys(e),i=a.length,o=0;i>o;)r.setDesc(t,n=a[o++],e[n]);return t}),i(i.S+i.F*!o,"Object",{getOwnPropertyDescriptor:r.getDesc,defineProperty:r.setDesc,defineProperties:j});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),D=L.concat("length","prototype"),N=L.length,F=function(){var t,e=p("iframe"),n=N,a=">";for(e.style.display="none",u.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("