diff --git a/code/__DEFINES/cleaning.dm b/code/__DEFINES/cleaning.dm
index 1c0f65cbdc8e..7eb4a665ad40 100644
--- a/code/__DEFINES/cleaning.dm
+++ b/code/__DEFINES/cleaning.dm
@@ -1,18 +1,19 @@
-//Cleaning tool strength
-// 1 is also a valid cleaning strength but completely unused so left undefined
-#define CLEAN_WEAK 2
-/// Acceptable tools
-#define CLEAN_MEDIUM 3
-/// Industrial strength
-#define CLEAN_STRONG 4
-/// Cleaning strong enough your granny would be proud
-#define CLEAN_IMPRESSIVE 5
-/// Cleans things spotless down to the atomic structure
-#define CLEAN_GOD 6
-/// Never cleaned
-#define CLEAN_NEVER 7
+// Cleaning flags
-//How strong things have to be to wipe forensic evidence...
-#define CLEAN_STRENGTH_FINGERPRINTS CLEAN_IMPRESSIVE
-#define CLEAN_STRENGTH_BLOOD CLEAN_WEAK
-#define CLEAN_STRENGTH_FIBERS CLEAN_IMPRESSIVE
+// Different kinds of things that can be cleaned.
+// Use these when overriding the wash proc or registering for the clean signals to check if your thing should be cleaned
+#define CLEAN_TYPE_BLOOD (1 << 0)
+#define CLEAN_TYPE_RUNES (1 << 1)
+#define CLEAN_TYPE_FINGERPRINTS (1 << 2)
+#define CLEAN_TYPE_FIBERS (1 << 3)
+#define CLEAN_TYPE_RADIATION (1 << 4)
+#define CLEAN_TYPE_DISEASE (1 << 5)
+#define CLEAN_TYPE_WEAK (1 << 6) // Special type, add this flag to make some cleaning processes non-instant. Currently only used for showers when removing radiation.
+#define CLEAN_TYPE_PAINT (1 << 7)
+
+// Different cleaning methods.
+// Use these when calling the wash proc for your cleaning apparatus
+#define CLEAN_WASH (CLEAN_TYPE_BLOOD | CLEAN_TYPE_RUNES | CLEAN_TYPE_DISEASE)
+#define CLEAN_SCRUB (CLEAN_WASH | CLEAN_TYPE_FINGERPRINTS | CLEAN_TYPE_FIBERS | CLEAN_TYPE_PAINT)
+#define CLEAN_RAD CLEAN_TYPE_RADIATION
+#define CLEAN_ALL (ALL & ~CLEAN_TYPE_WEAK)
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 3934f95f0eec..9b408c4060bb 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -60,18 +60,18 @@
// /atom signals
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
- #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
+#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob)
#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides)
//Positions for overrides list
- #define EXAMINE_POSITION_ARTICLE 1
- #define EXAMINE_POSITION_BEFORE 2
+#define EXAMINE_POSITION_ARTICLE 1
+#define EXAMINE_POSITION_BEFORE 2
//End positions
- #define COMPONENT_EXNAME_CHANGED 1
+#define COMPONENT_EXNAME_CHANGED 1
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom)
#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
- #define COMPONENT_ATOM_BLOCK_EXIT 1
+#define COMPONENT_ATOM_BLOCK_EXIT 1
#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc)
#define COMSIG_ATOM_BUMPED "atom_bumped" //from base of atom/Bumped(): (/atom/movable)
#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
@@ -92,21 +92,21 @@
#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted)
#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities)
#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): ()
- #define COMPONENT_BLOCK_RADIATION 1
+#define COMPONENT_BLOCK_RADIATION 1
#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength)
- #define COMPONENT_BLOCK_CONTAMINATION 1
+#define COMPONENT_BLOCK_CONTAMINATION 1
#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width)
#define COMPONENT_RAD_WAVE_HANDLED 1
#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next)
- #define COMPONENT_BLOCK_REACH 1
+#define COMPONENT_BLOCK_REACH 1
#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin)
- #define COMPONENT_BLOCK_TELEPORT 1
+#define COMPONENT_BLOCK_TELEPORT 1
/////////////////
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user)
- #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
+#define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
/////////////////
#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area)
@@ -135,12 +135,12 @@
// /atom/movable signals
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" //from base of atom/movable/Moved(): (/atom)
- #define COMPONENT_MOVABLE_BLOCK_PRE_MOVE 1
+#define COMPONENT_MOVABLE_BLOCK_PRE_MOVE 1
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable)
- #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1
+#define COMPONENT_MOVABLE_BLOCK_UNCROSS 1
#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable)
#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom)
#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
@@ -148,18 +148,18 @@
#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force)
#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force)
#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args)
- #define COMPONENT_CANCEL_THROW 1
+#define COMPONENT_CANCEL_THROW 1
#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z)
#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded" //called when the movable is placed in an unaccessible area, used for stationloving: ()
#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (proc args list(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode))
- #define HEARING_MESSAGE 1
- #define HEARING_SPEAKER 2
-// #define HEARING_LANGUAGE 3
- #define HEARING_RAW_MESSAGE 4
+#define HEARING_MESSAGE 1
+#define HEARING_SPEAKER 2
+//#define HEARING_LANGUAGE 3
+#define HEARING_RAW_MESSAGE 4
/* #define HEARING_RADIO_FREQ 5
- #define HEARING_SPANS 6
- #define HEARING_MESSAGE_MODE 7 */
+#define HEARING_SPANS 6
+#define HEARING_MESSAGE_MODE 7 */
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" //Called when the movable's glide size is updated: (new_glide_size)
@@ -177,10 +177,10 @@
#define COMSIG_MOB_LOGOUT "mob_logout"
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
#define COMSIG_MOB_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params)
- #define COMSIG_MOB_CANCEL_CLICKON 1
+#define COMSIG_MOB_CANCEL_CLICKON 1
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources)
- #define COMPONENT_BLOCK_MAGIC 1
+#define COMPONENT_BLOCK_MAGIC 1
#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): ()
#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of
#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user)
@@ -192,15 +192,15 @@
#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/target)
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): ()
- #define COMPONENT_UPPERCASE_SPEECH 1
+#define COMPONENT_UPPERCASE_SPEECH 1
// used to access COMSIG_MOB_SAY argslist
- #define SPEECH_MESSAGE 1
+#define SPEECH_MESSAGE 1
// #define SPEECH_BUBBLE_TYPE 2
- #define SPEECH_SPANS 3
+#define SPEECH_SPANS 3
/* #define SPEECH_SANITIZE 4
- #define SPEECH_LANGUAGE 5
- #define SPEECH_IGNORE_SPAM 6
- #define SPEECH_FORCED 7 */
+#define SPEECH_LANGUAGE 5
+#define SPEECH_IGNORE_SPAM 6
+#define SPEECH_FORCED 7 */
// /mob/living signals
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
@@ -219,7 +219,7 @@
#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize" //from base of mob/living/Immobilize() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore)
- #define COMPONENT_NO_STUN 1 //For all of them
+#define COMPONENT_NO_STUN 1 //For all of them
// /mob/living/carbon signals
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
@@ -227,7 +227,7 @@
// /mob/living/simple_animal/hostile signals
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
- #define COMPONENT_HOSTILE_NO_ATTACK 1
+#define COMPONENT_HOSTILE_NO_ATTACK 1
// /obj signals
#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)
@@ -241,11 +241,11 @@
// /obj/item signals
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
- #define COMPONENT_NO_INTERACT 1
+#define COMPONENT_NO_INTERACT 1
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
- #define COMPONENT_NO_ATTACK_OBJ 1
+#define COMPONENT_NO_ATTACK_OBJ 1
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
- #define COMPONENT_NO_ATTACK 1
+#define COMPONENT_NO_ATTACK 1
#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
@@ -253,7 +253,7 @@
#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval" //called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/targeted/summonitem/cast() : (mob/user)
- #define COMPONENT_BLOCK_MARK_RETRIEVAL 1
+#define COMPONENT_BLOCK_MARK_RETRIEVAL 1
#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
// /obj/item/clothing signals
@@ -263,19 +263,19 @@
// /obj/item/implant signals
#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args)
- #define COMPONENT_STOP_IMPLANTING 1
+#define COMPONENT_STOP_IMPLANTING 1
#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
//#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both
- #define COMPONENT_DELETE_NEW_IMPLANT 2
- #define COMPONENT_DELETE_OLD_IMPLANT 4
+#define COMPONENT_DELETE_NEW_IMPLANT 2
+#define COMPONENT_DELETE_OLD_IMPLANT 4
#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
//This uses all return values of COMSIG_IMPLANT_OTHER
// /obj/item/pda signals
#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
- #define COMPONENT_STOP_RINGTONE_CHANGE 1
+#define COMPONENT_STOP_RINGTONE_CHANGE 1
#define COMSIG_PDA_CHECK_DETONATE "pda_check_detonate"
- #define COMPONENT_PDA_NO_DETONATE 1
+#define COMPONENT_PDA_NO_DETONATE 1
// /obj/item/radio signals
#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args)
@@ -306,6 +306,11 @@
#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
+//Creamed
+
+///called when you wash your face at a sink: (num/strength)
+#define COMSIG_COMPONENT_CLEAN_FACE_ACT "clean_face_act"
+
//Food
#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
@@ -333,8 +338,8 @@
#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
- #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
- #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
+#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
+#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
// /datum/component/storage signals
@@ -354,7 +359,7 @@
// /datum/action signals
#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action)
- #define COMPONENT_ACTION_BLOCK_TRIGGER 1
+#define COMPONENT_ACTION_BLOCK_TRIGGER 1
/*******Non-Signal Component Related Defines*******/
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index bc3a69760247..c51cb4aa953a 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -45,6 +45,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define ADMIN_SPAWNED_1 (1<<15)
/// should not get harmed if this gets caught by an explosion?
#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16)
+/// should the contents of this atom be acted upon
+#define RAD_PROTECT_CONTENTS_1 (1 << 17)
+/// should this object be allowed to be contaminated
+#define RAD_NO_CONTAMINATE_1 (1 << 18)
//turf-only flags
#define NOJAUNT_1 (1<<0)
@@ -128,10 +132,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL)
#define MOBILITY_FLAGS_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
-// radiation
-#define RAD_PROTECT_CONTENTS (1<<0)
-#define RAD_NO_CONTAMINATE (1<<1)
-
//alternate appearance flags
#define AA_TARGET_SEE_APPEARANCE (1<<0)
#define AA_MATCH_TARGET_OVERLAYS (1<<1)
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index d75b8e5fb9fc..a08f5df7423d 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -214,7 +214,7 @@ GLOBAL_LIST_INIT(heavyfootmob, typecacheof(list(
#define ismecha(A) (istype(A, /obj/mecha))
-#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
+#define ismopable(A) (A.layer <= HIGH_SIGIL_LAYER) //If something can be cleaned by floor-cleaning devices such as mops or clean bots
#define isorgan(A) (istype(A, /obj/item/organ))
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 1f8b38ffae24..0879084f04c9 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -91,6 +91,7 @@
#define TRAIT_RESISTLOWPRESSURE "resist_low_pressure"
#define TRAIT_BOMBIMMUNE "bomb_immunity"
#define TRAIT_RADIMMUNE "rad_immunity"
+#define TRAIT_GENELESS "geneless"
#define TRAIT_VIRUSIMMUNE "virus_immunity"
#define TRAIT_PIERCEIMMUNE "pierce_immunity"
#define TRAIT_NODISMEMBER "dismember_immunity"
diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm
index 0617c5d3457d..f0e51ee0b223 100644
--- a/code/__DEFINES/vv.dm
+++ b/code/__DEFINES/vv.dm
@@ -19,3 +19,56 @@
#define VV_RESTORE_DEFAULT "Restore to Default"
#define VV_MARKED_DATUM "Marked Datum"
#define VV_BITFIELD "Bitfield"
+#define VV_TEXT_LOCATE "Custom Reference Locate"
+#define VV_PROCCALL_RETVAL "Return Value of Proccall"
+#define VV_NORMAL_LIST_NO_EXPAND_THRESHOLD 50
+#define VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD 150
+//#define IS_VALID_ASSOC_KEY(V) (istext(V) || ispath(V) || isdatum(V) || islist(V))
+#define IS_VALID_ASSOC_KEY(V) (!isnum(V)) //hhmmm..
+//General helpers
+#define VV_HREF_TARGET_INTERNAL(target, href_key) "?_src_=vars;[HrefToken()];[href_key]=TRUE;[VV_HK_TARGET]=[REF(target)]"
+#define VV_HREF_TARGETREF_INTERNAL(targetref, href_key) "?_src_=vars;[HrefToken()];[href_key]=TRUE;[VV_HK_TARGET]=[targetref]"
+#define VV_HREF_TARGET(target, href_key, text) "[text]"
+#define VV_HREF_TARGETREF(targetref, href_key, text) "[text]"
+#define VV_HREF_TARGET_1V(target, href_key, text, varname) "[text]" //for stuff like basic varedits, one variable
+#define VV_HREF_TARGETREF_1V(targetref, href_key, text, varname) "[text]"
+#define GET_VV_TARGET locate(href_list[VV_HK_TARGET])
+#define GET_VV_VAR_TARGET href_list[VV_HK_VARNAME]
+//Helper for getting something to vv_do_topic in general
+#define VV_TOPIC_LINK(datum, href_key, text) "text"
+//Helpers for vv_get_dropdown()
+#define VV_DROPDOWN_OPTION(href_key, name) . += ""
+// VV HREF KEYS
+#define VV_HK_TARGET "target"
+#define VV_HK_VARNAME "targetvar" //name or index of var for 1 variable targetting hrefs.
+// vv_do_list() keys
+#define VV_HK_LIST_ADD "listadd"
+#define VV_HK_LIST_EDIT "listedit"
+#define VV_HK_LIST_CHANGE "listchange"
+#define VV_HK_LIST_REMOVE "listremove"
+#define VV_HK_LIST_ERASE_NULLS "listnulls"
+#define VV_HK_LIST_ERASE_DUPES "listdupes"
+#define VV_HK_LIST_SHUFFLE "listshuffle"
+#define VV_HK_LIST_SET_LENGTH "listlen"
+// vv_do_basic() keys
+#define VV_HK_BASIC_EDIT "datumedit"
+#define VV_HK_BASIC_CHANGE "datumchange"
+#define VV_HK_BASIC_MASSEDIT "massedit"
+// /datum
+#define VV_HK_DELETE "delete"
+#define VV_HK_EXPOSE "expose"
+#define VV_HK_CALLPROC "proc_call"
+#define VV_HK_MARK "mark"
+#define VV_HK_ADDCOMPONENT "addcomponent"
+#define VV_HK_MODIFY_TRAITS "modtraits"
+#define VV_HK_VIEW_REFERENCES "viewreferences"
+// /atom
+#define VV_HK_MODIFY_TRANSFORM "atom_transform"
+#define VV_HK_ADD_REAGENT "addreagent"
+#define VV_HK_TRIGGER_EMP "empulse"
+#define VV_HK_TRIGGER_EXPLOSION "explode"
+#define VV_HK_AUTO_RENAME "auto_rename"
+#define VV_HK_RADIATE "radiate"
+
+// /obj
+#define VV_HK_OSAY "osay"
diff --git a/code/__HELPERS/radiation.dm b/code/__HELPERS/radiation.dm
index 0ce8ab07c716..593bdf8c5a18 100644
--- a/code/__HELPERS/radiation.dm
+++ b/code/__HELPERS/radiation.dm
@@ -20,7 +20,7 @@
if(ignored_things[thing.type])
continue
. += thing
- if((thing.rad_flags & RAD_PROTECT_CONTENTS) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION))
+ if((thing.flags_1 & RAD_PROTECT_CONTENTS_1) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION))
continue
processing_list += thing.contents
@@ -45,3 +45,14 @@
var/turf/_source_T = isturf(source) ? source : get_turf(source)
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)] ")
return TRUE
+
+/proc/get_rad_contamination(atom/location)
+ var/rad_strength = 0
+ for(var/i in get_rad_contents(location)) // Yes it's intentional that you can't detect radioactive things under rad protection. Gives traitors a way to hide their glowing green rocks.
+ var/atom/thing = i
+ if(!thing)
+ continue
+ var/datum/component/radioactive/radiation = thing.GetComponent(/datum/component/radioactive)
+ if(radiation && rad_strength < radiation.strength)
+ rad_strength = radiation.strength
+ return rad_strength
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 3ab6fc63666a..0ab7acec900f 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -138,6 +138,9 @@ GLOBAL_LIST_INIT(bitfields, list(
"TESLA_IGNORE_1" = TESLA_IGNORE_1,
"INITIALIZED_1" = INITIALIZED_1,
"ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1,
+ "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1,
+ "RAD_PROTECT_CONTENTS_1" = RAD_PROTECT_CONTENTS_1,
+ "RAD_NO_CONTAMINATE_1" = RAD_NO_CONTAMINATE_1,
),
"clothing_flags" = list(
"LAVAPROTECT" = LAVAPROTECT,
@@ -176,10 +179,6 @@ GLOBAL_LIST_INIT(bitfields, list(
"STORAGE" = MOBILITY_STORAGE,
"PULL" = MOBILITY_PULL,
),
- "rad_flags" = list(
- "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS,
- "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE,
- ),
"disease_flags" = list (
"CURABLE" = CURABLE,
"CAN_CARRY" = CAN_CARRY,
@@ -195,4 +194,4 @@ GLOBAL_LIST_INIT(bitfields, list(
"VIS_UNDERLAY" = VIS_UNDERLAY,
"VIS_HIDE" = VIS_HIDE
)
- ))
\ No newline at end of file
+ ))
diff --git a/code/datums/components/cleaning.dm b/code/datums/components/cleaning.dm
index ef0d9c624a33..256d4385421e 100644
--- a/code/datums/components/cleaning.dm
+++ b/code/datums/components/cleaning.dm
@@ -6,34 +6,23 @@
return COMPONENT_INCOMPATIBLE
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Clean)
-/datum/component/cleaning/proc/Clean()
- var/atom/movable/AM = parent
+/datum/component/cleaning/proc/Clean(datum/source)
+ var/atom/movable/AM = source
var/turf/tile = AM.loc
if(!isturf(tile))
return
- SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ tile.wash(CLEAN_WASH)
for(var/A in tile)
- if(is_cleanable(A))
- qdel(A)
- else if(istype(A, /obj/item))
+ // Clean small items that are lying on the ground
+ if(isitem(A))
var/obj/item/I = A
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(ismob(I.loc))
- var/mob/M = I.loc
- M.regenerate_icons()
+ if(I.w_class <= WEIGHT_CLASS_SMALL && !ismob(I.loc))
+ I.wash(CLEAN_WASH)
+ // Clean humans that are lying down
else if(ishuman(A))
var/mob/living/carbon/human/cleaned_human = A
if(!(cleaned_human.mobility_flags & MOBILITY_STAND))
- if(cleaned_human.head)
- SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.wear_suit)
- SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- else if(cleaned_human.w_uniform)
- SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.shoes)
- SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- cleaned_human.wash_cream()
+ cleaned_human.wash(CLEAN_WASH)
cleaned_human.regenerate_icons()
to_chat(cleaned_human, "[AM] cleans your face!")
diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm
index 8fb3405af0d6..3b60b92507cf 100644
--- a/code/datums/components/decal.dm
+++ b/code/datums/components/decal.dm
@@ -7,7 +7,7 @@
var/first_dir // This only stores the dir arg from init
-/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_NEVER, _color, _layer=TURF_LAYER, _description, _alpha=255)
+/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=FALSE, _color, _layer=TURF_LAYER, _description, _alpha=255)
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
return COMPONENT_INCOMPATIBLE
first_dir = _dir
@@ -19,7 +19,7 @@
/datum/component/decal/RegisterWithParent()
if(first_dir)
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
- if(cleanable != CLEAN_NEVER)
+ if(cleanable != FALSE)
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
if(description)
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
@@ -67,9 +67,10 @@
pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir))
apply()
-/datum/component/decal/proc/clean_react(datum/source, strength)
- if(strength >= cleanable)
+/datum/component/decal/proc/clean_react(datum/source, clean_types)
+ if(clean_types & cleanable)
qdel(src)
+ return TRUE
/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list)
examine_list += description
diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm
index 3114ddb24e9e..d2c5804222e1 100644
--- a/code/datums/components/decals/blood.dm
+++ b/code/datums/components/decals/blood.dm
@@ -1,7 +1,7 @@
/datum/component/decal/blood
dupe_mode = COMPONENT_DUPE_UNIQUE
-/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
+/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_TYPE_BLOOD, _color, _layer=ABOVE_OBJ_LAYER)
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
. = ..()
diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm
index f682308cae4c..498234cf10f1 100644
--- a/code/datums/components/forensics.dm
+++ b/code/datums/components/forensics.dm
@@ -51,13 +51,16 @@
fibers = null
return TRUE
-/datum/component/forensics/proc/clean_act(datum/source, strength)
- if(strength >= CLEAN_STRENGTH_FINGERPRINTS)
+/datum/component/forensics/proc/clean_act(datum/source, clean_types)
+ if(clean_types & CLEAN_TYPE_FINGERPRINTS)
wipe_fingerprints()
- if(strength >= CLEAN_STRENGTH_BLOOD)
+ . = TRUE
+ if(clean_types & CLEAN_TYPE_BLOOD)
wipe_blood_DNA()
- if(strength >= CLEAN_STRENGTH_FIBERS)
+ . = TRUE
+ if(clean_types & CLEAN_TYPE_FIBERS)
wipe_fibers()
+ . = TRUE
/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text)
if(!length(_fingerprints))
diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm
index 930c72d590f7..0c4ab27af12f 100644
--- a/code/datums/components/infective.dm
+++ b/code/datums/components/infective.dm
@@ -2,7 +2,7 @@
dupe_mode = COMPONENT_DUPE_ALLOWED
var/list/datum/disease/diseases //make sure these are the static, non-processing versions!
var/expire_time
- var/min_clean_strength = CLEAN_WEAK
+ var/required_clean_types = CLEAN_TYPE_DISEASE
/datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in)
if(islist(_diseases))
@@ -34,9 +34,10 @@
eater.ForceContractDisease(V)
try_infect(feeder, BODY_ZONE_L_ARM)
-/datum/component/infective/proc/clean(datum/source, clean_strength)
- if(clean_strength >= min_clean_strength)
+/datum/component/infective/proc/clean(datum/source, clean_types)
+ if(clean_types & required_clean_types)
qdel(src)
+ return TRUE
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
if(isliving(M))
diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm
index 697cb19088e1..8f5e5f46d3ae 100644
--- a/code/datums/components/radioactive.dm
+++ b/code/datums/components/radioactive.dm
@@ -7,7 +7,6 @@
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/source
-
var/hl3_release_date //the half-life measured in ticks
var/strength
var/can_contaminate
@@ -17,18 +16,16 @@
source = _source
hl3_release_date = _half_life
can_contaminate = _can_contaminate
-
if(istype(parent, /atom))
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/rad_examine)
+ RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/rad_clean)
if(istype(parent, /obj/item))
RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/rad_attack)
RegisterSignal(parent, COMSIG_ITEM_ATTACK_OBJ, .proc/rad_attack)
else
return COMPONENT_INCOMPATIBLE
-
if(strength > RAD_MINIMUM_CONTAMINATION)
SSradiation.warn(src)
-
//Let's make er glow
//This relies on parent not being a turf or something. IF YOU CHANGE THAT, CHANGE THIS
var/atom/movable/master = parent
@@ -46,11 +43,11 @@
if(!prob(50))
return
radiation_pulse(parent, strength, RAD_DISTANCE_COEFFICIENT*2, FALSE, can_contaminate)
-
if(!hl3_release_date)
return
strength -= strength / hl3_release_date
if(strength <= RAD_BACKGROUND_RADIATION)
+ qdel(src)
return PROCESS_KILL
/datum/component/radioactive/proc/glow_loop(atom/movable/master)
@@ -70,21 +67,22 @@
else
strength = max(strength, arguments[1])
-/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, atom/thing) //Yogs -- Mirrored!!
+/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, atom/thing)
var/atom/master = parent
var/list/out = list()
if(get_dist(master, user) <= 1)
out += "The air around [master] feels warm"
switch(strength)
if(RAD_AMOUNT_LOW to RAD_AMOUNT_MEDIUM)
- out += "[out ? " and it " : "[master] "]feels weird to look at."
+ out += "[length(out) ? " and it " : "[master] "]feels weird to look at."
if(RAD_AMOUNT_MEDIUM to RAD_AMOUNT_HIGH)
- out += "[out ? " and it " : "[master] "]seems to be glowing a bit."
+ out += "[length(out) ? " and it " : "[master] "]seems to be glowing a bit."
if(RAD_AMOUNT_HIGH to INFINITY) //At this level the object can contaminate other objects
- out += "[out ? " and it " : "[master] "]hurts to look at."
- else
- out += "."
- to_chat(user, out.Join())
+ out += "[length(out) ? " and it " : "[master] "]hurts to look at."
+ if(!LAZYLEN(out))
+ return
+ out += "."
+ to_chat(user, "[out.Join()]")
/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user)
radiation_pulse(parent, strength/20)
@@ -93,6 +91,21 @@
return
strength -= strength / hl3_release_date
+/datum/component/radioactive/proc/rad_clean(datum/source, clean_types)
+ if(QDELETED(src))
+ return
+
+ if(!(clean_types & CLEAN_TYPE_RADIATION))
+ return
+
+ if(!(clean_types & CLEAN_TYPE_WEAK))
+ qdel(src)
+ return
+
+ strength = max(0, (strength - (RAD_BACKGROUND_RADIATION * 2)))
+ if(strength <= RAD_BACKGROUND_RADIATION)
+ qdel(src)
+
#undef RAD_AMOUNT_LOW
#undef RAD_AMOUNT_MEDIUM
#undef RAD_AMOUNT_HIGH
diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm
index 8257a9e34f59..4b5c1aa5c909 100644
--- a/code/datums/components/thermite.dm
+++ b/code/datums/components/thermite.dm
@@ -71,6 +71,7 @@
/datum/component/thermite/proc/clean_react(datum/source, strength)
//Thermite is just some loose powder, you could probably clean it with your hands. << todo?
qdel(src)
+ return TRUE
/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 25fd68004d29..88b1cce6cfac 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -1033,6 +1033,12 @@
src.cmd_admin_explosion(A)
+ else if(href_list["radiate"] && check_rights(R_FUN))
+ var/atom/A = locate(href_list["radiate"])
+ var/strength = input(usr, "Choose the radiation strength.", "Choose the strength.") as num|null
+ if(!isnull(strength))
+ A.AddComponent(/datum/component/radioactive, strength, src)
+
else if(href_list["emp"])
if(!check_rights(R_FUN))
return
diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm
index 4547cd367233..964ed0aaf361 100644
--- a/code/datums/radiation_wave.dm
+++ b/code/datums/radiation_wave.dm
@@ -109,6 +109,8 @@
))
if(!can_contaminate || blacklisted[thing.type])
continue
+ if(thing.flags_1 & RAD_NO_CONTAMINATE_1 || SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION)
+ continue
if(prob(contamination_chance)) // Only stronk rads get to have little baby rads
if(SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION)
continue
diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm
index c6b9338c291f..707b6bca398f 100644
--- a/code/datums/weather/weather_types/radiation_storm.dm
+++ b/code/datums/weather/weather_types/radiation_storm.dm
@@ -33,7 +33,7 @@
if(prob(40))
if(ishuman(L))
var/mob/living/carbon/human/H = L
- if(H.dna && !HAS_TRAIT(H, TRAIT_RADIMMUNE))
+ if(H.dna && !HAS_TRAIT(H, TRAIT_GENELESS))
if(prob(max(0,100-resist)))
H.randmuti()
if(prob(50))
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 7b94d78c55db..9f0b696056dc 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -64,8 +64,6 @@
//List of datums orbiting this atom
var/datum/component/orbiter/orbiters
- /// Will move to flags_1 when i can be arsed to (2019, has not done so)
- var/rad_flags = NONE
/// Radiation insulation types
var/rad_insulation = RAD_NO_INSULATION
@@ -603,6 +601,24 @@
/atom/proc/wash_cream()
return TRUE
+/**
+ * Wash this atom
+ *
+ * This will clean it off any temporary stuff like blood. Override this in your item to add custom cleaning behavior.
+ * Returns true if any washing was necessary and thus performed
+ * Arguments:
+ * * clean_types: any of the CLEAN_ constants
+ */
+/atom/proc/wash(clean_types)
+ . = FALSE
+ if(SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, clean_types))
+ . = TRUE
+
+ // Basically "if has washable coloration"
+ if(length(atom_colours) >= WASHABLE_COLOUR_PRIORITY && atom_colours[WASHABLE_COLOUR_PRIORITY])
+ remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
+ return TRUE
+
///Is this atom in space
/atom/proc/isinspace()
if(isspaceturf(get_turf(src)))
@@ -819,8 +835,7 @@
///Removes an instance of colour_type from the atom's atom_colours list
/atom/proc/remove_atom_colour(colour_priority, coloration)
if(!atom_colours)
- atom_colours = list()
- atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently.
+ return
if(colour_priority > atom_colours.len)
return
if(coloration && atom_colours[colour_priority] != coloration)
@@ -828,13 +843,11 @@
atom_colours[colour_priority] = null
update_atom_colour()
-
-///Resets the atom's color to null, and then sets it to the highest priority colour available
/atom/proc/update_atom_colour()
- if(!atom_colours)
- atom_colours = list()
- atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently.
+///Resets the atom's color to null, and then sets it to the highest priority colour available
color = null
+ if(!atom_colours)
+ return
for(var/C in atom_colours)
if(islist(C))
var/list/L = C
@@ -879,6 +892,7 @@
.["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=[REF(src)]"
.["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]"
.["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]"
+ .["Radiate"] = "?_src_=vars;[HrefToken()];radiate=[REF(src)]"
///Where atoms should drop if taken from this atom
/atom/proc/drop_location()
@@ -1103,6 +1117,12 @@
arguments -= "priority"
filters += filter(arglist(arguments))
+/obj/item/update_filters()
+ . = ..()
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.UpdateButtonIcon()
+
/atom/movable/proc/get_filter(name)
if(filter_data && filter_data[name])
return filters[filter_data.Find(name)]
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index f71bff6e936a..bd93664bc2cc 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -1493,7 +1493,7 @@
// this DNA can not be bad
// is done via radiation bursts, so radiation immune carbons are not viable
// And the DNA Scanner itself must have a valid scan level
- if(scanner_occupant.has_dna() && !HAS_TRAIT(scanner_occupant, TRAIT_RADIMMUNE) && !HAS_TRAIT(scanner_occupant, TRAIT_BADDNA) || (connected_scanner.scan_level == 3))
+ if(scanner_occupant.has_dna() && !HAS_TRAIT(scanner_occupant, TRAIT_GENELESS) && !HAS_TRAIT(scanner_occupant, TRAIT_BADDNA) || (connected_scanner.scan_level == 3))
return TRUE
return FALSE
@@ -1987,4 +1987,4 @@
#undef SEARCH_OCCUPANT
#undef SEARCH_STORED
#undef SEARCH_DISKETTE
-#undef SEARCH_ADV_INJ
\ No newline at end of file
+#undef SEARCH_ADV_INJ
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index e4e15b40df13..894570c53203 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -107,7 +107,7 @@
var/list/bolt_log //yogs - Who can it be bolting all my doors? Go away, don't come down here no more.
var/list/shocking_log //yogs - who electrified this door.
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_MEDIUM_INSULATION
var/static/list/airlock_overlays = list()
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 3820145f554b..615d34d9feab 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -272,11 +272,9 @@
if(occupant)
things_to_clear += occupant
things_to_clear += occupant.GetAllContents()
- for(var/atom/movable/AM in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
- SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
- var/datum/component/radioactive/contamination = AM.GetComponent(/datum/component/radioactive)
- if(contamination)
- qdel(contamination)
+ for(var/am in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
+ var/atom/movable/dirty_movable = am
+ dirty_movable.wash(CLEAN_ALL)
open_machine(FALSE)
if(occupant)
dump_contents()
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 6388bb9da1bd..20ec0d437b1e 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -10,10 +10,6 @@
var/obj/item/color_source
var/max_wash_capacity = 5
-/obj/machinery/washing_machine/ComponentInitialize()
- . = ..()
- RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_blood)
-
/obj/machinery/washing_machine/examine(mob/user)
. = ..()
. += "Alt-click it to start a wash cycle."
@@ -56,15 +52,17 @@
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
-/obj/machinery/washing_machine/proc/clean_blood()
- if(!busy)
+/obj/machinery/washing_machine/wash(clean_types)
+ . = ..()
+ if(!busy && bloody_mess && (clean_types & CLEAN_TYPE_BLOOD))
bloody_mess = FALSE
update_icon()
+ . = TRUE
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
- SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ AM.wash(CLEAN_WASH)
AM.machine_wash(src)
busy = FALSE
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 3e8c887ba1c4..d956ef5928b4 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -30,7 +30,7 @@
return TRUE
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
+ if((istype(W, /obj/item/reagent_containers/glass) && !istype(W, /obj/item/reagent_containers/glass/rag)) || istype(W, /obj/item/reagent_containers/food/drinks))
if(src.reagents && W.reagents)
. = 1 //so the containers don't splash their content on the src while scooping.
if(!src.reagents.total_volume)
@@ -99,3 +99,8 @@
return bloodiness
else
return 0
+
+/obj/effect/decal/cleanable/wash(clean_types)
+ ..()
+ qdel(src)
+ return TRUE
diff --git a/code/game/objects/effects/decals/decal.dm b/code/game/objects/effects/decals/decal.dm
index 803b7250801f..0cacc65c35cb 100644
--- a/code/game/objects/effects/decals/decal.dm
+++ b/code/game/objects/effects/decals/decal.dm
@@ -45,4 +45,4 @@
var/turf/T = loc
if(!istype(T)) //you know this will happen somehow
CRASH("Turf decal initialized in an object/nullspace")
- T.AddComponent(/datum/component/decal, icon, icon_state, dir, CLEAN_NEVER, color, null, null, alpha)
+ T.AddComponent(/datum/component/decal, icon, icon_state, dir, FALSE, color, null, null, alpha)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index bb9aedb7e0e7..bc785a1362b4 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -815,3 +815,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
///Returns the temperature of src. If you want to know if an item is hot use this proc.
/obj/item/proc/get_temperature()
return heat
+
+// Update icons if this is being carried by a mob
+/obj/item/wash(clean_types)
+ . = ..()
+
+ if(ismob(loc))
+ var/mob/mob_loc = loc
+ mob_loc.regenerate_icons()
diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm
index f7e4bce6633a..8f79e18f5ac5 100644
--- a/code/game/objects/items/clown_items.dm
+++ b/code/game/objects/items/clown_items.dm
@@ -118,10 +118,8 @@
user.visible_message("[user] begins to clean \the [target.name] with [src]...", "You begin to clean \the [target.name] with [src]...")
if(do_after(user, src.cleanspeed, target = target))
to_chat(user, "You clean \the [target.name].")
- for(var/obj/effect/decal/cleanable/C in target)
- qdel(C)
+ target.wash(CLEAN_SCRUB)
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
target.wash_cream()
decreaseUses(user)
return
@@ -203,4 +201,4 @@
name = "Canned Laughter"
desc = "Just looking at this makes you want to giggle."
icon_state = "laughter"
- list_reagents = list(/datum/reagent/consumable/laughter = 50)
\ No newline at end of file
+ list_reagents = list(/datum/reagent/consumable/laughter = 50)
diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm
index fb5db099a58e..c4fb758b1c79 100644
--- a/code/game/objects/items/devices/geiger_counter.dm
+++ b/code/game/objects/items/devices/geiger_counter.dm
@@ -144,14 +144,7 @@
return TRUE
/obj/item/geiger_counter/proc/scan(atom/A, mob/user)
- var/rad_strength = 0
- for(var/i in get_rad_contents(A)) // Yes it's intentional that you can't detect radioactive things under rad protection. Gives traitors a way to hide their glowing green rocks.
- var/atom/thing = i
- if(!thing)
- continue
- var/datum/component/radioactive/radiation = thing.GetComponent(/datum/component/radioactive)
- if(radiation)
- rad_strength += radiation.strength
+ var/rad_strength = get_rad_contamination(A)
if(isliving(A))
var/mob/living/M = A
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 6242db3f13f2..f2a18e8eb621 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -708,7 +708,7 @@ GENE SCANNER
/obj/item/sequence_scanner/attack(mob/living/M, mob/living/carbon/human/user)
add_fingerprint(user)
- if (!HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_BADDNA)) //no scanning if its a husk or DNA-less Species
+ if (!HAS_TRAIT(M, TRAIT_GENELESS) && !HAS_TRAIT(M, TRAIT_BADDNA)) //no scanning if its a husk or DNA-less Species
user.visible_message("[user] has analyzed [M]'s genetic sequence.")
gene_scan(M, user)
diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm
index 2c5dd40b5bde..15b4e82c3eb9 100644
--- a/code/game/objects/items/dna_injector.dm
+++ b/code/game/objects/items/dna_injector.dm
@@ -20,7 +20,7 @@
return attack_hand(user)
/obj/item/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
- if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_BADDNA))
+ if(M.has_dna() && !HAS_TRAIT(M, TRAIT_GENELESS) && !HAS_TRAIT(M, TRAIT_BADDNA))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/HM in remove_mutations)
@@ -515,7 +515,7 @@
var/filled = FALSE
/obj/item/dnainjector/activator/inject(mob/living/carbon/M, mob/user)
- if(M.has_dna() && !HAS_TRAIT(M, TRAIT_RADIMMUNE) && !HAS_TRAIT(M, TRAIT_BADDNA))
+ if(M.has_dna() && !HAS_TRAIT(M, TRAIT_GENELESS) && !HAS_TRAIT(M, TRAIT_BADDNA))
M.radiation += rand(20/(damage_coeff ** 2),50/(damage_coeff ** 2))
var/log_msg = "[key_name(user)] injected [key_name(M)] with the [name]"
for(var/mutation in add_mutations)
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index 9cdd1b1dee81..0e036c2af30b 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -26,10 +26,7 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent(/datum/reagent/water, 1) || reagents.has_reagent(/datum/reagent/water/holywater, 1) || reagents.has_reagent(/datum/reagent/consumable/ethanol/vodka, 1) || reagents.has_reagent(/datum/reagent/space_cleaner, 1))
- SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
- for(var/obj/effect/O in A)
- if(is_cleanable(O))
- qdel(O)
+ A.wash(CLEAN_SCRUB)
reagents.reaction(A, TOUCH, 10) //Needed for proper floor wetting.
reagents.remove_any(1) //reaction() doesn't use up the reagents
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index 6f21963a4b51..f5d20b6147ee 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -353,7 +353,7 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
- SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_TYPE_BLOOD)
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 16599fe025bd..a5d97eeb8419 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -24,7 +24,7 @@
smooth = SMOOTH_TRUE
can_be_unanchored = FALSE
CanAtmosPass = ATMOS_PASS_DENSITY
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_MEDIUM_INSULATION
var/mineral = /obj/item/stack/sheet/metal
var/mineral_amount = 2
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 6180cc11ce9c..f9c2834f4bbc 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -8,7 +8,7 @@
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
var/can_displace = TRUE //If the girder can be moved around by wrenching it
max_integrity = 200
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_VERY_LIGHT_INSULATION
/obj/structure/girder/examine(mob/user)
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 1a4c0819503f..fab500e4a2c1 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -5,7 +5,7 @@
icon_state = "grille"
density = TRUE
anchored = TRUE
- flags_1 = CONDUCT_1
+ flags_1 = CONDUCT_1 | RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
pressure_resistance = 5*ONE_ATMOSPHERE
armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0)
max_integrity = 50
@@ -20,7 +20,6 @@
var/rods_broken = TRUE
var/grille_type = null
var/broken_type = null
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
FASTDMM_PROP(\
pipe_astar_cost = 1\
)
diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm
index 90632082eafb..8269aaa8418b 100644
--- a/code/game/objects/structures/holosign.dm
+++ b/code/game/objects/structures/holosign.dm
@@ -90,7 +90,7 @@
/obj/structure/holosign/barrier/engineering
icon_state = "holosign_engi"
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_LIGHT_INSULATION
/obj/structure/holosign/barrier/atmos
@@ -101,7 +101,7 @@
anchored = TRUE
CanAtmosPass = ATMOS_PASS_NO
alpha = 150
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_LIGHT_INSULATION
/obj/structure/holosign/barrier/atmos/Initialize()
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index bdbc34276966..29c7b08aba1e 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -13,7 +13,7 @@
max_integrity = 200
armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50)
CanAtmosPass = ATMOS_PASS_DENSITY
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_MEDIUM_INSULATION
var/door_opened = FALSE //if it's open or not.
diff --git a/code/game/objects/structures/shower.dm b/code/game/objects/structures/shower.dm
index 2e5aee7577fd..fc0600f04712 100644
--- a/code/game/objects/structures/shower.dm
+++ b/code/game/objects/structures/shower.dm
@@ -49,6 +49,7 @@
return ..()
/obj/machinery/shower/wrench_act(mob/living/user, obj/item/I)
+ ..()
to_chat(user, "You begin to adjust the temperature valve with \the [I]...")
if(I.use_tool(src, user, 50))
switch(current_temperature)
@@ -64,10 +65,9 @@
handle_mist()
return TRUE
-
/obj/machinery/shower/update_icon()
+ . = ..()
cut_overlays()
-
if(on)
add_overlay(mutable_appearance('icons/obj/watercloset.dmi', "water", ABOVE_MOB_LAYER))
@@ -98,109 +98,21 @@
wash_atom(AM)
/obj/machinery/shower/proc/wash_atom(atom/A)
- SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ A.wash(CLEAN_RAD | CLEAN_TYPE_WEAK) // Clean radiation non-instantly
+ A.wash(CLEAN_WASH)
+ SEND_SIGNAL(A, COMSIG_ADD_MOOD_EVENT, "shower", /datum/mood_event/nice_shower)
reagents.reaction(A, TOUCH, reaction_volume)
- if(isobj(A))
- wash_obj(A)
- else if(isturf(A))
- wash_turf(A)
- else if(isliving(A))
- wash_mob(A)
+ if(isliving(A))
check_heat(A)
- contamination_cleanse(A)
-
-/obj/machinery/shower/proc/wash_obj(obj/O)
- . = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
- O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
-
-
-/obj/machinery/shower/proc/wash_turf(turf/tile)
- SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
- tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- for(var/obj/effect/E in tile)
- if(is_cleanable(E))
- qdel(E)
-
-
-/obj/machinery/shower/proc/wash_mob(mob/living/L)
- SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
- L.wash_cream()
- L.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "shower", /datum/mood_event/nice_shower)
- if(iscarbon(L))
- var/mob/living/carbon/M = L
- . = TRUE
- for(var/I in M.held_items)
- if(isobj(I))
- wash_obj(I)
-
- if(M.back && wash_obj(M.back))
- M.update_inv_back(0)
-
- var/list/obscured = M.check_obscured_slots()
-
- if(M.head && wash_obj(M.head))
- M.update_inv_head()
-
- if(M.glasses && !(SLOT_GLASSES in obscured) && wash_obj(M.glasses))
- M.update_inv_glasses()
-
- if(M.wear_mask && !(SLOT_WEAR_MASK in obscured) && wash_obj(M.wear_mask))
- M.update_inv_wear_mask()
-
- if(M.ears && !(HIDEEARS in obscured) && wash_obj(M.ears))
- M.update_inv_ears()
-
- if(M.wear_neck && !(SLOT_NECK in obscured) && wash_obj(M.wear_neck))
- M.update_inv_neck()
-
- if(M.shoes && !(HIDESHOES in obscured) && wash_obj(M.shoes))
- M.update_inv_shoes()
-
- var/washgloves = FALSE
- if(M.gloves && !(HIDEGLOVES in obscured))
- washgloves = TRUE
-
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
-
-
- if(H.wear_suit && wash_obj(H.wear_suit))
- H.update_inv_wear_suit()
- else if(H.w_uniform && wash_obj(H.w_uniform))
- H.update_inv_w_uniform()
-
- if(washgloves)
- SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
-
- if(!H.is_mouth_covered())
- H.lip_style = null
- H.update_body()
-
- if(H.belt && wash_obj(H.belt))
- H.update_inv_belt()
- else
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- else
- SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
-
-/obj/machinery/shower/proc/contamination_cleanse(atom/thing)
- var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
- if(!healthy_green_glow || QDELETED(healthy_green_glow))
- return
- var/strength = healthy_green_glow.strength
- if(strength <= RAD_BACKGROUND_RADIATION)
- qdel(healthy_green_glow)
- return
- healthy_green_glow.strength -= max(0, (healthy_green_glow.strength - (RAD_BACKGROUND_RADIATION * 2)) * 0.2)
-
/obj/machinery/shower/process()
if(on)
wash_atom(loc)
- for(var/AM in loc)
- wash_atom(AM)
+ for(var/am in loc)
+ var/atom/movable/movable_content = am
+ if(!ismopable(movable_content)) // Mopables will be cleaned anyways by the turf wash above
+ wash_atom(movable_content)
else
return PROCESS_KILL
diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm
index ef7e29d03e0f..7d384d98f303 100644
--- a/code/game/objects/structures/signs/_signs.dm
+++ b/code/game/objects/structures/signs/_signs.dm
@@ -7,7 +7,7 @@
max_integrity = 100
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
var/buildable_sign = 1 //unwrenchable and modifiable
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
/obj/structure/sign/basic
name = "blank sign"
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index e797508eaa91..7c7594e3bd70 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -252,18 +252,20 @@
busy = FALSE
- user.visible_message("[user] washes [user.p_their()] [washing_face ? "face" : "hands"] using [src].", \
- "You wash your [washing_face ? "face" : "hands"] using [src].")
if(washing_face)
if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.lip_style = null //Washes off lipstick
- H.lip_color = initial(H.lip_color)
- H.wash_cream()
- H.regenerate_icons()
- user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
- else
- SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_FACE_ACT, CLEAN_WASH)
+ user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
+ else if(ishuman(user))
+ var/mob/living/carbon/human/human_user = user
+ if(!human_user.wash_hands(CLEAN_WASH))
+ to_chat(user, "Your hands are covered by something!")
+ return
+ else
+ user.wash(CLEAN_WASH)
+
+ user.visible_message("[user] washes [user.p_their()] [washing_face ? "face" : "hands"] using [src].", \
+ "You wash your [washing_face ? "face" : "hands"] using [src].")
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -310,7 +312,7 @@
//yogs start - BANDAGES
if(istype(O, /obj/item/medical/bandage/))
var/obj/item/medical/bandage/B = O
- B.wash(O, user)
+ B.wash2(O, user)
return
//yogs end
@@ -326,7 +328,7 @@
busy = FALSE
return 1
busy = FALSE
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ O.wash(CLEAN_WASH)
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 1bb3a9a5e904..016914c938ea 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -6,14 +6,13 @@
layer = ABOVE_OBJ_LAYER //Just above doors
pressure_resistance = 4*ONE_ATMOSPHERE
anchored = TRUE //initially is 0 for tile smoothing
- flags_1 = ON_BORDER_1
+ flags_1 = ON_BORDER_1 | RAD_PROTECT_CONTENTS_1
max_integrity = 25
can_be_unanchored = TRUE
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
CanAtmosPass = ATMOS_PASS_PROC
rad_insulation = RAD_VERY_LIGHT_INSULATION
- rad_flags = RAD_PROTECT_CONTENTS
var/ini_dir = null
var/state = WINDOW_SCREWED_TO_FRAME
var/reinf = FALSE
diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm
index 62ee9879dc08..51232bd3a229 100644
--- a/code/game/turfs/closed.dm
+++ b/code/game/turfs/closed.dm
@@ -3,7 +3,7 @@
opacity = 1
density = TRUE
blocks_air = TRUE
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
rad_insulation = RAD_MEDIUM_INSULATION
/turf/closed/Initialize()
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index e152dd7bac6b..9e520a8c8d9b 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -331,10 +331,12 @@
for(var/mob/living/simple_animal/slime/M in src)
M.apply_water()
- SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
- for(var/obj/effect/O in src)
- if(is_cleanable(O))
- qdel(O)
+ wash(CLEAN_WASH)
+ for(var/am in src)
+ var/atom/movable/movable_content = am
+ if(ismopable(movable_content)) // Will have already been washed by the wash call above at this point.
+ continue
+ movable_content.wash(CLEAN_WASH)
return TRUE
/turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube, paralyze_amount, force_drop)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index cebb1bea51d0..0f6fe5d7458e 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -553,3 +553,17 @@ GLOBAL_LIST_EMPTY(station_turfs)
. = ..()
if(. != BULLET_ACT_FORCE_PIERCE)
. = BULLET_ACT_TURF
+
+/**
+ * Called when this turf is being washed. Washing a turf will also wash any mopable floor decals
+ */
+/turf/wash(clean_types)
+ . = ..()
+
+ for(var/am in src)
+ if(am == src)
+ continue
+ var/atom/movable/movable_content = am
+ if(!ismopable(movable_content))
+ continue
+ movable_content.wash(clean_types)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 2294004bd49c..70d976796f34 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -94,6 +94,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
/client/proc/give_antag_token,
/client/proc/show_redeemable_antag_tokens,
/datum/admins/proc/cmd_create_centcom,
+ /datum/admins/proc/cmd_admin_fuckrads,
/client/proc/admincryo
)
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/ban_panel, /client/proc/stickybanpanel))
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index ecc06f39ec1f..4efd8cbf9773 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1276,3 +1276,15 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/msg = "[key_name_admin(usr)] has spawned in at centcom [ADMIN_VERBOSEJMP(usr)]."
message_admins(msg)
log_admin(msg)
+
+/datum/admins/proc/cmd_admin_fuckrads()
+ set category = "Admin.Round Interaction"
+ set name = "Delete All Rads"
+ if(!check_rights(R_ADMIN))
+ return
+ for(var/datum/a in SSradiation.processing)
+ qdel(a)
+ message_admins("[key_name_admin(usr)] has cleared all radiation.")
+ log_admin("[key_name_admin(usr)] has cleared all radiation.")
+
+
\ No newline at end of file
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
index e177d5a490ee..ea081f443ec1 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
@@ -167,7 +167,7 @@
required_atoms = list(/mob/living/carbon/human)
cost = 3
route = PATH_ASH
- var/list/trait_list = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_BOMBIMMUNE)
+ var/list/trait_list = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_BOMBIMMUNE)
/datum/eldritch_knowledge/final/ash_final/on_finished_recipe(mob/living/user, list/atoms, loc)
priority_announce("$^@*$^@(#&$(@^$^@# Fear The Blaze, for Ashbringer [user.real_name] has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm
index fe39e292f662..185d4f122834 100644
--- a/code/modules/antagonists/revenant/revenant.dm
+++ b/code/modules/antagonists/revenant/revenant.dm
@@ -50,6 +50,7 @@
unique_name = TRUE
hud_possible = list(ANTAG_HUD)
hud_type = /datum/hud/revenant
+ flags_1 = RAD_NO_CONTAMINATE_1
var/essence = 75 //The resource, and health, of revenants.
var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm
index 9b381cef7f8c..aec341d2f987 100644
--- a/code/modules/clothing/gloves/_gloves.dm
+++ b/code/modules/clothing/gloves/_gloves.dm
@@ -11,12 +11,14 @@
strip_delay = 20
equip_delay_other = 40
-/obj/item/clothing/gloves/ComponentInitialize()
+/obj/item/clothing/gloves/wash(clean_types)
. = ..()
- RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_blood)
+ if((clean_types & CLEAN_TYPE_BLOOD) && transfer_blood > 0)
+ transfer_blood = 0
+ return TRUE
/obj/item/clothing/gloves/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
+ if(strength < CLEAN_TYPE_BLOOD)
return
transfer_blood = 0
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 677e3565e005..dd86e43c4745 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -16,10 +16,6 @@
var/equipped_before_drop = FALSE
var/can_be_bloody = TRUE
-/obj/item/clothing/shoes/ComponentInitialize()
- . = ..()
- RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_blood)
-
/obj/item/clothing/shoes/suicide_act(mob/living/carbon/user)
if(rand(2)>1)
user.visible_message("[user] begins tying \the [src] up waaay too tightly! It looks like [user.p_theyre()] trying to commit suicide!")
@@ -77,14 +73,16 @@
var/mob/M = loc
M.update_inv_shoes()
-/obj/item/clothing/shoes/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
+/obj/item/clothing/shoes/wash(clean_types)
+ . = ..()
+ if(!(clean_types & CLEAN_TYPE_BLOOD) || blood_state == BLOOD_STATE_NOT_BLOODY)
return
bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
blood_state = BLOOD_STATE_NOT_BLOODY
if(ismob(loc))
var/mob/M = loc
M.update_inv_shoes()
+ return TRUE
/obj/item/proc/negates_gravity()
return FALSE
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index d186ef388ef7..0cfdfefedf2c 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -127,7 +127,7 @@
equip_delay_other = 60
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
resistance_flags = NONE
- rad_flags = RAD_PROTECT_CONTENTS
+ flags_1 = RAD_PROTECT_CONTENTS_1
/obj/item/clothing/suit/radiation
name = "radiation suit"
@@ -146,4 +146,4 @@
equip_delay_other = 60
flags_inv = HIDEJUMPSUIT
resistance_flags = NONE
- rad_flags = RAD_PROTECT_CONTENTS
+ flags_1 = RAD_PROTECT_CONTENTS_1
diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm
index fe5197036718..98df8ad72d9c 100644
--- a/code/modules/detectivework/detective_work.dm
+++ b/code/modules/detectivework/detective_work.dm
@@ -46,10 +46,10 @@
if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
G.transfer_blood--
- else if(M.bloody_hands > 1)
+ else if(M.blood_in_hands > 1)
old = length(M.return_blood_DNA())
if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
- M.bloody_hands--
+ M.blood_in_hands--
var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
. = D.add_fibers(M)
@@ -92,7 +92,7 @@
G.add_blood_DNA(blood_dna)
else if(length(blood_dna))
AddComponent(/datum/component/forensics, null, null, blood_dna)
- bloody_hands = rand(2, 4)
+ blood_in_hands = rand(2, 4)
update_inv_gloves() //handles bloody hands overlays and updating
return TRUE
diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm
index aaf279bd3402..2fabc255de2f 100644
--- a/code/modules/detectivework/footprints_and_rag.dm
+++ b/code/modules/detectivework/footprints_and_rag.dm
@@ -1,11 +1,6 @@
-
-/mob
- var/bloody_hands = 0
-
/obj/item/clothing/gloves
var/transfer_blood = 0
-
/obj/item/reagent_containers/glass/rag
name = "damp rag"
desc = "For cleaning up messes, you suppose."
@@ -46,6 +41,4 @@
user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...")
if(do_after(user,30, target = A))
user.visible_message("[user] finishes wiping off [A]!", "You finish wiping off [A].")
- if(is_cleanable(A))
- qdel(A)
- SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ A.wash(CLEAN_SCRUB)
diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm
index 916040c2e102..8fc11134d427 100644
--- a/code/modules/lighting/lighting_object.dm
+++ b/code/modules/lighting/lighting_object.dm
@@ -145,6 +145,9 @@
/atom/movable/lighting_object/onTransitZ()
return
+/atom/movable/lighting_object/wash(clean_types)
+ return
+
// Override here to prevent things accidentally moving around overlays.
/atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE)
if(harderforce)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index dc01d265ee86..efc7e5e5191b 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -972,3 +972,39 @@
/// Returns if the carbon is wearing shock proof gloves
/mob/living/carbon/proc/wearing_shock_proof_gloves()
return gloves?.siemens_coefficient == 0
+
+/mob/living/carbon/wash(clean_types)
+ . = ..()
+ // Wash equipped stuff that cannot be covered
+ for(var/i in held_items)
+ var/obj/item/held_thing = i
+ if(held_thing.wash(clean_types))
+ . = TRUE
+ if(back?.wash(clean_types))
+ update_inv_back(0)
+ . = TRUE
+ if(head?.wash(clean_types))
+ update_inv_head()
+ . = TRUE
+ // Check and wash stuff that can be covered
+ var/list/obscured = check_obscured_slots()
+
+ // If the eyes are covered by anything but glasses, that thing will be covering any potential glasses as well.
+ if(glasses && is_eyes_covered(FALSE, TRUE, TRUE) && glasses.wash(clean_types))
+ update_inv_glasses()
+ . = TRUE
+ if(wear_mask && !(ITEM_SLOT_MASK in obscured) && wear_mask.wash(clean_types))
+ update_inv_wear_mask()
+ . = TRUE
+ if(ears && !(ITEM_SLOT_EARS in obscured) && ears.wash(clean_types))
+ update_inv_ears()
+ . = TRUE
+ if(wear_neck && !(ITEM_SLOT_NECK in obscured) && wear_neck.wash(clean_types))
+ update_inv_neck()
+ . = TRUE
+ if(shoes && !(ITEM_SLOT_FEET in obscured) && shoes.wash(clean_types))
+ update_inv_shoes()
+ . = TRUE
+ if(gloves && !(ITEM_SLOT_GLOVES in obscured) && gloves.wash(clean_types))
+ update_inv_gloves()
+ . = TRUE
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 56683710791c..c27cf433a7bf 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -25,7 +25,7 @@
. = ..()
- RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_blood)
+ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_FACE_ACT, .proc/clean_face)
AddComponent(/datum/component/personal_crafting)
/mob/living/carbon/human/proc/setup_human_dna()
@@ -670,16 +670,82 @@
if(..())
dropItemToGround(I)
-/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
+/**
+ * Wash the hands, cleaning either the gloves if equipped and not obscured, otherwise the hands themselves if they're not obscured.
+ *
+ * Returns false if we couldn't wash our hands due to them being obscured, otherwise true
+ */
+/mob/living/carbon/human/proc/wash_hands(clean_types)
+ var/list/obscured = check_obscured_slots()
+ if(ITEM_SLOT_GLOVES in obscured)
+ return FALSE
if(gloves)
- if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- update_inv_gloves()
- else
- if(bloody_hands)
- bloody_hands = 0
+ if(gloves.wash(clean_types))
update_inv_gloves()
+ else if((clean_types & CLEAN_TYPE_BLOOD) && blood_in_hands > 0)
+ blood_in_hands = 0
+ update_inv_gloves()
+
+ return TRUE
+
+/**
+ * Cleans the lips of any lipstick. Returns TRUE if the lips had any lipstick and was thus cleaned
+ */
+/mob/living/carbon/human/proc/clean_lips()
+ if(isnull(lip_style) && lip_color == initial(lip_color))
+ return FALSE
+ lip_style = null
+ lip_color = initial(lip_color)
+ update_body()
+ return TRUE
+
+/**
+ * Called on the COMSIG_COMPONENT_CLEAN_FACE_ACT signal
+ */
+/mob/living/carbon/human/proc/clean_face(datum/source, clean_types)
+ if(!is_mouth_covered() && clean_lips())
+ . = TRUE
+
+ if(glasses && is_eyes_covered(FALSE, TRUE, TRUE) && glasses.wash(clean_types))
+ update_inv_glasses()
+ . = TRUE
+
+ var/list/obscured = check_obscured_slots()
+ if(wear_mask && !(ITEM_SLOT_MASK in obscured) && wear_mask.wash(clean_types))
+ update_inv_wear_mask()
+ . = TRUE
+
+/**
+ * Called when this human should be washed
+ */
+/mob/living/carbon/human/wash(clean_types)
+ . = ..()
+
+ // Wash equipped stuff that cannot be covered
+ if(wear_suit?.wash(clean_types))
+ update_inv_wear_suit()
+ . = TRUE
+
+ if(belt?.wash(clean_types))
+ update_inv_belt()
+ . = TRUE
+
+ // Check and wash stuff that can be covered
+ var/list/obscured = check_obscured_slots()
+
+ if(w_uniform && !(ITEM_SLOT_ICLOTHING in obscured) && w_uniform.wash(clean_types))
+ update_inv_w_uniform()
+ . = TRUE
+
+ if(!is_mouth_covered() && clean_lips())
+ . = TRUE
+
+ // Wash hands if exposed
+ if(!gloves && (clean_types & CLEAN_TYPE_BLOOD) && blood_in_hands > 0 && !(ITEM_SLOT_GLOVES in obscured))
+ blood_in_hands = 0
+ update_inv_gloves()
+ . = TRUE
+ wash_cream()
/mob/living/carbon/human/wash_cream()
if(creamed) //clean both to prevent a rare bug
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 1fce6c052602..00c5a1bf76bb 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -56,3 +56,4 @@
var/last_fire_update
var/account_id
var/xylophone = 0 //For the spoooooooky xylophone cooldown
+ var/blood_in_hands = 0
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 3c65df8e3441..c6164e00d2d5 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1176,13 +1176,13 @@ GLOBAL_LIST_EMPTY(mentor_races)
return 0
/datum/species/proc/handle_mutations_and_radiation(mob/living/carbon/human/H)
+ if(HAS_TRAIT(H, TRAIT_RADIMMUNE))
+ H.radiation = 0
+ return TRUE
+
. = FALSE
var/radiation = H.radiation
- if(HAS_TRAIT(H, TRAIT_RADIMMUNE))
- radiation = 0
- return TRUE
-
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
if(!H.IsParalyzed())
H.emote("collapse")
diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm
index b2e4ac907c36..8d5fdd123a7f 100644
--- a/code/modules/mob/living/carbon/human/species_types/android.dm
+++ b/code/modules/mob/living/carbon/human/species_types/android.dm
@@ -3,7 +3,7 @@
id = "android"
say_mod = "states"
species_traits = list(NOBLOOD)
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
meat = null
damage_overlay_type = "synth"
diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm
index 7ccf5354df28..a5f951a3c049 100644
--- a/code/modules/mob/living/carbon/human/species_types/corporate.dm
+++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm
@@ -15,6 +15,6 @@
attack_sound = 'sound/weapons/resonator_blast.ogg'
use_skintones = 0
species_traits = list(NOBLOOD,EYECOLOR)
- inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
+ inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
sexes = 0
changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN
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 e250c7536b4b..058a2bfa837e 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -3,7 +3,7 @@
name = "Golem"
id = "iron golem"
species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR)
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) // yogs - Gives golems NOHUNGER
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOGUNS)
inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
mutant_organs = list(/obj/item/organ/adamantine_resonator)
speedmod = 2
@@ -86,7 +86,7 @@
fixed_mut_color = "a3d"
meat = /obj/item/stack/ore/plasma
//Can burn and takes damage from heat
- inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER) //no RESISTHEAT, NOFIRE
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER) //no RESISTHEAT, NOFIRE
info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!"
heatmod = 0 //fine until they blow up
prefix = "Plasma"
@@ -275,7 +275,7 @@
fixed_mut_color = "9E704B"
meat = /obj/item/stack/sheet/mineral/wood
//Can burn and take damage from heat
- inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
armor = 30
burnmod = 1.25
heatmod = 1.5
@@ -701,7 +701,7 @@
info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable. \
Being made of cloth, your body is magic resistant and faster than that of other golems, but weaker and less resilient."
species_traits = list(NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn
- inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
armor = 15 //feels no pain, but not too resistant
burnmod = 2 // don't get burned
@@ -903,7 +903,7 @@
prefix = "Snow"
special_names = list("Flake", "Blizzard", "Storm", "Frosty")
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES) //no mutcolors, no eye sprites
- inherent_traits = list(TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
var/obj/effect/proc_holder/spell/targeted/conjure_item/snowball/ball
var/obj/effect/proc_holder/spell/aimed/cryo/cryo
@@ -950,7 +950,7 @@
special_names = list("Box")
info_text = "As a Cardboard Golem, you aren't very strong, but you are a bit quicker and can easily create more brethren by using cardboard on yourself."
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,NOFLASH)
- inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
limbs_id = "c_golem" //special sprites
attack_verb = "whips"
attack_sound = 'sound/weapons/whip.ogg'
@@ -995,7 +995,7 @@
name = "Leather Golem"
id = "leather golem"
special_names = list("Face", "Man", "Belt") //Ah dude 4 strength 4 stam leather belt AHHH
- inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER, TRAIT_STRONG_GRABBER)
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER, TRAIT_STRONG_GRABBER)
prefix = "Leather"
fixed_mut_color = "624a2e"
info_text = "As a Leather Golem, you are flammable, but you can grab things with incredible ease, allowing all your grabs to start at a strong level."
@@ -1010,7 +1010,7 @@
special_names = list("Boll","Weave")
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,NOFLASH)
fixed_mut_color = null
- inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
info_text = "As a Durathread Golem, your strikes will cause those your targets to start choking, but your woven body won't withstand fire as well."
/datum/species/golem/durathread/spec_unarmedattacked(mob/living/carbon/human/user, mob/living/carbon/human/target)
@@ -1031,7 +1031,7 @@
mutanttongue = /obj/item/organ/tongue/bone
sexes = FALSE
fixed_mut_color = null
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER)
info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice."
var/datum/action/innate/bonechill/bonechill
@@ -1090,7 +1090,7 @@
special_names = list("John D. Rockefeller","Rich Uncle Pennybags","Commodore Vanderbilt","Entrepreneur","Mr. Moneybags", "Adam Smith")
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,NOFLASH)
fixed_mut_color = null
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
info_text = "As a Capitalist Golem, your fist spreads the powerful industrializing light of capitalism."
changesource_flags = MIRROR_BADMIN
random_eligible = FALSE
@@ -1138,7 +1138,7 @@
special_names = list("John D. Rockefeller","Rich Uncle Pennybags","Commodore Vanderbilt","Entrepreneur","Mr. Moneybags", "Adam Smith")
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES)
fixed_mut_color = null
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
info_text = "As a Churchgoing Capitalist Golem, your god-given right is to make fat stacks of money!"
changesource_flags = MIRROR_BADMIN
random_eligible = FALSE
@@ -1160,7 +1160,7 @@
special_names = list("Stalin","Lenin","Trotsky","Marx","Comrade") //comrade comrade
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,NOFLASH)
fixed_mut_color = null
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
info_text = "As a Soviet Golem, your fist spreads the bright soviet light of communism."
changesource_flags = MIRROR_BADMIN
random_eligible = FALSE
@@ -1203,7 +1203,7 @@
id = "cheese golem"
fixed_mut_color = "F1D127"
meat = /obj/item/stack/sheet/cheese
- inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
armor = 10
burnmod = 1.25
heatmod = 1.5
@@ -1237,7 +1237,7 @@
info_text = "As a Metallic Hydrogen Golem, you were forged in the highest pressures and the highest heats. Your unique mineral makeup makes you immune to most types of damages."
prefix = "Metallic Hydrogen"
special_names = null
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_NODISMEMBER)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_NODISMEMBER)
/datum/species/golem/mhydrogen/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index 1b482816af60..d7ecfeda2cc4 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -5,7 +5,7 @@
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
species_traits = list(NOBLOOD,NOTRANSSTING)
- inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER,TRAIT_ALWAYS_CLEAN)
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER,TRAIT_ALWAYS_CLEAN)
inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index 366e7f88522e..ce1f4c530b79 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -6,7 +6,7 @@
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBLOOD)
- inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index f96ec2c29e98..e604842e4609 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -176,7 +176,7 @@ There are several things that need to be remembered:
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_GLOVES]
inv.update_icon()
- if(!gloves && bloody_hands)
+ if(!gloves && blood_in_hands)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
if(get_num_arms(FALSE) < 2)
if(has_left_hand(FALSE))
@@ -672,4 +672,4 @@ generate/load female uniform sprites matching all previously decided variables
dna.species.handle_hair(src)
update_inv_head()
- update_inv_wear_mask()
\ No newline at end of file
+ update_inv_wear_mask()
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index ce174f34d01e..3b38b09574a7 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -80,10 +80,10 @@
-/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
+/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = 0)
var/hit_percent = (100-blocked)/100
if(!effect || (hit_percent <= 0))
- return 0
+ return FALSE
switch(effecttype)
if(EFFECT_STUN)
Stun(effect * hit_percent)
@@ -96,7 +96,8 @@
if(EFFECT_UNCONSCIOUS)
Unconscious(effect * hit_percent)
if(EFFECT_IRRADIATE)
- radiation += max(effect * hit_percent, 0)
+ if(!HAS_TRAIT(src, TRAIT_RADIMMUNE))
+ radiation += max(effect * hit_percent, 0)
if(EFFECT_SLUR)
slurring = max(slurring,(effect * hit_percent))
if(EFFECT_STUTTER)
@@ -113,12 +114,12 @@
Paralyze(effect * hit_percent)
if(EFFECT_IMMOBILIZE)
Immobilize(effect * hit_percent)
- return 1
+ return TRUE
-/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, paralyze = 0, immobilize = 0)
+/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = 0, stamina = 0, jitter = 0, paralyze = 0, immobilize = 0)
if(blocked >= 100)
- return BULLET_ACT_BLOCK
+ return FALSE
if(stun)
apply_effect(stun, EFFECT_STUN, blocked)
if(knockdown)
@@ -143,7 +144,7 @@
apply_damage(stamina, STAMINA, null, blocked)
if(jitter)
apply_effect(jitter, EFFECT_JITTER, blocked)
- return BULLET_ACT_HIT
+ return TRUE
/mob/living/proc/getBruteLoss()
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 939eb8b3b8c7..3862273ad677 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -11,10 +11,9 @@
weather_immunities = list("ash")
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
mob_biotypes = list(MOB_ROBOTIC)
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
deathsound = 'sound/voice/borg_deathsound.ogg'
speech_span = SPAN_ROBOT
- flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
+ flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1 | RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
@@ -458,4 +457,4 @@
lawcheck.len += 1
.+= "[number]: [law]"
number++
- .+= ""
\ No newline at end of file
+ .+= ""
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index dbbad683f5db..1e4dcba57441 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -209,18 +209,14 @@
target_types = typecacheof(target_types)
/mob/living/simple_animal/bot/cleanbot/UnarmedAttack(atom/A)
- if(is_cleanable(A))
+ if(ismopable(A))
icon_state = "cleanbot-c"
mode = BOT_CLEANING
var/turf/T = get_turf(A)
if(do_after(src, 1, target = T))
- SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
+ T.wash(CLEAN_WASH)
visible_message("[src] cleans \the [T].")
- for(var/atom/dirtything in T)
- if(is_cleanable(dirtything))
- qdel(dirtything)
-
target = null
mode = BOT_IDLE
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 45973a287a43..0ff8cff17cae 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -172,11 +172,9 @@
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
if(ismovable(target))
+ target.wash(CLEAN_WASH)
if(istype(target, /obj/effect/decal/cleanable))
visible_message("[src] cleans up \the [target].")
- qdel(target)
- return TRUE
- var/atom/movable/M = target
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- visible_message("[src] polishes \the [target].")
+ else
+ visible_message("[src] polishes \the [target].")
return TRUE
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 4d329a406ef1..0383bd967468 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -992,56 +992,26 @@
var/toxpwr = 1
taste_description = "sourness"
reagent_weight = 0.6 //so it sprays further
+ var/clean_types = CLEAN_WASH
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
- if(istype(O, /obj/effect/decal/cleanable))
- qdel(O)
- else
- if(O)
- O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ O?.wash(clean_types)
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 1)
- T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- for(var/obj/effect/decal/cleanable/C in T)
- qdel(C)
+ T.wash(clean_types)
+ for(var/am in T)
+ var/atom/movable/movable_content
+ if(ismopable(movable_content)) // Mopables will be cleaned anyways by the turf wash
+ continue
+ movable_content.wash(clean_types)
for(var/mob/living/simple_animal/slime/M in T)
M.adjustToxLoss(rand(5,10))
/datum/reagent/space_cleaner/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
- M.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(ishuman(M))
- var/mob/living/carbon/human/H = M
- if(H.lip_style)
- H.lip_style = null
- H.update_body()
- for(var/obj/item/I in C.held_items)
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(C.wear_mask)
- if(SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- C.update_inv_wear_mask()
- if(ishuman(M))
- var/mob/living/carbon/human/H = C
- if(H.head)
- if(SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- H.update_inv_head()
- if(H.wear_suit)
- if(SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- H.update_inv_wear_suit()
- else if(H.w_uniform)
- if(SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- H.update_inv_w_uniform()
- if(H.shoes)
- if(SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- H.update_inv_shoes()
- H.wash_cream()
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ M.wash(clean_types)
/datum/reagent/space_cleaner/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(toxpwr*REM, 0)
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 38083e984aab..781787a04b75 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -34,7 +34,7 @@
/datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume)
if(!..())
return
- if(!M.has_dna() || HAS_TRAIT(M, TRAIT_RADIMMUNE) || HAS_TRAIT(M, TRAIT_BADDNA))
+ if(!M.has_dna() || HAS_TRAIT(M, TRAIT_GENELESS) || HAS_TRAIT(M, TRAIT_BADDNA))
return //No robots, AIs, aliens, Ians or other mobs should be affected by this.
if((method==VAPOR && prob(min(33, reac_volume))) || method==INGEST || method==PATCH || method==INJECT)
M.randmuti()
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 1cabbecb20d5..0f26af458004 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -10,7 +10,7 @@
resistance_flags = FIRE_PROOF
interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON
obj_flags = CAN_BE_HIT | USES_TGUI
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
var/datum/gas_mixture/air_contents // internal reservoir
var/full_pressure = FALSE
var/pressure_charging = TRUE
diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm
index 66b647e5f4fd..efa8d9a5e3a8 100644
--- a/code/modules/recycling/disposal/holder.dm
+++ b/code/modules/recycling/disposal/holder.dm
@@ -7,7 +7,7 @@
invisibility = INVISIBILITY_MAXIMUM
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
dir = NONE
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
var/datum/gas_mixture/gas // gas used to flush, will appear at exit point
var/active = FALSE // true if the holder is moving, otherwise inactive
var/count = 1000 // can travel 1000 steps before going inactive (in case of loops)
diff --git a/code/modules/recycling/disposal/outlet.dm b/code/modules/recycling/disposal/outlet.dm
index 7655988c8ffd..3eed0d3ef3d5 100644
--- a/code/modules/recycling/disposal/outlet.dm
+++ b/code/modules/recycling/disposal/outlet.dm
@@ -6,7 +6,7 @@
icon_state = "outlet"
density = TRUE
anchored = TRUE
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
var/active = FALSE
var/turf/target // this will be where the output objects are 'thrown' to.
var/obj/structure/disposalpipe/trunk/trunk // the attached pipe trunk
diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm
index 20fca2721cff..13274590d95b 100644
--- a/code/modules/recycling/disposal/pipe.dm
+++ b/code/modules/recycling/disposal/pipe.dm
@@ -12,7 +12,7 @@
max_integrity = 200
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30)
layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes
- rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ flags_1 = RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
var/dpdir = NONE // bitmask of pipe directions
var/initialize_dirs = NONE // bitflags of pipe directions added on init, see \code\_DEFINES\pipe_construction.dm
var/flip_type // If set, the pipe is flippable and becomes this type when flipped
diff --git a/yogstation/code/datums/components/radioactive.dm b/yogstation/code/datums/components/radioactive.dm
index bc15957461f1..7d8a8cd4bffc 100644
--- a/yogstation/code/datums/components/radioactive.dm
+++ b/yogstation/code/datums/components/radioactive.dm
@@ -21,4 +21,4 @@
#undef RAD_AMOUNT_LOW
#undef RAD_AMOUNT_MEDIUM
#undef RAD_AMOUNT_HIGH
-#undef RAD_AMOUNT_EXTREME
\ No newline at end of file
+#undef RAD_AMOUNT_EXTREME
diff --git a/yogstation/code/game/objects/items/bandage.dm b/yogstation/code/game/objects/items/bandage.dm
index 76a9dd996305..04dca6cf70fa 100644
--- a/yogstation/code/game/objects/items/bandage.dm
+++ b/yogstation/code/game/objects/items/bandage.dm
@@ -95,7 +95,7 @@
to_chat(user, "This doesn't look like it'll work.")
return FALSE
-/obj/item/medical/bandage/proc/wash(obj/O, mob/user)
+/obj/item/medical/bandage/proc/wash2(obj/O, mob/user)
if (src.used)
to_chat(user, "You clean [src] fastidiously washing away as much of the detritus and residue as you can. The bandage can probably be used again now.")
name = "reused bandages"
diff --git a/yogstation/code/modules/clothing/shoes/special_shoes.dm b/yogstation/code/modules/clothing/shoes/special_shoes.dm
index d0cae94017ee..ff6114532aed 100644
--- a/yogstation/code/modules/clothing/shoes/special_shoes.dm
+++ b/yogstation/code/modules/clothing/shoes/special_shoes.dm
@@ -64,7 +64,7 @@
return FALSE
if(istype(I, /obj/item/clothing))
if(charges)
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ I.wash(CLEAN_WASH)
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
to_chat(user, "You've successfully cleaned [I] with [src]")
charges --
diff --git a/yogstation/code/modules/power/lighting.dm b/yogstation/code/modules/power/lighting.dm
index 58cd9bfe5ab9..28eb5259d72a 100644
--- a/yogstation/code/modules/power/lighting.dm
+++ b/yogstation/code/modules/power/lighting.dm
@@ -3,7 +3,7 @@
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_light)
/obj/machinery/light/proc/clean_light(O,strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
+ if(strength < CLEAN_TYPE_BLOOD)
return
bulb_colour = initial(bulb_colour)
update()