diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 16214b58117a..022343e7dca0 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -8926,6 +8926,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, +/obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) "caH" = ( @@ -12277,6 +12278,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, /obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/structure/cable, /turf/open/floor/iron, /area/station/service/abandoned_gambling_den) "cRT" = ( @@ -13439,6 +13441,13 @@ /obj/machinery/duct, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"dgZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/closed/wall, +/area/station/service/library/printer) "dhk" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -17325,9 +17334,6 @@ /turf/open/floor/plating, /area/station/cargo/storage) "ehg" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/newscaster/directional/west, /obj/structure/table/wood, /obj/item/clipboard, @@ -18837,9 +18843,6 @@ /obj/structure/sign/painting/library_private{ pixel_y = -32 }, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/modular_computer/console/preset/curator{ dir = 1 }, @@ -31620,9 +31623,8 @@ /turf/open/floor/wood, /area/station/service/theater/abandoned) "hHF" = ( -/turf/open/floor/plating{ - icon_state = "foam_plating" - }, +/obj/structure/cable, +/turf/open/floor/glass/reinforced, /area/station/maintenance/department/science/xenobiology) "hHG" = ( /obj/machinery/telecomms/receiver/preset_left, @@ -37966,10 +37968,9 @@ /turf/open/floor/iron, /area/station/hallway/secondary/construction) "jiX" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, -/turf/open/floor/iron/dark, +/turf/open/floor/plating, /area/station/service/abandoned_gambling_den) "jjc" = ( /obj/structure/frame/computer{ @@ -44192,6 +44193,9 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "kHp" = ( @@ -46905,6 +46909,7 @@ /area/station/maintenance/department/eva/abandoned) "lqa" = ( /obj/machinery/light/small/red/directional/east, +/obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) "lql" = ( @@ -47972,6 +47977,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "lDV" = ( @@ -51463,6 +51471,7 @@ "mwA" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/oil, +/obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) "mwK" = ( @@ -52119,6 +52128,9 @@ /obj/effect/turf_decal/bot_white, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "mEx" = ( @@ -52185,6 +52197,7 @@ /area/station/security/warden) "mFq" = ( /obj/structure/sign/warning/secure_area/directional/north, +/obj/structure/cable, /turf/open/floor/glass/reinforced, /area/station/maintenance/department/science/xenobiology) "mFu" = ( @@ -56874,6 +56887,21 @@ pixel_y = 2; pixel_x = 9 }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, /turf/open/floor/iron/vaporwave, /area/station/service/library/printer) "nMN" = ( @@ -59137,6 +59165,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, /obj/effect/spawner/random/structure/steam_vent, +/obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) "opv" = ( @@ -66189,6 +66218,9 @@ dir = 8 }, /obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "qaF" = ( @@ -68364,9 +68396,6 @@ /turf/open/floor/iron/white, /area/station/medical/medbay) "qEj" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/machinery/light/small/directional/south, /obj/structure/table/wood, /obj/item/paper_bin{ @@ -75072,6 +75101,7 @@ "smj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/delivery, +/obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) "smo" = ( @@ -76145,6 +76175,7 @@ /obj/effect/decal/cleanable/xenoblood, /obj/structure/sign/warning/xeno_mining/directional/north, /obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) "sAm" = ( @@ -82902,9 +82933,6 @@ /area/station/commons/toilet/locker) "ufz" = ( /obj/machinery/firealarm/directional/south, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, /obj/effect/turf_decal/bot_white, /obj/structure/filingcabinet, /turf/open/floor/iron/dark, @@ -84964,6 +84992,7 @@ /turf/open/floor/iron/cafeteria, /area/station/service/cafeteria) "uGn" = ( +/obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) "uGx" = ( @@ -88806,6 +88835,7 @@ /area/station/maintenance/port) "vBO" = ( /obj/effect/decal/cleanable/dirt, +/obj/structure/cable, /turf/open/floor/plating{ icon_state = "foam_plating" }, @@ -92724,7 +92754,9 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, -/obj/structure/disposalpipe/segment, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, /turf/open/floor/iron/dark, /area/station/service/library/printer) "wwP" = ( @@ -93073,9 +93105,6 @@ /area/station/maintenance/starboard/aft) "wAZ" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /obj/structure/table/wood, /obj/item/taperecorder, /obj/item/camera, @@ -118460,7 +118489,7 @@ sfN sfN sfN nCi -vPU +hHF nCi nCi hCt @@ -118974,7 +119003,7 @@ sfN sfN sfN nCi -vPU +hHF nCi bET hVB @@ -119749,7 +119778,7 @@ jPZ oia nCi mwA -hHF +jDc guA nCi aaa @@ -120777,7 +120806,7 @@ uhb uhb mAt qCs -blc +jiX hLM jBx pxb @@ -121035,7 +121064,7 @@ fOp mAt ifk mMb -jiX +bNr blc rCc rCc @@ -146975,7 +147004,7 @@ dLH dfZ dfZ fcx -dfZ +dgZ dfZ khZ nHY diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index a5e759c6d785..0a7dc2984940 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -14435,6 +14435,21 @@ pixel_y = 2; pixel_x = 9 }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, /turf/open/floor/glass, /area/station/service/library) "ezJ" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index da5ab5939ef9..572db0791f1e 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -2747,6 +2747,21 @@ pixel_y = 2; pixel_x = 9 }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, /turf/open/floor/iron/vaporwave, /area/station/service/library) "aWl" = ( diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 4180df4b30a2..1b30f3328465 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -17238,6 +17238,9 @@ name = "CentCom Security" }, /obj/effect/mapping_helpers/airlock/access/any/admin/general, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 8 + }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) "Zc" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 40a172f77cc3..3a631e34457f 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -19551,12 +19551,6 @@ "ffa" = ( /obj/machinery/vending/wallmed/directional/west, /obj/effect/decal/cleanable/dirt, -/obj/item/toy/plush/pkplush{ - pixel_x = -3 - }, -/obj/item/toy/plush/rouny{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue/opposingcorners, /turf/open/floor/iron/white, /area/station/asteroid) @@ -23397,9 +23391,6 @@ "gvS" = ( /obj/effect/decal/cleanable/dirt, /obj/item/kirbyplants/random, -/obj/structure/sign/poster/contraband/ambrosia_vulgaris{ - pixel_x = 32 - }, /obj/machinery/light/warm{ dir = 4 }, @@ -32787,7 +32778,6 @@ /obj/structure/sign/poster/contraband/kudzu{ pixel_x = -32 }, -/obj/item/seeds/cocaleaf, /obj/machinery/light/warm, /turf/open/floor/iron/smooth, /area/station/maintenance/starboard/central) @@ -33469,9 +33459,14 @@ /area/station/maintenance/central/lesser) "jJt" = ( /obj/effect/decal/cleanable/dirt, -/obj/item/kirbyplants/random, -/obj/item/seeds/kudzu, -/turf/open/floor/iron/smooth, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/open/floor/catwalk_floor, /area/station/maintenance/starboard/central) "jJv" = ( /turf/open/floor/circuit, @@ -39810,17 +39805,15 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "lLW" = ( -/obj/item/toy/plush/moth{ - name = "Delivers-The-Pizza" - }, -/obj/item/clothing/head/soft/red{ - pixel_x = -4; - pixel_y = 9 - }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/blue/opposingcorners, -/turf/open/floor/iron/white, -/area/station/asteroid) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/starboard/central) "lMd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -44075,7 +44068,6 @@ /turf/open/floor/plating, /area/station/security/execution/transfer) "neX" = ( -/obj/item/kirbyplants/random, /obj/effect/decal/cleanable/dirt, /obj/machinery/light/directional/south, /obj/effect/turf_decal/tile/blue/fourcorners, @@ -49772,15 +49764,6 @@ }, /turf/open/floor/iron, /area/station/security/brig) -"pac" = ( -/obj/item/pizzabox/margherita{ - pixel_y = 27 - }, -/obj/structure/dresser, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/blue/opposingcorners, -/turf/open/floor/iron/white, -/area/station/asteroid) "pal" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -51804,7 +51787,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/engineering, +/obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/catwalk_floor, /area/station/maintenance/starboard/lesser) "pFw" = ( @@ -53975,14 +53958,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"qpR" = ( -/obj/structure/filingcabinet/chestdrawer{ - pixel_y = 2 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/blue/opposingcorners, -/turf/open/floor/iron/white, -/area/station/asteroid) "qpW" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -55990,9 +55965,9 @@ pixel_x = -3; pixel_y = 3 }, -/obj/item/clothing/under/syndicate, -/obj/item/clothing/under/syndicate, /obj/item/clothing/under/misc/syndicate_souvenir, +/obj/item/clothing/under/syndicate/tacticool, +/obj/item/clothing/under/syndicate/tacticool, /turf/open/floor/iron/grimy, /area/ruin/powered/clownplanet) "qVH" = ( @@ -60439,7 +60414,6 @@ /turf/open/floor/iron, /area/station/hallway/primary/tram/right) "srX" = ( -/obj/structure/closet/wardrobe/pjs, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/asteroid) @@ -66874,6 +66848,21 @@ pixel_y = 2; pixel_x = 9 }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, +/obj/item/device/cassette_tape/random{ + pixel_y = 8 + }, /turf/open/floor/iron/vaporwave, /area/station/service/library/upper) "uss" = ( @@ -124036,7 +124025,7 @@ mbJ aaa qxm hGg -jJt +iqy jys qxm aaa @@ -128136,7 +128125,7 @@ qxm bjI fsM fsM -fsM +lLW oys oys oys @@ -128393,7 +128382,7 @@ qxm qxm qxm qxm -qoO +jJt gDw gDw gDw @@ -177388,7 +177377,7 @@ jhd jhd jhd jhd -jhd +vXM jhd jhd jhd @@ -180848,7 +180837,7 @@ whz kSi whz ffa -qpR +rXK ugt kOL vrJ @@ -181618,8 +181607,8 @@ ebw whz qdj whz -lLW -pac +rXK +rXK ugt ugt ugt diff --git a/_maps/~monkestation/RandomBars/Icebox/cultbar_icebox.dmm b/_maps/~monkestation/RandomBars/Icebox/cultbar_icebox.dmm index b9afa7452553..1201953d3555 100644 --- a/_maps/~monkestation/RandomBars/Icebox/cultbar_icebox.dmm +++ b/_maps/~monkestation/RandomBars/Icebox/cultbar_icebox.dmm @@ -192,7 +192,6 @@ /area/station/service/theater) "iX" = ( /obj/effect/spawner/random/structure/musician/piano/random_piano, -/obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, /turf/open/floor/cult, /area/station/service/theater) @@ -401,7 +400,6 @@ "uL" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/cult, /area/station/service/bar/backroom) "vh" = ( diff --git a/_maps/~monkestation/RandomEngines/KiloStation/singularity.dmm b/_maps/~monkestation/RandomEngines/KiloStation/singularity.dmm index 0a79c673dcd7..ae0b4e69c26f 100644 --- a/_maps/~monkestation/RandomEngines/KiloStation/singularity.dmm +++ b/_maps/~monkestation/RandomEngines/KiloStation/singularity.dmm @@ -93,8 +93,10 @@ "is" = ( /obj/structure/cable, /obj/machinery/door/airlock/external, -/obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/structure/cable/layer1, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "kilo_singularity_airlock" + }, /turf/open/floor/iron, /area/station/engineering/supermatter/room) "iW" = ( @@ -106,11 +108,11 @@ "jc" = ( /obj/structure/cable, /obj/machinery/door/airlock/external, -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ - dir = 8 - }, /obj/structure/fans/tiny, /obj/structure/cable/layer1, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ + cycle_id = "kilo_singularity_airlock" + }, /turf/open/floor/iron, /area/station/engineering/supermatter/room) "jl" = ( @@ -396,7 +398,6 @@ dir = 1 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/supermatter/room) @@ -1004,7 +1005,7 @@ IJ rz Ib oK -Hs +oK pk Ii Ii @@ -1026,7 +1027,7 @@ En (12,1,1) = {" pa UA -oK +Hs NK pk lZ @@ -1121,9 +1122,9 @@ Ib oK NK pk -sz -sz -sz +oK +oK +oK Fj RL WZ diff --git a/code/__DEFINES/acid.dm b/code/__DEFINES/acid.dm index 37bf5f07ed54..7434fd94cd45 100644 --- a/code/__DEFINES/acid.dm +++ b/code/__DEFINES/acid.dm @@ -1,9 +1,9 @@ /// The acid power required to destroy most closed turfs. #define ACID_POWER_MELT_TURF 200 /// The maximum amount of damage (per second) acid can deal to an [/obj]. -#define OBJ_ACID_DAMAGE_MAX 300 +#define MOVABLE_ACID_DAMAGE_MAX 300 /// Maximum acid volume that can be applied to an [/obj]. -#define OBJ_ACID_VOLUME_MAX 300 +#define MOVABLE_ACID_VOLUME_MAX 300 /// Maximum acid volume that can be applied to a [/mob/living]. #define MOB_ACID_VOLUME_MAX 1000 /// Maximum acid volume that can be applied to a [/turf]. @@ -15,7 +15,5 @@ /// The scaling factor for the acid decay rate. #define ACID_DECAY_SCALING 1 -/// The default icon state for the acid overlay. Not to be confused with the error icon state. -#define ACID_OVERLAY_DEFAULT "default" /// The combined acid power and acid volume required to burn hands. #define ACID_LEVEL_HANDBURN 20 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 8456deca3363..7883f5ba9ae9 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -196,6 +196,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_GUN_NATURAL "gunnatural" /// Causes death-like unconsciousness #define TRAIT_DEATHCOMA "deathcoma" +/// The mob has the stasis effect. +/// Does nothing on its own, applied via status effect. +#define TRAIT_STASIS "in_stasis" /// Makes the owner appear as dead to most forms of medical examination #define TRAIT_FAKEDEATH "fakedeath" #define TRAIT_DISFIGURED "disfigured" @@ -256,8 +259,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_LIVERLESS_METABOLISM "liverless_metabolism" /// Humans with this trait cannot be turned into zombies #define TRAIT_NO_ZOMBIFY "no_zombify" -/// Humans with this trait cannot be affected by changeling transformation stings -#define TRAIT_NO_TRANSFORMATION_STING "no_transformation_sting" /// Carbons with this trait can't have their DNA copied by diseases nor changelings #define TRAIT_NO_DNA_COPY "no_dna_copy" /// Carbons with this trait can eat blood to regenerate their own blood volume, instead of injecting it diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index e8f8d96b9a41..6b6dca84f290 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -612,8 +612,6 @@ GLOBAL_LIST_EMPTY(species_list) #define ISADVANCEDTOOLUSER(mob) (HAS_TRAIT(mob, TRAIT_ADVANCEDTOOLUSER) && !HAS_TRAIT(mob, TRAIT_DISCOORDINATED_TOOL_USER)) -#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis) || mob.has_status_effect(/datum/status_effect/embryonic)) - /// Gets the client of the mob, allowing for mocking of the client. /// You only need to use this if you know you're going to be mocking clients somewhere else. #define GET_CLIENT(mob) (##mob.client || ##mob.mock_client) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 5b9d561afcae..4fb02a8bb3b6 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -439,6 +439,7 @@ Used by the AI doomsday and the self-destruct nuke. template.weight = (template.weight / 2) if(template.stock <= 0) template.spawned = TRUE + log_world("Loading random room template [template.name] ([template.type]) at [AREACOORD(R)]") template.stationinitload(get_turf(R), centered = template.centerspawner) SSmapping.random_room_spawners -= R qdel(R) @@ -459,6 +460,7 @@ Used by the AI doomsday and the self-destruct nuke. possible_engine_templates[engine_candidate] = engine_candidate.weight if(possible_engine_templates.len) var/datum/map_template/random_room/random_engines/template = pick_weight(possible_engine_templates) + log_world("Loading random engine template [template.name] ([template.type]) at [AREACOORD(engine_spawner)]") template.stationinitload(get_turf(engine_spawner), centered = template.centerspawner) SSmapping.random_engine_spawners -= engine_spawner qdel(engine_spawner) @@ -480,6 +482,7 @@ Used by the AI doomsday and the self-destruct nuke. possible_bar_templates[bar_candidate] = bar_candidate.weight if(possible_bar_templates.len) var/datum/map_template/random_room/random_bar/template = pick_weight(possible_bar_templates) + log_world("Loading random bar template [template.name] ([template.type]) at [AREACOORD(bar_spawner)]") template.stationinitload(get_turf(bar_spawner), centered = template.centerspawner) SSmapping.random_bar_spawners -= bar_spawner qdel(bar_spawner) @@ -500,6 +503,7 @@ Used by the AI doomsday and the self-destruct nuke. possible_arena_templates[arena_candidate] = arena_candidate.weight if(possible_arena_templates.len) var/datum/map_template/random_room/random_arena/template = pick_weight(possible_arena_templates) + log_world("Loading random arena template [template.name] ([template.type]) at [AREACOORD(arena_spawner)]") template.stationinitload(get_turf(arena_spawner), centered = template.centerspawner) SSmapping.random_arena_spawners -= arena_spawner qdel(arena_spawner) diff --git a/code/controllers/subsystem/processing/fire_burning.dm b/code/controllers/subsystem/processing/fire_burning.dm index 43c9ffd33064..6cde5e3c34f6 100644 --- a/code/controllers/subsystem/processing/fire_burning.dm +++ b/code/controllers/subsystem/processing/fire_burning.dm @@ -1,6 +1,6 @@ /// The subsystem used to tick [/datum/component/burning] instances. -PROCESSING_SUBSYSTEM_DEF(fire_burning) - name = "Fire Burning" +PROCESSING_SUBSYSTEM_DEF(burning) + name = "Burning" priority = FIRE_PRIORITY_BURNING flags = SS_NO_INIT|SS_BACKGROUND runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm index 8e78089022f7..89430ff368e2 100644 --- a/code/datums/components/acid.dm +++ b/code/datums/components/acid.dm @@ -1,10 +1,11 @@ -GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid")) +GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/acid.dmi', "default")) -/** Component representing acid applied to an object. - * +/** + * Component representing acid applied to an object. * Must be attached to an atom. * Processes, repeatedly damaging whatever it is attached to. * If the parent atom is a turf it applies acid to the contents of the turf. + * If not being applied to a mob or turf, the atom must use the integrity system. */ /datum/component/acid dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS @@ -14,6 +15,8 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e var/acid_volume /// The maximum volume of acid on the parent [/atom]. var/max_volume = INFINITY + /// Acid overlay appearance we apply + var/acid_overlay /// The ambiant sound of acid eating away at the parent [/atom]. var/datum/looping_sound/acid/sizzle /// Used exclusively for melting turfs. TODO: Move integrity to the atom level so that this can be dealt with there. @@ -23,71 +26,80 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e /// The proc used to handle the parent [/atom] when processing. TODO: Unify damage and resistance flags so that this doesn't need to exist! var/datum/callback/process_effect -/datum/component/acid/Initialize(_acid_power, _acid_volume, _max_volume=null) - if((_acid_power) <= 0 || (_acid_volume <= 0)) - stack_trace("Acid component added with insufficient acid power ([_acid_power]) or acid volume ([_acid_power]).") - return COMPONENT_INCOMPATIBLE // Not enough acid or the acid's too weak, either one. +/datum/component/acid/Initialize(acid_power = ACID_POWER_MELT_TURF, acid_volume = 50, acid_overlay = GLOB.acid_overlay) if(!isatom(parent)) - stack_trace("Acid component added to [parent] ([parent?.type]) which is not a /atom subtype.") - return COMPONENT_INCOMPATIBLE // Incompatible type. TODO: Rework take_damage to the atom level and move this there. - - if(isobj(parent)) - var/obj/parent_object = parent - if(parent_object.resistance_flags & UNACIDABLE) // The parent object cannot have acid. Should never happen, will happen. - stack_trace("Acid component added to unacidable object [parent].") - return COMPONENT_INCOMPATIBLE - - max_volume = OBJ_ACID_VOLUME_MAX - process_effect = CALLBACK(src, PROC_REF(process_obj), parent) - else if(isliving(parent)) + return COMPONENT_INCOMPATIBLE + //not incompatible, but pointless + var/atom/atom_parent = parent + if((acid_power) <= 0 || (acid_volume <= 0)) + stack_trace("Acid component added to an atom ([atom_parent.type]) with insufficient acid power ([acid_power]) or acid volume ([acid_volume]).") + qdel(src) + return + + + if(isliving(parent)) max_volume = MOB_ACID_VOLUME_MAX process_effect = CALLBACK(src, PROC_REF(process_mob), parent) else if(isturf(parent)) max_volume = TURF_ACID_VOLUME_MAX process_effect = CALLBACK(src, PROC_REF(process_turf), parent) + //if we failed all other checks, we must be an /atom/movable that uses integrity + else if(atom_parent.uses_integrity) + // The parent object cannot have acid. Not incompatible, but should not really happen. + if(atom_parent.resistance_flags & UNACIDABLE) + qdel(src) + return + + max_volume = MOVABLE_ACID_VOLUME_MAX + process_effect = CALLBACK(src, PROC_REF(process_movable), parent) + //or not... + else + stack_trace("Tried to add /datum/component/acid to an atom ([atom_parent.type]) which does not use atom_integrity!") + return COMPONENT_INCOMPATIBLE + + src.acid_power = acid_power + set_volume(acid_volume) + src.acid_overlay = acid_overlay - acid_power = _acid_power - set_volume(_acid_volume) - - var/atom/parent_atom = parent - RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays)) - parent_atom.update_appearance() sizzle = new(parent, TRUE) START_PROCESSING(SSacid, src) /datum/component/acid/Destroy(force, silent) STOP_PROCESSING(SSacid, src) - QDEL_NULL(sizzle) + if(sizzle) + QDEL_NULL(sizzle) if(process_effect) QDEL_NULL(process_effect) - UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS) - if(parent && !QDELING(parent)) - var/atom/parent_atom = parent - parent_atom.update_appearance() return ..() /datum/component/acid/RegisterWithParent() RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays)) RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(on_clean)) RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(on_attack_hand)) RegisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENT, PROC_REF(on_expose_reagent)) if(isturf(parent)) RegisterSignal(parent, COMSIG_ATOM_ENTERED, PROC_REF(on_entered)) + var/atom/atom_parent = parent + atom_parent.update_appearance() /datum/component/acid/UnregisterFromParent() UnregisterSignal(parent, list( COMSIG_ATOM_EXAMINE, + COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_EXPOSE_REAGENT)) - if(isturf(parent)) UnregisterSignal(parent, COMSIG_ATOM_ENTERED) + var/atom/atom_parent = parent + if(!QDELETED(atom_parent)) + atom_parent.update_appearance() /// Averages corrosive power and sums volume. -/datum/component/acid/InheritComponent(datum/component/C, i_am_original, _acid_power, _acid_volume) - acid_power = ((acid_power * acid_volume) + (_acid_power * _acid_volume)) / (acid_volume + _acid_volume) - set_volume(acid_volume + _acid_volume) +/datum/component/acid/InheritComponent(datum/component/new_comp, i_am_original, acid_power, acid_volume) + acid_power = ((src.acid_power * src.acid_volume) + (acid_power * acid_volume)) / (src.acid_volume + acid_volume) + set_volume(src.acid_volume + acid_volume) /// Sets the acid volume to a new value. Limits the acid volume by the amount allowed to exist on the parent atom. /datum/component/acid/proc/set_volume(new_volume) @@ -95,7 +107,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(!acid_volume) qdel(src) - /// Handles the slow corrosion of the parent [/atom]. /datum/component/acid/process(seconds_per_tick) process_effect?.InvokeAsync(seconds_per_tick) @@ -103,11 +114,11 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e return set_volume(acid_volume - (ACID_DECAY_BASE + (ACID_DECAY_SCALING*round(sqrt(acid_volume)))) * seconds_per_tick) -/// Handles processing on a [/obj]. -/datum/component/acid/proc/process_obj(obj/target, seconds_per_tick) +/// Handles processing on an [/atom/movable] (that uses atom_integrity). +/datum/component/acid/proc/process_movable(atom/movable/target, seconds_per_tick) if(target.resistance_flags & ACID_PROOF) return - target.take_damage(min(1 + round(sqrt(acid_power * acid_volume)*0.3), OBJ_ACID_DAMAGE_MAX) * seconds_per_tick, BURN, ACID, 0) + target.take_damage(min(1 + round(sqrt(acid_power * acid_volume)*0.3), MOVABLE_ACID_DAMAGE_MAX) * seconds_per_tick, BURN, ACID, 0) /// Handles processing on a [/mob/living]. /datum/component/acid/proc/process_mob(mob/living/target, seconds_per_tick) @@ -117,8 +128,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e /datum/component/acid/proc/process_turf(turf/target_turf, seconds_per_tick) var/acid_used = min(acid_volume * 0.05, 20) * seconds_per_tick var/applied_targets = 0 - for(var/am in target_turf) - var/atom/movable/target_movable = am + for(var/atom/movable/target_movable as anything in target_turf) if(target_movable.acid_act(acid_power, acid_used)) applied_targets++ @@ -150,16 +160,17 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e /datum/component/acid/proc/on_update_overlays(atom/parent_atom, list/overlays) SIGNAL_HANDLER - overlays += mutable_appearance('icons/effects/acid.dmi', parent_atom.custom_acid_overlay || ACID_OVERLAY_DEFAULT) + if(acid_overlay) + overlays += acid_overlay /// Alerts any examiners to the acid on the parent atom. -/datum/component/acid/proc/on_examine(atom/A, mob/user, list/examine_list) +/datum/component/acid/proc/on_examine(atom/source, mob/user, list/examine_list) SIGNAL_HANDLER - examine_list += span_danger("[A.p_theyre()] covered in corrosive liquid!") + examine_list += span_danger("[source.p_theyre(TRUE)] covered in a corrosive liquid!") /// Makes it possible to clean acid off of objects. -/datum/component/acid/proc/on_clean(atom/A, clean_types) +/datum/component/acid/proc/on_clean(atom/source, clean_types) SIGNAL_HANDLER if(!(clean_types & CLEAN_TYPE_ACID)) @@ -178,7 +189,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e set_volume(acid_volume + reac_volume) return NONE - /// Handles searing the hand of anyone who tries to touch this without protection. /datum/component/acid/proc/on_attack_hand(atom/parent_atom, mob/living/carbon/user) SIGNAL_HANDLER @@ -201,7 +211,6 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e user.update_damage_overlays() return COMPONENT_CANCEL_ATTACK_CHAIN - /// Handles searing the feet of whoever walks over this without protection. Only active if the parent is a turf. /datum/component/acid/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER diff --git a/code/datums/components/burning.dm b/code/datums/components/burning.dm index d2ccd03147c7..347340e3e2c4 100644 --- a/code/datums/components/burning.dm +++ b/code/datums/components/burning.dm @@ -2,7 +2,8 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e /** * Component representing an atom being on fire. - * Should not be used on mobs, they use the fire stacks system. + * Should not be used on mobs, they use the fire stacks status effects. + * Can only be used on atoms that use the integrity system. */ /datum/component/burning /// Fire overlay appearance we apply @@ -10,12 +11,12 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e /// Particle holder for fire particles, if any var/obj/effect/abstract/particle_holder/particle_effect -/datum/component/burning/Initialize(fire_overlay, fire_particles) +/datum/component/burning/Initialize(fire_overlay = GLOB.fire_overlay, fire_particles = /particles/smoke/burning) if(!isatom(parent)) return COMPONENT_INCOMPATIBLE var/atom/atom_parent = parent if(!atom_parent.uses_integrity) - stack_trace("Tried to add /datum/component/burning to an atom ([atom_parent]) that does not use atom_integrity!") + stack_trace("Tried to add /datum/component/burning to an atom ([atom_parent.type]) that does not use atom_integrity!") return COMPONENT_INCOMPATIBLE // only flammable atoms should have this component, but it's not really an error if we try to apply this to a non flammable one if(!(atom_parent.resistance_flags & FLAMMABLE) || (atom_parent.resistance_flags & FIRE_PROOF)) @@ -23,30 +24,30 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e return src.fire_overlay = fire_overlay if(fire_particles) - particle_effect = new(atom_parent, fire_particles) - atom_parent.resistance_flags |= ON_FIRE - START_PROCESSING(SSfire_burning, src) + // burning particles look pretty bad when they stack on mobs, so that behavior is not wanted for items + particle_effect = new(atom_parent, fire_particles, isitem(atom_parent) ? NONE : PARTICLE_ATTACH_MOB) + START_PROCESSING(SSburning, src) + +/datum/component/burning/Destroy(force, silent) + STOP_PROCESSING(SSburning, src) + if(particle_effect) + QDEL_NULL(particle_effect) + return ..() /datum/component/burning/RegisterWithParent() - . = ..() + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays)) RegisterSignal(parent, COMSIG_ATOM_EXTINGUISH, PROC_REF(on_extinguish)) var/atom/atom_parent = parent - atom_parent.update_appearance(UPDATE_ICON) + atom_parent.resistance_flags |= ON_FIRE + atom_parent.update_appearance() /datum/component/burning/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ATOM_EXTINGUISH)) - -/datum/component/burning/Destroy(force, silent) - STOP_PROCESSING(SSfire_burning, src) - if(particle_effect) - QDEL_NULL(particle_effect) + UnregisterSignal(parent, list(COMSIG_ATOM_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_ATOM_EXTINGUISH)) var/atom/atom_parent = parent - if(!QDELING(atom_parent) && (atom_parent.resistance_flags & ON_FIRE)) + if(!QDELETED(atom_parent)) atom_parent.resistance_flags &= ~ON_FIRE - atom_parent.update_appearance(UPDATE_ICON) - return ..() + atom_parent.update_appearance() /datum/component/burning/process(seconds_per_tick) var/atom/atom_parent = parent @@ -56,10 +57,20 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e return atom_parent.take_damage(10 * seconds_per_tick, BURN, FIRE, FALSE) +/// Alerts any examiners that the parent is on fire (even though it should be rather obvious) +/datum/component/burning/proc/on_examine(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + examine_list += span_danger("[source.p_theyre(TRUE)] burning!") + /// Maintains the burning overlay on the parent atom /datum/component/burning/proc/on_update_overlays(atom/source, list/overlays) SIGNAL_HANDLER + //most likely means the component is being removed + if(!(source.resistance_flags & ON_FIRE)) + return + if(fire_overlay) overlays += fire_overlay diff --git a/code/datums/components/irradiated.dm b/code/datums/components/irradiated.dm index c8a57f3761ad..bffd56459bfb 100644 --- a/code/datums/components/irradiated.dm +++ b/code/datums/components/irradiated.dm @@ -96,7 +96,7 @@ process_tox_damage(human_parent, seconds_per_tick) /datum/component/irradiated/proc/should_halt_effects(mob/living/carbon/human/target) - if (IS_IN_STASIS(target)) + if (HAS_TRAIT(target, TRAIT_STASIS)) return TRUE if (HAS_TRAIT(target, TRAIT_HALT_RADIATION_EFFECTS)) diff --git a/code/datums/mutations/void_magnet.dm b/code/datums/mutations/void_magnet.dm index d6636b0b6306..48f04eda636a 100644 --- a/code/datums/mutations/void_magnet.dm +++ b/code/datums/mutations/void_magnet.dm @@ -60,7 +60,7 @@ /datum/action/cooldown/spell/void/cursed/proc/on_life(mob/living/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - if(!isliving(source) || IS_IN_STASIS(source) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) + if(!isliving(source) || HAS_TRAIT(source, TRAIT_STASIS) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) return if(!is_valid_target(source)) diff --git a/code/datums/quirks/negative_quirks.dm b/code/datums/quirks/negative_quirks.dm index 3a6f72acdc9b..77328dfce103 100644 --- a/code/datums/quirks/negative_quirks.dm +++ b/code/datums/quirks/negative_quirks.dm @@ -981,7 +981,7 @@ if(!iscarbon(quirk_holder)) return - if(IS_IN_STASIS(quirk_holder)) + if(HAS_TRAIT(quirk_holder, TRAIT_STASIS)) return if(quirk_holder.stat == DEAD) diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index fa9a3f785581..504b89e590ff 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -254,7 +254,7 @@ . = ..() if(!.) return - owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), TRAIT_STATUS_EFFECT(id)) + owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS), TRAIT_STATUS_EFFECT(id)) owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2)) var/filter = owner.get_filter("stasis_status_ripple") animate(filter, radius = 0, time = 0.2 SECONDS, size = 2, easing = JUMP_EASING, loop = -1, flags = ANIMATION_PARALLEL) @@ -267,7 +267,7 @@ update_time_of_death() /datum/status_effect/grouped/stasis/on_remove() - owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED), TRAIT_STATUS_EFFECT(id)) + owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS), TRAIT_STATUS_EFFECT(id)) owner.remove_filter("stasis_status_ripple") update_time_of_death() if(iscarbon(owner)) diff --git a/code/datums/status_effects/debuffs/dna_transformation.dm b/code/datums/status_effects/debuffs/dna_transformation.dm new file mode 100644 index 000000000000..09c688e7c1f4 --- /dev/null +++ b/code/datums/status_effects/debuffs/dna_transformation.dm @@ -0,0 +1,92 @@ +/// Transforms a carbon mob into a new DNA for a set amount of time, +/// then turns them back to how they were before transformation. +/datum/status_effect/temporary_transformation + id = "temp_dna_transformation" + tick_interval = -1 + duration = 1 MINUTES // set in on creation, this just needs to be any value to process + alert_type = null + remove_on_fullheal = TRUE + /// A reference to a COPY of the DNA that the mob will be transformed into. + var/datum/dna/new_dna + /// A reference to a COPY of the DNA of the mob prior to transformation. + var/datum/dna/old_dna + +/datum/status_effect/temporary_transformation/Destroy() + . = ..() // parent must be called first, so we clear DNA refs AFTER transforming back... yeah i know + QDEL_NULL(new_dna) + QDEL_NULL(old_dna) + +/datum/status_effect/temporary_transformation/on_creation(mob/living/new_owner, new_duration = 1 MINUTES, datum/dna/dna_to_copy) + src.duration = (new_duration == INFINITY) ? -1 : new_duration + src.new_dna = new() + src.old_dna = new() + dna_to_copy.copy_dna(new_dna) + return ..() + +/datum/status_effect/temporary_transformation/on_apply() + if(!iscarbon(owner)) + return FALSE + + var/mob/living/carbon/transforming = owner + if(!transforming.has_dna()) + return FALSE + + // Save the old DNA + transforming.dna.copy_dna(old_dna) + // Makes them into the new DNA + new_dna.transfer_identity(transforming) + transforming.real_name = new_dna.real_name + transforming.name = transforming.get_visible_name() + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + return TRUE + +/datum/status_effect/temporary_transformation/on_remove() + var/mob/living/carbon/transforming = owner + + if(!QDELING(owner)) // Don't really need to do appearance stuff if we're being deleted + old_dna.transfer_identity(transforming) + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + + transforming.real_name = old_dna.real_name // Name is fine though + transforming.name = transforming.get_visible_name() + +/datum/status_effect/temporary_transformation/trans_sting + /// Tracks the time left on the effect when the owner last died. Used to pause the effect. + var/time_before_pause = -1 + /// Signals which we react to to determine if we should pause the effect. + var/static/list/update_on_signals = list( + COMSIG_MOB_STATCHANGE, + SIGNAL_ADDTRAIT(TRAIT_STASIS), + SIGNAL_REMOVETRAIT(TRAIT_STASIS), + SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), + SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), + ) + +/datum/status_effect/temporary_transformation/trans_sting/on_apply() + . = ..() + if(!.) + return + RegisterSignals(owner, update_on_signals, PROC_REF(pause_effect)) + pause_effect(owner) // for if we sting a dead guy + +/datum/status_effect/temporary_transformation/trans_sting/on_remove() + . = ..() + UnregisterSignal(owner, update_on_signals) + +/datum/status_effect/temporary_transformation/trans_sting/proc/pause_effect(mob/living/source) + SIGNAL_HANDLER + + // Pause if we're dead, appear dead, or in stasis + if(source.stat == DEAD || HAS_TRAIT(source, TRAIT_DEATHCOMA) || HAS_TRAIT(source, TRAIT_STASIS)) + if(duration == -1) + return // Already paused + + time_before_pause = duration - world.time + duration = -1 + + // Resume if we're none of the above and also were paused + else if(time_before_pause != -1) + duration = time_before_pause + world.time + time_before_pause = -1 diff --git a/code/datums/status_effects/debuffs/drowsiness.dm b/code/datums/status_effects/debuffs/drowsiness.dm index 5bc415d7cd44..a64fd710068d 100644 --- a/code/datums/status_effects/debuffs/drowsiness.dm +++ b/code/datums/status_effects/debuffs/drowsiness.dm @@ -29,7 +29,7 @@ /datum/status_effect/drowsiness/tick(seconds_per_tick) // You do not feel drowsy while unconscious or in stasis - if(owner.stat >= UNCONSCIOUS || IS_IN_STASIS(owner)) + if(owner.stat >= UNCONSCIOUS || HAS_TRAIT(owner, TRAIT_STASIS)) return // Resting helps against drowsiness diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm index adba65380261..e0b26797b9f4 100644 --- a/code/datums/status_effects/debuffs/drunk.dm +++ b/code/datums/status_effects/debuffs/drunk.dm @@ -63,7 +63,7 @@ /datum/status_effect/inebriated/tick() // Drunk value does not decrease while dead or in stasis - if(owner.stat == DEAD || IS_IN_STASIS(owner)) + if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_STASIS)) return // Every tick, the drunk value decrases by diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index c84c0598b642..12482d152236 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -76,7 +76,7 @@ /datum/wound/blunt/bone/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index 42203c4f2a70..f34cd34623b6 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -37,7 +37,7 @@ /datum/wound/burn/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return . = ..() diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index 82f49b035032..1085b422263d 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -66,7 +66,7 @@ return BLOOD_FLOW_STEADY /datum/wound/pierce/bleed/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)) diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 410f48d9d576..e297849e61a3 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -134,7 +134,7 @@ /datum/wound/slash/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return // in case the victim has the NOBLOOD trait, the wound will simply not clot on it's own diff --git a/code/game/atom_defense.dm b/code/game/atom_defense.dm index 7d6fa23911f9..0149a0175f79 100644 --- a/code/game/atom_defense.dm +++ b/code/game/atom_defense.dm @@ -137,19 +137,3 @@ if(uses_integrity) return clamp(PENETRATE_ARMOUR(get_armor_rating(impacting_projectile.armor_flag), impacting_projectile.armour_penetration), 0, 100) return 0 - -/** - * Should be called when the atom is destroyed by fire - * This proc is terrible. I do not know why it exists. - * Please remove it at some point. - */ -/atom/proc/burn() - return - -/** - * Sends COMSIG_ATOM_EXTINGUISH signal which properly removes burning component. - * Can be hooked onto for extra behavior. - */ -/atom/proc/extinguish() - SHOULD_CALL_PARENT(TRUE) - return SEND_SIGNAL(src, COMSIG_ATOM_EXTINGUISH) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 779671e94a46..e8b4b6f9c7f0 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -949,9 +949,23 @@ return FALSE return TRUE +/** + * Respond to fire being used on our atom + * + * Default behaviour is to send [COMSIG_ATOM_FIRE_ACT] and return + */ /atom/proc/fire_act(exposed_temperature, exposed_volume) SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) - return + return FALSE + +/** + * Sends [COMSIG_ATOM_EXTINGUISH] signal, which properly removes burning component if it is present. + * + * Default behaviour is to send [COMSIG_ATOM_ACID_ACT] and return + */ +/atom/proc/extinguish() + SHOULD_CALL_PARENT(TRUE) + return SEND_SIGNAL(src, COMSIG_ATOM_EXTINGUISH) /** * React to being hit by a thrown object @@ -1912,6 +1926,7 @@ * Override this if you want custom behaviour in whatever gets hit by the rust */ /atom/proc/rust_heretic_act() + return /** * Used to set something as 'open' if it's being used as a supplypod diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 5fca4a56b0d1..3123bc4749f9 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -1114,8 +1114,6 @@ if(machine_stat & BROKEN) . += span_notice("It looks broken and non-functional.") if(!(resistance_flags & INDESTRUCTIBLE)) - if(resistance_flags & ON_FIRE) - . += span_warning("It's on fire!") var/healthpercent = (atom_integrity/max_integrity) * 100 switch(healthpercent) if(50 to 99) diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 54deffb85626..b60b563f7b2d 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -68,7 +68,7 @@ /obj/machinery/stasis/Exited(atom/movable/gone, direction) if(gone == occupant) var/mob/living/L = gone - if(IS_IN_STASIS(L)) + if(HAS_TRAIT(L, TRAIT_STASIS)) thaw_them(L) return ..() @@ -157,9 +157,9 @@ return var/mob/living/L_occupant = occupant if(stasis_running()) - if(!IS_IN_STASIS(L_occupant)) + if(!HAS_TRAIT(L_occupant, TRAIT_STASIS)) chill_out(L_occupant) - else if(IS_IN_STASIS(L_occupant)) + else if(HAS_TRAIT(L_occupant, TRAIT_STASIS)) thaw_them(L_occupant) /obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) diff --git a/code/game/objects/effects/particles/smoke.dm b/code/game/objects/effects/particles/smoke.dm index 13c8da4218e0..4f31ffc08699 100644 --- a/code/game/objects/effects/particles/smoke.dm +++ b/code/game/objects/effects/particles/smoke.dm @@ -18,6 +18,11 @@ /particles/smoke/burning position = list(0, 0, 0) +/particles/smoke/burning/small + spawning = 1 + scale = list(0.8, 0.8) + velocity = list(0, 0.4, 0) + /particles/smoke/steam icon_state = list("steam_1" = 1, "steam_2" = 1, "steam_3" = 2) fade = 1.5 SECONDS diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index e2078dad2d2b..02588d175c03 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -3,6 +3,7 @@ name = "item" icon = 'icons/obj/objects.dmi' blocks_emissive = EMISSIVE_BLOCK_GENERIC + burning_particles = /particles/smoke/burning/small pass_flags_self = PASSITEM /* !!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!! diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 0d29aa1f203d..383c9d88af7e 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -116,10 +116,10 @@ ///the obj's reaction when touched by acid /obj/acid_act(acidpwr, acid_volume) . = ..() - if((resistance_flags & UNACIDABLE) || (acid_volume <= 0) || acidpwr <= 0) + if((resistance_flags & UNACIDABLE) || (acid_volume <= 0) || (acidpwr <= 0)) return FALSE - AddComponent(/datum/component/acid, acidpwr, acid_volume) + AddComponent(/datum/component/acid, acidpwr, acid_volume, custom_acid_overlay || GLOB.acid_overlay) return TRUE ///called when the obj is destroyed by acid. @@ -131,8 +131,8 @@ ///Called when the obj is exposed to fire. /obj/fire_act(exposed_temperature, exposed_volume) if(isturf(loc)) - var/turf/T = loc - if(T.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE)) + var/turf/our_turf = loc + if(our_turf.underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(src, TRAIT_T_RAY_VISIBLE)) return if(exposed_temperature && !(resistance_flags & FIRE_PROOF)) take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0) @@ -141,9 +141,8 @@ return TRUE return ..() -///called when the obj is destroyed by fire -/obj/burn() - . = ..() +/// Should be called when the atom is destroyed by fire, comparable to acid_melt() proc +/obj/proc/burn() deconstruct(FALSE) ///Called when the obj is hit by a tesla bolt. diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index f9568d660cb3..2e5f404b5849 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -339,11 +339,6 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) if(. && receive_ricochet_damage_coeff) take_damage(P.damage * receive_ricochet_damage_coeff, P.damage_type, P.armor_flag, 0, turn(P.dir, 180), P.armour_penetration) // pass along receive_ricochet_damage_coeff damage to the structure for the ricochet -/obj/update_overlays() - . = ..() - if(resistance_flags & ON_FIRE) - . += custom_fire_overlay ? custom_fire_overlay : GLOB.fire_overlay - /// Handles exposing an object to reagents. /obj/expose_reagents(list/reagents, datum/reagents/source, methods=TOUCH, volume_modifier=1, show_message=TRUE) . = ..() diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 871a58e823b5..3e2d83550000 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -146,13 +146,13 @@ var/mob/living/burn_victim = burn_target burn_victim.adjust_fire_stacks(BONFIRE_FIRE_STACK_STRENGTH * 0.5 * seconds_per_tick) burn_victim.ignite_mob() - else if(isobj(burn_target)) - var/obj/burned_object = burn_target - if(grill && isitem(burned_object)) - var/obj/item/grilled_item = burned_object + else + var/atom/movable/burned_movable = burn_target + if(grill && isitem(burned_movable)) + var/obj/item/grilled_item = burned_movable SEND_SIGNAL(grilled_item, COMSIG_ITEM_GRILL_PROCESS, src, seconds_per_tick) //Not a big fan, maybe make this use fire_act() in the future. continue - burned_object.fire_act(1000, 250 * seconds_per_tick) + burned_movable.fire_act(1000, 250 * seconds_per_tick) /obj/structure/bonfire/process(seconds_per_tick) if(!check_oxygen()) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 8808b89125e3..5303c8856515 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -601,12 +601,12 @@ GLOBAL_LIST_EMPTY(station_turfs) if((acidpwr <= 0) || (acid_volume <= 0)) return FALSE - AddComponent(/datum/component/acid, acidpwr, acid_volume) - for(var/obj/O in src) - if(underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE)) + AddComponent(/datum/component/acid, acidpwr, acid_volume, GLOB.acid_overlay) + for(var/atom/movable/movable_atom as anything in src) + if(underfloor_accessibility < UNDERFLOOR_INTERACTABLE && HAS_TRAIT(movable_atom, TRAIT_T_RAY_VISIBLE)) continue - O.acid_act(acidpwr, acid_volume) + movable_atom.acid_act(acidpwr, acid_volume) return . || TRUE diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index f8e731e820e9..0eab76764623 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -65,46 +65,74 @@ /datum/action/changeling/sting/transformation name = "Transformation Sting" - desc = "We silently sting a human, injecting a retrovirus that forces them to transform. Costs 50 chemicals." - helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human." + desc = "We silently sting an organism, injecting a retrovirus that forces them to transform." + helptext = "The victim will transform much like a changeling would. \ + For complex humanoids, the transformation is temporarily, but the duration is paused while the victim is dead or in stasis. \ + For more simple humanoids, such as monkeys, the transformation is permanent. \ + Does not provide a warning to others. Mutations will not be transferred." button_icon_state = "sting_transform" - chemical_cost = 50 - dna_cost = 3 - var/datum/changeling_profile/selected_dna = null + chemical_cost = 33 // Low enough that you can sting only two people in quick succession + dna_cost = 2 + /// A reference to our active profile, which we grab DNA from + VAR_FINAL/datum/changeling_profile/selected_dna + /// Duration of the sting + var/sting_duration = 8 MINUTES + +/datum/action/changeling/sting/transformation/Grant(mob/grant_to) + . = ..() + build_all_button_icons(UPDATE_BUTTON_NAME) -/datum/action/changeling/sting/transformation/Trigger(trigger_flags) - var/mob/user = usr +/datum/action/changeling/sting/transformation/update_button_name(atom/movable/screen/movable/action_button/button, force) + . = ..() + button.desc += " Lasts [DisplayTimeText(sting_duration)] for humans, but duration is paused while dead or in stasis." + button.desc += " Costs [chemical_cost] chemicals." + +/datum/action/changeling/sting/transformation/Destroy() + selected_dna = null + return ..() + +/datum/action/changeling/sting/transformation/set_sting(mob/user) + selected_dna = null var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling.chosen_sting) - unset_sting(user) + var/datum/changeling_profile/new_selected_dna = changeling.select_dna() + if(QDELETED(src) || QDELETED(changeling) || QDELETED(user)) return - selected_dna = changeling.select_dna() - if(!selected_dna) + if(!new_selected_dna || changeling.chosen_sting || selected_dna) // selected other sting or other DNA while sleeping return - if(NOTRANSSTING in selected_dna.dna.species.species_traits) - user.balloon_alert(user, "incompatible DNA!") - return - ..() + selected_dna = new_selected_dna + return ..() /datum/action/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target) . = ..() if(!.) return - if((HAS_TRAIT(target, TRAIT_HUSK)) || !iscarbon(target) || (NOTRANSSTING in target.dna.species.species_traits)) + // Similar checks here are ran to that of changeling can_absorb_dna - + // Logic being that if their DNA is incompatible with us, it's also bad for transforming + if(!iscarbon(target) \ + || !target.has_dna() \ + || HAS_TRAIT(target, TRAIT_HUSK) \ + || HAS_TRAIT(target, TRAIT_BADDNA) \ + || (HAS_TRAIT(target, TRAIT_NO_DNA_COPY) && !ismonkey(target))) // sure, go ahead, make a monk-clone user.balloon_alert(user, "incompatible DNA!") return FALSE + if(target.has_status_effect(/datum/status_effect/temporary_transformation/trans_sting)) + user.balloon_alert(user, "already transformed!") + return FALSE return TRUE -/datum/action/changeling/sting/transformation/sting_action(mob/user, mob/target) - log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'") - var/datum/dna/NewDNA = selected_dna.dna - - var/mob/living/carbon/C = target - . = TRUE - if(istype(C)) - C.real_name = NewDNA.real_name - NewDNA.transfer_identity(C) - C.updateappearance(mutcolor_update=1) +/datum/action/changeling/sting/transformation/sting_action(mob/living/user, mob/living/target) + var/final_duration = sting_duration + var/final_message = span_notice("We transform [target] into [selected_dna.dna.real_name].") + if(ismonkey(target)) + final_duration = INFINITY + final_message = span_warning("Our genes cry out as we transform the lesser form of [target] into [selected_dna.dna.real_name] permanently!") + + if(target.apply_status_effect(/datum/status_effect/temporary_transformation/trans_sting, final_duration, selected_dna.dna)) + ..() + log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'") + to_chat(user, final_message) + return TRUE + return FALSE /datum/action/changeling/sting/false_armblade diff --git a/code/modules/bitrunning/antagonists/cyber_police.dm b/code/modules/bitrunning/antagonists/cyber_police.dm index 438b86acdec9..73ff96ff7c8c 100644 --- a/code/modules/bitrunning/antagonists/cyber_police.dm +++ b/code/modules/bitrunning/antagonists/cyber_police.dm @@ -33,7 +33,6 @@ player.add_traits(list( //TRAIT_NO_AUGMENTS, TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, TRAIT_NOBLOOD, TRAIT_NOBREATH, TRAIT_NOHUNGER, diff --git a/code/modules/bitrunning/components/netpod_healing.dm b/code/modules/bitrunning/components/netpod_healing.dm index fc7de89bcf3e..2d302d5b4adb 100644 --- a/code/modules/bitrunning/components/netpod_healing.dm +++ b/code/modules/bitrunning/components/netpod_healing.dm @@ -59,6 +59,15 @@ id = "embryonic" alert_type = /atom/movable/screen/alert/status_effect/embryonic +/datum/status_effect/embryonic/on_apply() + . = ..() + if(.) + ADD_TRAIT(owner, TRAIT_STASIS, TRAIT_STATUS_EFFECT(id)) + +/datum/status_effect/embryonic/on_remove() + REMOVE_TRAIT(owner, TRAIT_STASIS, TRAIT_STATUS_EFFECT(id)) + return ..() + /atom/movable/screen/alert/status_effect/embryonic name = "Embryonic Stasis" icon_state = "netpod_stasis" diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 2e2674e14e76..147079ae720c 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -3,7 +3,7 @@ /mob/living/carbon/alien/larva/Life(seconds_per_tick = SSMOBS_DT, times_fired) if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return - if(!..() || IS_IN_STASIS(src) || (amount_grown >= max_grown)) + if(!..() || HAS_TRAIT(src, TRAIT_STASIS) || (amount_grown >= max_grown)) return // We're dead, in stasis, or already grown. // GROW! amount_grown = min(amount_grown + (0.5 * seconds_per_tick), max_grown) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index ac449c7794c9..9d9be81466ac 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -1548,7 +1548,7 @@ GLOBAL_LIST_EMPTY(features_by_species) return //Only stabilise core temp when alive and not in statis - if(humi.stat < DEAD && !IS_IN_STASIS(humi)) + if(humi.stat < DEAD && !HAS_TRAIT(humi, TRAIT_STASIS)) body_temperature_core(humi, seconds_per_tick, times_fired) //These do run in statis @@ -1556,7 +1556,7 @@ GLOBAL_LIST_EMPTY(features_by_species) body_temperature_alerts(humi, seconds_per_tick, times_fired) //Do not cause more damage in statis - if(!IS_IN_STASIS(humi)) + if(!HAS_TRAIT(humi, TRAIT_STASIS)) body_temperature_damage(humi, seconds_per_tick, times_fired) /** diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 678442bd79d3..09e83b21d87a 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -29,7 +29,7 @@ //Body temperature stability and damage dna.species.handle_body_temperature(src, seconds_per_tick, times_fired) - if(!IS_IN_STASIS(src)) + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(.) //not dead for(var/datum/mutation/human/HM in dna.mutations) // Handle active genes 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 45d36076c6f6..037df6b982e3 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -16,7 +16,6 @@ TRAIT_PIERCEIMMUNE, TRAIT_RADIMMUNE, TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, TRAIT_NODISMEMBER, TRAIT_NEVER_WOUNDED ) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 660fb28e8e81..e9dd49a3a951 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -14,7 +14,7 @@ damageoverlaytemp = 0 update_damage_hud() - if(IS_IN_STASIS(src)) + if(HAS_TRAIT(src, TRAIT_STASIS)) . = ..() reagents.handle_stasis_chems(src, seconds_per_tick, times_fired) else diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 27995ce1ce00..cda90a8e7316 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -40,7 +40,7 @@ if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return - if(!IS_IN_STASIS(src)) + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(stat != DEAD) //Mutations and radiation diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e8be8f51da47..07150137a295 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -531,7 +531,7 @@ return TRUE if(!(flags & IGNORE_GRAB) && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE) return TRUE - if(!(flags & IGNORE_STASIS) && IS_IN_STASIS(src)) + if(!(flags & IGNORE_STASIS) && HAS_TRAIT(src, TRAIT_STASIS)) return TRUE return FALSE @@ -1564,9 +1564,9 @@ GLOBAL_LIST_EMPTY(fire_appearances) return fire_status.ignite(silent) /mob/living/proc/update_fire() - var/datum/status_effect/fire_handler/fire_handler = has_status_effect(/datum/status_effect/fire_handler) - if(fire_handler) - fire_handler.update_overlay() + var/datum/status_effect/fire_handler/fire_stacks/fire_stacks = has_status_effect(/datum/status_effect/fire_handler/fire_stacks) + if(fire_stacks) + fire_stacks.update_overlay() /** * Extinguish all fire on the mob diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 8df5e8b6d596..f5224f337d1f 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -1154,12 +1154,12 @@ if(BLEED_OVERLAY_LOW to BLEED_OVERLAY_MED) new_bleed_icon = "[body_zone]_1" if(BLEED_OVERLAY_MED to BLEED_OVERLAY_GUSH) - if(owner.body_position == LYING_DOWN || IS_IN_STASIS(owner) || owner.stat == DEAD) + if(owner.body_position == LYING_DOWN || HAS_TRAIT(owner, TRAIT_STASIS) || owner.stat == DEAD) new_bleed_icon = "[body_zone]_2s" else new_bleed_icon = "[body_zone]_2" if(BLEED_OVERLAY_GUSH to INFINITY) - if(IS_IN_STASIS(owner) || owner.stat == DEAD) + if(HAS_TRAIT(owner, TRAIT_STASIS) || owner.stat == DEAD) new_bleed_icon = "[body_zone]_2s" else new_bleed_icon = "[body_zone]_3" diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index 449f636c8303..03554ac081d4 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -64,8 +64,6 @@ /obj/vehicle/examine(mob/user) . = ..() - if(resistance_flags & ON_FIRE) - . += span_warning("It's on fire!") . += generate_integrity_message() /// Returns a readable string of the vehicle's health for examining. Overridden by subtypes who want to be more verbose with their health messages. diff --git a/monkestation/code/modules/datums/components/nanites.dm b/monkestation/code/modules/datums/components/nanites.dm index 29f516da7828..a2d5a962e249 100644 --- a/monkestation/code/modules/datums/components/nanites.dm +++ b/monkestation/code/modules/datums/components/nanites.dm @@ -110,7 +110,7 @@ adjust_nanites(null, amount) //just add to the nanite volume /datum/component/nanites/process(seconds_per_tick) - if(!IS_IN_STASIS(host_mob)) + if(!HAS_TRAIT(host_mob, TRAIT_STASIS)) adjust_nanites(null, (regen_rate + (SSresearch.science_tech.researched_nodes["nanite_harmonic"] ? HARMONIC_REGEN_BOOST : 0)) * seconds_per_tick) add_research() for(var/X in programs) diff --git a/monkestation/code/modules/ghost_players/arena/arena_assets/event_floors.dm b/monkestation/code/modules/ghost_players/arena/arena_assets/event_floors.dm index 5ed0633862cc..64d10d42108c 100644 --- a/monkestation/code/modules/ghost_players/arena/arena_assets/event_floors.dm +++ b/monkestation/code/modules/ghost_players/arena/arena_assets/event_floors.dm @@ -8,3 +8,9 @@ barefootstep = FOOTSTEP_HARD_BAREFOOT clawfootstep = FOOTSTEP_HARD_CLAW heavyfootstep = FOOTSTEP_GENERIC_HEAVY + +/turf/open/misc/ashplanet/rocky/arena + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + +/turf/open/water/arena + initial_gas_mix = OPENTURF_DEFAULT_ATMOS diff --git a/monkestation/code/modules/ghost_players/arena/maps/atlantis.dmm b/monkestation/code/modules/ghost_players/arena/maps/atlantis.dmm index 06e098ddcf56..de89b464516c 100644 --- a/monkestation/code/modules/ghost_players/arena/maps/atlantis.dmm +++ b/monkestation/code/modules/ghost_players/arena/maps/atlantis.dmm @@ -10,41 +10,31 @@ "b" = ( /mob/living/basic/aquatic/fish, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "d" = ( /obj/structure/flora/bush/stalky/style_3, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "g" = ( /obj/structure/flora/rock/pile/icy/style_2{ name = "rocks" }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "h" = ( /obj/structure/flora/rock/icy/style_2{ name = "rock" }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "i" = ( /obj/effect/overlay/water, /obj/machinery/light/floor/has_bulb, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "k" = ( /obj/structure/atlantis/column/broken_1, @@ -91,27 +81,21 @@ anchored = 1 }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "v" = ( /obj/structure/flora/rock/pile/icy/style_3{ name = "rocks" }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "w" = ( /obj/structure/flora/rock/icy{ name = "rock" }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "z" = ( /obj/effect/overlay/water, @@ -122,9 +106,7 @@ "A" = ( /obj/structure/flora/bush/stalky/style_2, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "B" = ( /obj/item/aquarium_prop/seaweed_top{ @@ -132,9 +114,7 @@ }, /obj/effect/overlay/water, /obj/machinery/light/floor/has_bulb, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "D" = ( /obj/effect/overlay/water, @@ -146,56 +126,42 @@ "E" = ( /obj/structure/flora/bush/stalky, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "G" = ( /obj/structure/flora/rock/pile/icy{ name = "rocks" }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "H" = ( /mob/living/basic/aquatic/fish/gupper, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "K" = ( /obj/structure/flora/rock/icy/style_3{ name = "rock" }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "L" = ( /obj/machinery/light/floor/has_bulb, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "N" = ( /obj/item/aquarium_prop/seaweed_top{ anchored = 1 }, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "P" = ( /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "Q" = ( /obj/structure/atlantis/statue{ @@ -209,9 +175,7 @@ "R" = ( /obj/structure/flora/bush/reed/style_3, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "T" = ( /obj/structure/atlantis/column/lantern, @@ -226,16 +190,12 @@ /obj/structure/flora/bush/reed/style_3, /mob/living/basic/aquatic/fish/gupper, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "V" = ( /mob/living/basic/aquatic/fish/cod, /obj/effect/overlay/water, -/turf/open/misc/ashplanet/rocky{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/misc/ashplanet/rocky, /area/centcom/tdome/arena/actual) "X" = ( /obj/effect/overlay/water, diff --git a/monkestation/code/modules/ghost_players/arena/maps/two_forts.dmm b/monkestation/code/modules/ghost_players/arena/maps/two_forts.dmm index ea3c06ee5cb5..c2bdb05d8de6 100644 --- a/monkestation/code/modules/ghost_players/arena/maps/two_forts.dmm +++ b/monkestation/code/modules/ghost_players/arena/maps/two_forts.dmm @@ -26,9 +26,7 @@ /area/centcom/tdome/arena/actual) "hA" = ( /obj/structure/flora/bush/reed/style_3, -/turf/open/water{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/water/arena, /area/centcom/tdome/arena/actual) "hL" = ( /obj/effect/turf_decal/siding/wood{ @@ -76,9 +74,7 @@ /area/centcom/tdome/arena/actual) "wZ" = ( /obj/machinery/light/directional/north, -/turf/open/water{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/water/arena, /area/centcom/tdome/arena/actual) "yW" = ( /obj/machinery/light/small/blacklight/directional/west, @@ -94,15 +90,11 @@ /area/centcom/tdome/arena/actual) "BT" = ( /obj/structure/flora/bush/reed/style_2, -/turf/open/water{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/water/arena, /area/centcom/tdome/arena/actual) "Cb" = ( /obj/machinery/light/directional/south, -/turf/open/water{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/water/arena, /area/centcom/tdome/arena/actual) "Cu" = ( /obj/effect/turf_decal/sand/plating, @@ -159,9 +151,7 @@ /turf/open/floor/wood/parquet, /area/centcom/tdome/arena/actual) "VF" = ( -/turf/open/water{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/water/arena, /area/centcom/tdome/arena/actual) "Wh" = ( /obj/effect/turf_decal/sand/plating, @@ -185,9 +175,7 @@ /area/centcom/tdome/arena/actual) "Zu" = ( /obj/structure/flora/bush/reed, -/turf/open/water{ - initial_gas_mix = "o2=22;n2=82;TEMP=293.15" - }, +/turf/open/water/arena, /area/centcom/tdome/arena/actual) (1,1,1) = {" diff --git a/monkestation/code/modules/research/techweb/all_nodes.dm b/monkestation/code/modules/research/techweb/all_nodes.dm index 4e07d6cebf3e..7a491327307b 100644 --- a/monkestation/code/modules/research/techweb/all_nodes.dm +++ b/monkestation/code/modules/research/techweb/all_nodes.dm @@ -207,5 +207,3 @@ design_ids = list("linked_surgery") boost_item_paths = list(/obj/item/organ/internal/cyberimp/brain/linked_surgery) research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) - hidden = TRUE - experimental = TRUE diff --git a/monkestation/code/modules/surgery/organs/augments.dm b/monkestation/code/modules/surgery/organs/augments.dm index 91002d049d0a..8f2ea371e9ce 100644 --- a/monkestation/code/modules/surgery/organs/augments.dm +++ b/monkestation/code/modules/surgery/organs/augments.dm @@ -19,7 +19,7 @@ /obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/on_step_completion(mob/living/user, datum/surgery_step/current_step, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results) SIGNAL_HANDLER - if(CHECK_BITFIELD(organ_flags, ORGAN_FAILING)) + if(organ_flags & ORGAN_FAILING) return var/possible_steps = list() if(current_step.repeatable) @@ -36,8 +36,8 @@ /obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/check_surgery(mob/user, datum/surgery/surgery, mob/patient) SIGNAL_HANDLER - if(CHECK_BITFIELD(organ_flags, ORGAN_FAILING)) - return + if(organ_flags & ORGAN_FAILING) + return FALSE if(surgery.replaced_by in loaded_surgeries) return COMPONENT_CANCEL_SURGERY if(surgery.type in loaded_surgeries) @@ -45,7 +45,7 @@ /obj/item/organ/internal/cyberimp/brain/linked_surgery/on_insert(mob/living/carbon/organ_owner, special) . = ..() - update_surgeries(download_from_held = FALSE, silent = TRUE) + update_surgeries(download_from_held = FALSE) RegisterSignal(organ_owner, COMSIG_SURGERY_STARTING, PROC_REF(check_surgery)) RegisterSignal(organ_owner, COMSIG_MOB_SURGERY_STEP_SUCCESS, PROC_REF(on_step_completion)) @@ -59,7 +59,7 @@ return update_surgeries() -/obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/update_surgeries(download_from_held = TRUE, silent = FALSE) +/obj/item/organ/internal/cyberimp/brain/linked_surgery/proc/update_surgeries(download_from_held = TRUE) var/list/prev_amt = length(loaded_surgeries) for(var/design in linked_techweb.researched_designs) var/datum/design/surgery/surgery_design = SSresearch.techweb_design_by_id(design) @@ -84,8 +84,7 @@ surgeries_to_add |= surgery_design.surgery else if(istype(held_item, /obj/item/disk/nuclear)) // funny joke message - if(!silent) - to_chat(owner, span_warning("Do you want to explode? You can't get surgery data from \the [held_item]!")) + to_chat(owner, span_warning("Do you want to explode? You can't get surgery data from \the [held_item]!")) continue else continue @@ -97,8 +96,6 @@ owner.balloon_alert(owner, "surgery download interrupted!") return loaded_surgeries |= surgeries_to_add - if(silent) - return var/new_amt = length(loaded_surgeries) var/diff = new_amt - prev_amt if(diff) @@ -113,12 +110,24 @@ organ_traits = list(TRAIT_PERFECT_SURGEON) actions_types = null var/list/blocked_surgeries = list( - /datum/surgery/advanced/brainwashing_sleeper, + /datum/surgery/advanced/brainwashing_sleeper, // this one has special handling /datum/surgery/advanced/necrotic_revival, /datum/surgery/organ_extraction ) -/obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect/update_surgeries(download_from_held = TRUE, silent = FALSE) +// Special behavior to allow for sleeper agent surgery to be done if the traitor has the objective +/obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect/check_surgery(mob/user, datum/surgery/surgery, mob/patient) + . = ..() + if(istype(surgery, /datum/surgery/advanced/brainwashing_sleeper)) + var/datum/antagonist/traitor/traitor_datum = user.mind?.has_antag_datum(/datum/antagonist/traitor) + var/list/active_objectives = traitor_datum?.uplink_handler?.active_objectives + if(!length(active_objectives)) + return + if(locate(/datum/traitor_objective/sleeper_protocol) in active_objectives) + return COMPONENT_FORCE_SURGERY + + +/obj/item/organ/internal/cyberimp/brain/linked_surgery/perfect/update_surgeries(download_from_held = TRUE) loaded_surgeries.Cut() for(var/datum/surgery/surgery as() in GLOB.surgeries_list) if(surgery.type in blocked_surgeries) diff --git a/monkestation/code/modules/uplink/uplink_items/device_tools.dm b/monkestation/code/modules/uplink/uplink_items/device_tools.dm index 3ccfc94cb441..bc0776cbb196 100644 --- a/monkestation/code/modules/uplink/uplink_items/device_tools.dm +++ b/monkestation/code/modules/uplink/uplink_items/device_tools.dm @@ -3,3 +3,12 @@ /datum/uplink_item/device_tools/rad_laser surplus = 40 + +/datum/uplink_item/device_tools/hacked_linked_surgery + name = "Syndicate Surgery Implant" + desc = "A powerful brain implant, capable of uploading perfect, forbidden surgical knowledge to its users mind, \ + allowing them to do just about any surgery, anywhere, without making any (unintentional) mistakes. \ + Comes with a syndicate autosurgeon for immediate self-application." + cost = 12 + item = /obj/item/autosurgeon/syndicate/hacked_linked_surgery + surplus = 50 diff --git a/monkestation/code/modules/uplink/uplink_items/job.dm b/monkestation/code/modules/uplink/uplink_items/job.dm index f912bc23cd5f..216d4cb5987d 100644 --- a/monkestation/code/modules/uplink/uplink_items/job.dm +++ b/monkestation/code/modules/uplink/uplink_items/job.dm @@ -11,13 +11,3 @@ /datum/uplink_item/role_restricted/modified_syringe_gun surplus = 50 - -/datum/uplink_item/role_restricted/hacked_linked_surgery - name = "Syndicate Surgery Implant" - desc = "A powerful brain implant, capable of uploading perfect, forbidden surgical knowledge to its users mind, \ - allowing them to do just about any surgery, anywhere, without making any (unintentional) mistakes. \ - Comes with a syndicate autosurgeon for immediate self-application." - cost = 12 - item = /obj/item/autosurgeon/syndicate/hacked_linked_surgery - restricted_roles = list(JOB_CHIEF_MEDICAL_OFFICER, JOB_MEDICAL_DOCTOR, JOB_PARAMEDIC, JOB_ROBOTICIST) - surplus = 50 diff --git a/tgstation.dme b/tgstation.dme index 1a20274810b6..b9cf0383be47 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1568,6 +1568,7 @@ #include "code\datums\status_effects\debuffs\confusion.dm" #include "code\datums\status_effects\debuffs\debuffs.dm" #include "code\datums\status_effects\debuffs\dizziness.dm" +#include "code\datums\status_effects\debuffs\dna_transformation.dm" #include "code\datums\status_effects\debuffs\drowsiness.dm" #include "code\datums\status_effects\debuffs\drugginess.dm" #include "code\datums\status_effects\debuffs\drunk.dm"