diff --git a/code/__DEFINES/acid.dm b/code/__DEFINES/acid.dm
new file mode 100644
index 00000000000..86199b67495
--- /dev/null
+++ b/code/__DEFINES/acid.dm
@@ -0,0 +1,21 @@
+/// The acid power required to destroy most closed turfs.
+#define ACID_POWER_MELT_TURF 200
+/// The maximum amount of damage (per tick) acid can deal to an [/obj].
+#define OBJ_ACID_DAMAGE_MAX 300
+/// Maximum acid volume that can be applied to an [/obj].
+#define OBJ_ACID_VOLUME_MAX 300
+/// Maximum acid volume that can be applied to a [/mob/living].
+#define MOB_ACID_VOLUME_MAX 1000
+/// Maximum acid volume that can be applied to a [/turf].
+#define TURF_ACID_VOLUME_MAX 12000
+
+// Acid decay rate constants.
+/// The constant factor for the acid decay rate.
+#define ACID_DECAY_BASE 1
+/// The scaling factor for the acid decay rate.
+#define ACID_DECAY_SCALING 1
+
+/// The default icon state for the acid overlay. Not to be confused with the error icon state.
+#define ACID_OVERLAY_DEFAULT "default"
+/// The combined acid power and acid volume required to burn hands.
+#define ACID_LEVEL_HANDBURN 20
diff --git a/code/__DEFINES/cleaning.dm b/code/__DEFINES/cleaning.dm
index 53f4887fa20..343956a0655 100644
--- a/code/__DEFINES/cleaning.dm
+++ b/code/__DEFINES/cleaning.dm
@@ -3,18 +3,28 @@
// 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)
+/// Cleans blood off of the cleanable atom.
+#define CLEAN_TYPE_BLOOD (1 << 0)
+/// Cleans runes off of the cleanable atom.
+#define CLEAN_TYPE_RUNES (1 << 1)
+/// Cleans fingerprints off of the cleanable atom.
+#define CLEAN_TYPE_FINGERPRINTS (1 << 2)
+/// Cleans fibres off of the cleanable atom.
+#define CLEAN_TYPE_FIBERS (1 << 3)
+/// Cleans radiation off of the cleanable atom.
+#define CLEAN_TYPE_RADIATION (1 << 4)
+/// Cleans diseases off of the cleanable atom.
+#define CLEAN_TYPE_DISEASE (1 << 5)
+/// Special type, add this flag to make some cleaning processes non-instant. Currently only used for showers when removing radiation.
+#define CLEAN_TYPE_WEAK (1 << 6)
+/// Cleans paint off of the cleanable atom.
+#define CLEAN_TYPE_PAINT (1 << 7)
+/// Cleans acid off of the cleanable atom.
+#define CLEAN_TYPE_ACID (1 << 8)
// 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_WASH (CLEAN_TYPE_BLOOD | CLEAN_TYPE_RUNES | CLEAN_TYPE_DISEASE | CLEAN_TYPE_ACID)
#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/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 14d5a38b64d..c605f5ea3d2 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -161,10 +161,21 @@
//from base of atom/movable/on_exit_storage(): (datum/component/storage/concrete/master_storage)
#define CONSIG_STORAGE_EXITED "storage_exited"
-///from base of atom/expose_reagents():
+///from base of atom/expose_reagents(): (/list, /datum/reagents, methods, volume_modifier, show_message)
#define COMSIG_ATOM_EXPOSE_REAGENTS "atom_expose_reagents"
/// Prevents the atom from being exposed to reagents if returned on [COMPONENT_ATOM_EXPOSE_REAGENTS]
#define COMPONENT_NO_EXPOSE_REAGENTS (1<<0)
+///from base of [/datum/reagent/proc/expose_atom]: (/datum/reagent, reac_volume)
+#define COMSIG_ATOM_EXPOSE_REAGENT "atom_expose_reagent"
+///from base of [/datum/reagent/proc/expose_atom]: (/atom, reac_volume)
+#define COMSIG_REAGENT_EXPOSE_ATOM "reagent_expose_atom"
+///from base of [/datum/reagent/proc/expose_atom]: (/obj, reac_volume)
+#define COMSIG_REAGENT_EXPOSE_OBJ "reagent_expose_obj"
+///from base of [/datum/reagent/proc/expose_atom]: (/mob/living, reac_volume, methods, show_message, touch_protection, /mob/camera/blob) // ovemind arg is only used by blob reagents.
+#define COMSIG_REAGENT_EXPOSE_MOB "reagent_expose_mob"
+///from base of [/datum/reagent/proc/expose_atom]: (/turf, reac_volume)
+#define COMSIG_REAGENT_EXPOSE_TURF "reagent_expose_turf"
+
///Called right before the atom changes the value of light_range to a different one, from base atom/set_light_range(): (new_range)
#define COMSIG_ATOM_SET_LIGHT_RANGE "atom_set_light_range"
///Called right before the atom changes the value of light_power to a different one, from base atom/set_light_power(): (new_power)
@@ -653,6 +664,8 @@
///Called on an object to "clean it", such as removing blood decals/overlays, etc. The clean types bitfield is sent with it. Return TRUE if any cleaning was necessary and thus performed.
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act"
+ ///Returned by cleanable components when they are cleaned.
+ #define COMPONENT_CLEANED (1<<0)
//Creamed
diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm
deleted file mode 100644
index 49c4f58ffa9..00000000000
--- a/code/controllers/subsystem/acid.dm
+++ /dev/null
@@ -1,37 +0,0 @@
-SUBSYSTEM_DEF(acid)
- name = "Acid"
- priority = FIRE_PRIORITY_ACID
- flags = SS_NO_INIT|SS_BACKGROUND
- runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
-
- var/list/currentrun = list()
- var/list/processing = list()
-
-/datum/controller/subsystem/acid/stat_entry(msg)
- msg = "P:[length(processing)]"
- return ..()
-
-
-/datum/controller/subsystem/acid/fire(resumed = FALSE)
- if (!resumed)
- src.currentrun = processing.Copy()
-
- //cache for sanic speed (lists are references anyways)
- var/list/currentrun = src.currentrun
-
- while (currentrun.len)
- var/obj/O = currentrun[currentrun.len]
- currentrun.len--
- if (!O || QDELETED(O))
- processing -= O
- if (MC_TICK_CHECK)
- return
- continue
-
- if(O.acid_level && O.acid_processing())
- else
- O.update_icon()
- processing -= O
-
- if (MC_TICK_CHECK)
- return
diff --git a/code/controllers/subsystem/processing/acid.dm b/code/controllers/subsystem/processing/acid.dm
new file mode 100644
index 00000000000..a92880f51e3
--- /dev/null
+++ b/code/controllers/subsystem/processing/acid.dm
@@ -0,0 +1,6 @@
+/// The subsystem used to tick [/datum/component/acid] instances.
+PROCESSING_SUBSYSTEM_DEF(acid)
+ name = "Acid"
+ priority = FIRE_PRIORITY_ACID
+ flags = SS_NO_INIT|SS_BACKGROUND
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm
new file mode 100644
index 00000000000..80487255bd7
--- /dev/null
+++ b/code/datums/components/acid.dm
@@ -0,0 +1,215 @@
+/** Component representing acid applied to an object.
+ *
+ * Must be attached to an atom.
+ * Processes, repeatedly damaging whatever it is attached to.
+ * If the parent atom is a turf it applies acid to the contents of the turf.
+ */
+/datum/component/acid
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ /// The strength of the acid on the parent [/atom].
+ var/acid_power
+ /// The volume of acid on the parent [/atom].
+ var/acid_volume
+ /// The maximum volume of acid on the parent [/atom].
+ var/max_volume = INFINITY
+ /// The ambiant sound of acid eating away at the parent [/atom].
+ var/datum/looping_sound/acid/sizzle
+ /// Used exclusively for melting turfs. TODO: Move integrity to the atom level so that this can be dealt with there.
+ var/parent_integrity = 30
+ /// The proc used to handle the parent [/atom] when processing. TODO: Unify damage and resistance flags so that this doesn't need to exist!
+ var/datum/callback/process_effect
+
+/datum/component/acid/Initialize(_acid_power, _acid_volume, _max_volume=null)
+ if((_acid_power) <= 0 || (_acid_volume <= 0))
+ stack_trace("Acid component added with insufficient acid power ([_acid_power]) or acid volume ([_acid_power]).")
+ return COMPONENT_INCOMPATIBLE // Not enough acid or the acid's too weak, either one.
+ if(!isatom(parent))
+ stack_trace("Acid component added to [parent] ([parent?.type]) which is not a /atom subtype.")
+ return COMPONENT_INCOMPATIBLE // Incompatible type. TODO: Rework take_damage to the atom level and move this there.
+
+ if(isobj(parent))
+ var/obj/parent_object = parent
+ if(parent_object.resistance_flags & UNACIDABLE) // The parent object cannot have acid. Should never happen, will happen.
+ stack_trace("Acid component added to unacidable object [parent].")
+ return COMPONENT_INCOMPATIBLE
+
+ max_volume = OBJ_ACID_VOLUME_MAX
+ process_effect = CALLBACK(src, .proc/process_obj, parent)
+ else if(isliving(parent))
+ max_volume = MOB_ACID_VOLUME_MAX
+ process_effect = CALLBACK(src, .proc/process_mob, parent)
+ else if(isturf(parent))
+ max_volume = TURF_ACID_VOLUME_MAX
+ process_effect = CALLBACK(src, .proc/process_turf, parent)
+
+ acid_power = _acid_power
+ set_volume(_acid_volume)
+
+ var/atom/parent_atom = parent
+ RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/on_update_overlays)
+ parent_atom.update_icon()
+ sizzle = new(list(parent), TRUE)
+ START_PROCESSING(SSacid, src)
+
+/datum/component/acid/Destroy(force, silent)
+ STOP_PROCESSING(SSacid, src)
+ if(sizzle)
+ QDEL_NULL(sizzle)
+ if(process_effect)
+ QDEL_NULL(process_effect)
+ UnregisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS)
+ if(parent && !QDELING(parent))
+ var/atom/parent_atom = parent
+ parent_atom.update_icon()
+ return ..()
+
+/datum/component/acid/RegisterWithParent()
+ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
+ RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/on_clean)
+ RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand)
+ RegisterSignal(parent, COMSIG_ATOM_EXPOSE_REAGENT, .proc/on_expose_reagent)
+ if(isturf(parent))
+ RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/on_crossed)
+
+/datum/component/acid/UnregisterFromParent()
+ UnregisterSignal(parent, list(
+ COMSIG_PARENT_EXAMINE,
+ COMSIG_COMPONENT_CLEAN_ACT,
+ COMSIG_ATOM_ATTACK_HAND,
+ COMSIG_ATOM_EXPOSE_REAGENT))
+
+ if(isturf(parent))
+ UnregisterSignal(parent, COMSIG_MOVABLE_CROSSED)
+
+/// Averages corrosive power and sums volume.
+/datum/component/acid/InheritComponent(datum/component/C, i_am_original, _acid_power, _acid_volume)
+ acid_power = ((acid_power * acid_volume) + (_acid_power * _acid_volume)) / (acid_volume + _acid_volume)
+ set_volume(acid_volume + _acid_volume)
+
+/// Sets the acid volume to a new value. Limits the acid volume by the amount allowed to exist on the parent atom.
+/datum/component/acid/proc/set_volume(new_volume)
+ acid_volume = clamp(new_volume, 0, max_volume)
+ if(!acid_volume)
+ qdel(src)
+
+
+/// Handles the slow corrosion of the parent [/atom].
+/datum/component/acid/process()
+ process_effect?.InvokeAsync()
+ if(QDELING(src)) //The process effect deals damage, and on turfs diminishes the acid volume, potentially destroying the component. Let's not destroy it twice.
+ return
+ set_volume(acid_volume - (ACID_DECAY_BASE + (ACID_DECAY_SCALING*round(sqrt(acid_volume)))))
+
+/// Handles processing on a [/obj].
+/datum/component/acid/proc/process_obj(obj/target)
+ if(target.resistance_flags & ACID_PROOF)
+ return
+ target.take_damage(min(1 + round(sqrt(acid_power * acid_volume)*0.3), OBJ_ACID_DAMAGE_MAX), BURN, ACID, 0)
+
+/// Handles processing on a [/mob/living].
+/datum/component/acid/proc/process_mob(mob/living/target)
+ target.acid_act(acid_power, acid_volume)
+
+/// Handles processing on a [/turf].
+/datum/component/acid/proc/process_turf(turf/target_turf)
+ var/acid_used = min(acid_volume * 0.05, 20)
+ var/applied_targets = 0
+ for(var/am in target_turf)
+ var/atom/movable/target_movable = am
+ if(target_movable.acid_act(acid_power, acid_used))
+ applied_targets++
+
+ if(applied_targets)
+ set_volume(acid_volume - (acid_used * applied_targets))
+
+ // Snowflake code for handling acid melting walls. TODO: Move integrity handling to the atom level so this can be desnowflaked.
+ if(acid_power < ACID_POWER_MELT_TURF)
+ return
+
+ switch(parent_integrity--)
+ if(-INFINITY to 0)
+ target_turf.visible_message("[target_turf] collapses under its own weight into a puddle of goop and undigested debris!")
+ target_turf.acid_melt()
+ if(0 to 4)
+ target_turf.visible_message("[target_turf] begins to crumble under the acid!")
+ if(4 to 8)
+ target_turf.visible_message("[target_turf] is struggling to withstand the acid!")
+ if(8 to 16)
+ target_turf.visible_message("[target_turf] is being melted by the acid!")
+ if(16 to 24)
+ target_turf.visible_message("[target_turf] is holding up against the acid!")
+
+
+/// Used to maintain the acid overlay on the parent [/atom].
+/datum/component/acid/proc/on_update_overlays(atom/parent_atom, list/overlays)
+ SIGNAL_HANDLER
+
+ overlays += mutable_appearance('icons/effects/acid.dmi', parent_atom.custom_acid_overlay || ACID_OVERLAY_DEFAULT)
+
+/// Alerts any examiners to the acid on the parent atom.
+/datum/component/acid/proc/on_examine(atom/A, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+
+ examine_list += "[A.p_theyre()] covered in corrosive liquid!"
+
+/// Makes it possible to clean acid off of objects.
+/datum/component/acid/proc/on_clean(atom/A, clean_types)
+ SIGNAL_HANDLER
+
+ if(!(clean_types & CLEAN_TYPE_ACID))
+ return NONE
+ qdel(src)
+ return COMPONENT_CLEANED
+
+/// Handles water diluting the acid on the object.
+/datum/component/acid/proc/on_expose_reagent(atom/parent_atom, datum/reagent/exposing_reagent, reac_volume)
+ SIGNAL_HANDLER
+
+ if(!istype(exposing_reagent, /datum/reagent/water))
+ return NONE
+
+ acid_power /= (acid_volume / (acid_volume + reac_volume))
+ set_volume(acid_volume + reac_volume)
+ return NONE
+
+
+/// Handles searing the hand of anyone who tries to touch this without protection.
+/datum/component/acid/proc/on_attack_hand(atom/parent_atom, mob/living/carbon/user)
+ SIGNAL_HANDLER
+
+ if(!istype(user))
+ return NONE
+ if((parent_atom == user) || (parent_atom.loc == user))
+ return NONE // So people can take their own clothes off.
+ if((acid_power * acid_volume) < ACID_LEVEL_HANDBURN)
+ return NONE
+ if(user.gloves?.resistance_flags & (UNACIDABLE|ACID_PROOF))
+ return NONE
+
+ var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
+ if(!affecting?.receive_damage(0, 5))
+ return NONE
+
+ to_chat(user, "The acid on \the [parent_atom] burns your hand!")
+ playsound(parent_atom, 'sound/weapons/sear.ogg', 50, TRUE)
+ user.update_damage_overlays()
+ return COMPONENT_NO_ATTACK_HAND
+
+/// Handles searing the feet of whoever walks over this without protection. Only active if the parent is a turf.
+/datum/component/acid/proc/on_crossed(atom/parent_atom, mob/living/crosser)
+ SIGNAL_HANDLER
+
+ if(!isliving(crosser))
+ return
+ if(crosser.movement_type & FLYING)
+ return
+ if(crosser.m_intent & MOVE_INTENT_WALK)
+ return
+ if(prob(60))
+ return
+
+ var/acid_used = min(acid_volume * 0.05, 20)
+ if(crosser.acid_act(acid_power, acid_used, FEET))
+ playsound(crosser, 'sound/weapons/sear.ogg', 50, TRUE)
+ to_chat(crosser, "The acid on the [parent] burns you!")
+ set_volume(max(acid_volume - acid_used, 10))
diff --git a/code/datums/components/bloodysoles.dm b/code/datums/components/bloodysoles.dm
index 3ef793899be..c3627cc80dc 100644
--- a/code/datums/components/bloodysoles.dm
+++ b/code/datums/components/bloodysoles.dm
@@ -206,12 +206,12 @@
SIGNAL_HANDLER
if(!(clean_types & CLEAN_TYPE_BLOOD) || last_blood_state == BLOOD_STATE_NOT_BLOODY)
- return
+ return NONE
bloody_shoes = list(BLOOD_STATE_HUMAN = 0, BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
last_blood_state = BLOOD_STATE_NOT_BLOODY
update_icon()
- return TRUE
+ return COMPONENT_CLEANED
/**
diff --git a/code/datums/components/creamed.dm b/code/datums/components/creamed.dm
index 2abdf6cff0a..d390e14c3ae 100644
--- a/code/datums/components/creamed.dm
+++ b/code/datums/components/creamed.dm
@@ -58,6 +58,9 @@ GLOBAL_LIST_INIT(creamable, typecacheof(list(
///Callback to remove pieface
/datum/component/creamed/proc/clean_up(datum/source, clean_types)
- if(clean_types & CLEAN_TYPE_BLOOD)
+ SIGNAL_HANDLER
+
+ . = NONE
+ if(!(clean_types & CLEAN_TYPE_BLOOD))
qdel(src)
- return TRUE
+ return COMPONENT_CLEANED
diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm
index 9a6f40ec95e..8214a374170 100644
--- a/code/datums/components/decal.dm
+++ b/code/datums/components/decal.dm
@@ -89,9 +89,10 @@
/datum/component/decal/proc/clean_react(datum/source, clean_types)
SIGNAL_HANDLER
+ . = NONE
if(clean_types & cleanable)
qdel(src)
- return TRUE
+ return COMPONENT_CLEANED
/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list)
SIGNAL_HANDLER
diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm
index 2622c0e2d6b..9d451a06b72 100644
--- a/code/datums/components/forensics.dm
+++ b/code/datums/components/forensics.dm
@@ -54,15 +54,16 @@
/datum/component/forensics/proc/clean_act(datum/source, clean_types)
SIGNAL_HANDLER
+ . = NONE
if(clean_types & CLEAN_TYPE_FINGERPRINTS)
wipe_fingerprints()
- . = TRUE
+ . = COMPONENT_CLEANED
if(clean_types & CLEAN_TYPE_BLOOD)
wipe_blood_DNA()
- . = TRUE
+ . = COMPONENT_CLEANED
if(clean_types & CLEAN_TYPE_FIBERS)
wipe_fibers()
- . = TRUE
+ . = COMPONENT_CLEANED
/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 7bf6c87afca..372f381aedb 100644
--- a/code/datums/components/infective.dm
+++ b/code/datums/components/infective.dm
@@ -51,9 +51,10 @@
/datum/component/infective/proc/clean(datum/source, clean_types)
SIGNAL_HANDLER
+ . = NONE
if(clean_types & required_clean_types)
qdel(src)
- return TRUE
+ return COMPONENT_CLEANED
/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force)
SIGNAL_HANDLER
diff --git a/code/datums/components/radioactive.dm b/code/datums/components/radioactive.dm
index 5f2c28b5c6c..bdbb9cf56d1 100644
--- a/code/datums/components/radioactive.dm
+++ b/code/datums/components/radioactive.dm
@@ -99,18 +99,19 @@
SIGNAL_HANDLER
if(QDELETED(src))
- return
+ return COMPONENT_CLEANED
if(!(clean_types & CLEAN_TYPE_RADIATION))
- return
+ return COMPONENT_CLEANED
if(!(clean_types & CLEAN_TYPE_WEAK))
qdel(src)
- return
+ return COMPONENT_CLEANED
strength = max(0, (strength - (RAD_BACKGROUND_RADIATION * 2)))
if(strength <= RAD_BACKGROUND_RADIATION)
qdel(src)
+ return COMPONENT_CLEANED
#undef RAD_AMOUNT_LOW
#undef RAD_AMOUNT_MEDIUM
diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm
index 23f020adb7f..cd8546c6a17 100644
--- a/code/datums/components/thermite.dm
+++ b/code/datums/components/thermite.dm
@@ -84,7 +84,7 @@
//Thermite is just some loose powder, you could probably clean it with your hands. << todo?
qdel(src)
- return TRUE
+ return COMPONENT_CLEANED
/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume)
SIGNAL_HANDLER
diff --git a/code/datums/looping_sounds/acid.dm b/code/datums/looping_sounds/acid.dm
new file mode 100644
index 00000000000..e461e5d02ce
--- /dev/null
+++ b/code/datums/looping_sounds/acid.dm
@@ -0,0 +1,5 @@
+/// Soundloop for the acid component.
+/datum/looping_sound/acid
+ mid_sounds = list('sound/items/welder.ogg' = 1)
+ mid_length = 10
+ volume = 150
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 1d9584981b6..f31bd028cb5 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -74,6 +74,9 @@
/// Radiation insulation types
var/rad_insulation = RAD_NO_INSULATION
+ /// The icon state intended to be used for the acid component. Used to override the default acid overlay icon state.
+ var/custom_acid_overlay = null
+
///The custom materials this atom is made of, used by a lot of things like furniture, walls, and floors (if I finish the functionality, that is.)
///The list referenced by this var can be shared by multiple objects and should not be directly modified. Instead, use [set_custom_materials][/atom/proc/set_custom_materials].
var/list/custom_materials
@@ -786,6 +789,7 @@
*/
/atom/proc/acid_act(acidpwr, acid_volume)
SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume)
+ return FALSE
/**
* Respond to an emag being used on our atom
@@ -990,7 +994,7 @@
*/
/atom/proc/wash(clean_types)
. = FALSE
- if(SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, clean_types))
+ if(SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, clean_types) & COMPONENT_CLEANED)
. = TRUE
// Basically "if has washable coloration"
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
deleted file mode 100644
index 3c40c1366f2..00000000000
--- a/code/game/objects/effects/alien_acid.dm
+++ /dev/null
@@ -1,93 +0,0 @@
-/obj/effect/acid
- gender = PLURAL
- name = "acid"
- desc = "Burbling corrosive stuff."
- icon_state = "acid"
- density = FALSE
- opacity = FALSE
- anchored = TRUE
- resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
- layer = ABOVE_NORMAL_TURF_LAYER
- var/turf/target
-
-
-/obj/effect/acid/Initialize(mapload, acid_pwr, acid_amt)
- . = ..()
-
- target = get_turf(src)
-
- if(acid_amt)
- acid_level = min(acid_amt*acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor.
-
- //handle APCs and newscasters and stuff nicely
- pixel_x = target.pixel_x + rand(-4,4)
- pixel_y = target.pixel_y + rand(-4,4)
-
- START_PROCESSING(SSobj, src)
-
-
-/obj/effect/acid/Destroy()
- STOP_PROCESSING(SSobj, src)
- target = null
- return ..()
-
-/obj/effect/acid/process()
- if(!target)
- qdel(src)
- return FALSE
-
- if(prob(5))
- playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
-
- for(var/obj/O in target)
- if(prob(20) && !(resistance_flags & UNACIDABLE))
- if(O.acid_level < acid_level*0.3)
- var/acid_used = min(acid_level*0.05, 20)
- O.acid_act(10, acid_used)
- acid_level = max(0, acid_level - acid_used*10)
-
- acid_level = max(acid_level - (5 + 2*round(sqrt(acid_level))), 0)
- if(acid_level <= 0)
- qdel(src)
- return FALSE
- return TRUE
-
-/obj/effect/acid/Crossed(AM as mob|obj)
- . = ..()
- if(isliving(AM))
- var/mob/living/L = AM
- if(L.movement_type & FLYING)
- return
- if(L.m_intent != MOVE_INTENT_WALK && prob(40))
- var/acid_used = min(acid_level*0.05, 20)
- if(L.acid_act(10, acid_used, "feet"))
- acid_level = max(0, acid_level - acid_used*10)
- playsound(L, 'sound/weapons/sear.ogg', 50, TRUE)
- to_chat(L, "[src] burns you!")
-
-//xenomorph corrosive acid
-/obj/effect/acid/alien
- var/target_strength = 30
-
-
-/obj/effect/acid/alien/process()
- . = ..()
- if(.)
- if(prob(45))
- playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
- target_strength--
- if(target_strength <= 0)
- target.visible_message("[target] collapses under its own weight into a puddle of goop and undigested debris!")
- target.acid_melt()
- qdel(src)
- else
-
- switch(target_strength)
- if(24)
- visible_message("[target] is holding up against the acid!")
- if(16)
- visible_message("[target] is being melted by the acid!")
- if(8)
- visible_message("[target] is struggling to withstand the acid!")
- if(4)
- visible_message("[target] begins to crumble under the acid!")
diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm
index 790b6c5a592..a09d686f510 100644
--- a/code/game/objects/effects/decals/remains.dm
+++ b/code/game/objects/effects/decals/remains.dm
@@ -8,6 +8,7 @@
playsound(src, 'sound/items/welder.ogg', 150, TRUE)
new /obj/effect/decal/cleanable/greenglow(drop_location())
qdel(src)
+ return TRUE
/obj/effect/decal/remains/human
desc = "They look like human remains. They have a strange aura about them."
diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm
index b6748426de0..b9a36855442 100644
--- a/code/game/objects/effects/effects.dm
+++ b/code/game/objects/effects/effects.dm
@@ -15,7 +15,7 @@
return
/obj/effect/acid_act()
- return
+ return FALSE
/obj/effect/blob_act(obj/structure/blob/B)
return
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index e0c96d05d7c..87bcb854396 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -208,11 +208,11 @@
take_damage(5, BURN, 0, 0)
/obj/structure/glowshroom/acid_act(acidpwr, acid_volume)
- . = 1
visible_message("[src] melts away!")
var/obj/effect/decal/cleanable/molten_object/I = new (get_turf(src))
I.desc = "Looks like this was \an [src] some time ago."
qdel(src)
+ return TRUE
/obj/structure/glowshroom/attackby(obj/item/I, mob/living/user, params)
if (istype(I, /obj/item/plant_analyzer))
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 1bfdaf105f8..d0dc6475956 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -365,15 +365,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
C.update_damage_overlays()
return
- if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid.
- var/mob/living/carbon/C = user
- if(istype(C))
- if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
- to_chat(user, "The acid on [src] burns your hand!")
- var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
- if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
- C.update_damage_overlays()
-
if(!(interaction_flags_item & INTERACT_ITEM_ATTACK_HAND_PICKUP)) //See if we're supposed to auto pickup.
return
diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm
index 199874bfdc7..dcda346c968 100644
--- a/code/game/objects/items/melee/misc.dm
+++ b/code/game/objects/items/melee/misc.dm
@@ -493,6 +493,7 @@
visible_message("The acid smacks into [src] and rapidly flashes to ash.",\
"You hear a loud crack as you are washed with a wave of heat.")
consume_everything()
+ return TRUE
/obj/item/melee/supermatter_sword/bullet_act(obj/projectile/P)
visible_message("[P] smacks into [src] and rapidly flashes to ash.",\
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 9a57ee62856..38ce00352a9 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -151,31 +151,15 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
///the obj's reaction when touched by acid
/obj/acid_act(acidpwr, acid_volume)
- if(!(resistance_flags & UNACIDABLE) && acid_volume)
-
- if(!acid_level)
- SSacid.processing[src] = src
- update_icon()
- var/acid_cap = acidpwr * 300 //so we cannot use huge amounts of weak acids to do as well as strong acids.
- if(acid_level < acid_cap)
- acid_level = min(acid_level + acidpwr * acid_volume, acid_cap)
- return 1
-
-///the proc called by the acid subsystem to process the acid that's on the obj
-/obj/proc/acid_processing()
- . = TRUE
- if(!(resistance_flags & ACID_PROOF))
- if(prob(33))
- playsound(loc, 'sound/items/welder.ogg', 150, TRUE)
- take_damage(min(1 + round(sqrt(acid_level)*0.3), 300), BURN, ACID, 0)
-
- acid_level = max(acid_level - (5 + 3*round(sqrt(acid_level))), 0)
- if(!acid_level)
+ . = ..()
+ if((resistance_flags & UNACIDABLE) || (acid_volume <= 0) || acidpwr <= 0)
return FALSE
+ AddComponent(/datum/component/acid, acidpwr, acid_volume)
+ return TRUE
+
///called when the obj is destroyed by acid.
/obj/proc/acid_melt()
- SSacid.processing -= src
deconstruct(FALSE)
//// FIRE
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 4104a1424ba..2b26cf1bb41 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -22,8 +22,6 @@
var/resistance_flags = NONE // INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ON_FIRE | UNACIDABLE | ACID_PROOF
- var/acid_level = 0 //how much acid is on that obj
-
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/current_skin //Has the item been reskinned?
var/list/unique_reskin //List of options to reskin.
@@ -355,8 +353,6 @@
/obj/update_overlays()
. = ..()
- if(acid_level)
- . += GLOB.acid_overlay
if(resistance_flags & ON_FIRE)
. += custom_fire_overlay ? custom_fire_overlay : GLOB.fire_overlay
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index ed92fb3fbcf..5317efdf3d4 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -302,7 +302,7 @@
busy = FALSE
reagents.remove_any(5)
- reagents.expose(user, TOUCH)
+ reagents.expose(user, TOUCH, 5 / max(reagents.total_volume, 5))
if(washing_face)
SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_FACE_ACT, CLEAN_WASH)
@@ -389,8 +389,7 @@
return 1
busy = FALSE
O.wash(CLEAN_WASH)
- O.acid_level = 0
- reagents.expose(O, TOUCH)
+ reagents.expose(O, TOUCH, 5 / max(reagents.total_volume, 5))
user.visible_message("[user] washes [O] using [src].", \
"You wash [O] using [src].")
return 1
@@ -566,10 +565,7 @@
return TRUE
busy = FALSE
O.wash(CLEAN_WASH)
- O.acid_level = 0
- create_reagents(5)
- reagents.add_reagent(dispensedreagent, 5)
- reagents.expose(O, TOUCH)
+ reagents.expose(O, TOUCH, 5 / max(reagents.total_volume, 5))
user.visible_message("[user] washes [O] using [src].", \
"You wash [O] using [src].")
return TRUE
diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm
index 9411630a726..736b6fb2bb8 100644
--- a/code/game/turfs/closed/walls.dm
+++ b/code/game/turfs/closed/walls.dm
@@ -251,7 +251,7 @@
/turf/closed/wall/acid_act(acidpwr, acid_volume)
if(explosion_block >= 2)
acidpwr = min(acidpwr, 50) //we reduce the power so strong walls never get melted.
- . = ..()
+ return ..()
/turf/closed/wall/acid_melt()
dismantle_wall(1)
diff --git a/code/game/turfs/open/floor/reinf_floor.dm b/code/game/turfs/open/floor/reinf_floor.dm
index 6ce8f41aa61..138bd093fdc 100644
--- a/code/game/turfs/open/floor/reinf_floor.dm
+++ b/code/game/turfs/open/floor/reinf_floor.dm
@@ -49,7 +49,7 @@
/turf/open/floor/engine/acid_act(acidpwr, acid_volume)
acidpwr = min(acidpwr, 50) //we reduce the power so reinf floor never get melted.
- . = ..()
+ return ..()
/turf/open/floor/engine/ex_act(severity,target)
var/shielded = is_shielded()
diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm
index 68048a2e70d..f294b7d915c 100644
--- a/code/game/turfs/open/lava.dm
+++ b/code/game/turfs/open/lava.dm
@@ -28,7 +28,7 @@
return src
/turf/open/lava/acid_act(acidpwr, acid_volume)
- return
+ return FALSE
/turf/open/lava/MakeDry(wet_setting = TURF_WET_WATER)
return
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index fdcd2759309..ad5b05bd1ec 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -501,22 +501,18 @@ GLOBAL_LIST_EMPTY(station_turfs)
return
/turf/acid_act(acidpwr, acid_volume)
- . = 1
- var/acid_type = /obj/effect/acid
- if(acidpwr >= 200) //alien acid power
- acid_type = /obj/effect/acid/alien
- var/has_acid_effect = FALSE
+ . = ..()
+ if((acidpwr <= 0) || (acid_volume <= 0))
+ return FALSE
+
+ AddComponent(/datum/component/acid, acidpwr, acid_volume)
for(var/obj/O in src)
if(intact && HAS_TRAIT(O, TRAIT_T_RAY_VISIBLE))
- return
- if(istype(O, acid_type))
- var/obj/effect/acid/A = O
- A.acid_level = min(acid_volume * acidpwr, 12000)//capping acid level to limit power of the acid
- has_acid_effect = 1
continue
+
O.acid_act(acidpwr, acid_volume)
- if(!has_acid_effect)
- new acid_type(src, acidpwr, acid_volume)
+
+ return . || TRUE
/turf/proc/acid_melt()
return
diff --git a/code/modules/antagonists/blob/blobstrains/_reagent.dm b/code/modules/antagonists/blob/blobstrains/_reagent.dm
index 0113013c957..5b7522c8d31 100644
--- a/code/modules/antagonists/blob/blobstrains/_reagent.dm
+++ b/code/modules/antagonists/blob/blobstrains/_reagent.dm
@@ -25,9 +25,11 @@
color = "#FFFFFF"
taste_description = "bad code and slime"
can_synth = FALSE
+ penetrates_skin = NONE
-/datum/reagent/blob/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
+/datum/reagent/blob/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
+ ..()
+ if(exposed_mob.stat == DEAD || istype(exposed_mob, /mob/living/simple_animal/hostile/blob))
return 0 //the dead, and blob mobs, don't cause reactions
return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume.
diff --git a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm
index 1a717787dec..2383dccf87f 100644
--- a/code/modules/antagonists/blob/blobstrains/blazing_oil.dm
+++ b/code/modules/antagonists/blob/blobstrains/blazing_oil.dm
@@ -31,11 +31,11 @@
taste_description = "burning oil"
color = "#B68D00"
-/datum/reagent/blob/blazing_oil/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/blazing_oil/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.adjust_fire_stacks(round(reac_volume/10))
- M.IgniteMob()
- if(M)
- M.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND)
- if(iscarbon(M))
- M.emote("scream")
+ exposed_mob.adjust_fire_stacks(round(reac_volume/10))
+ exposed_mob.IgniteMob()
+ if(exposed_mob)
+ exposed_mob.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND)
+ if(iscarbon(exposed_mob))
+ exposed_mob.emote("scream")
diff --git a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm
index ebfc84f008d..8dea4c1ab5b 100644
--- a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm
+++ b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm
@@ -16,17 +16,17 @@
color = "#8BA6E9"
taste_description = "brain freeze"
-/datum/reagent/blob/cryogenic_poison/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/cryogenic_poison/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- if(M.reagents)
- M.reagents.add_reagent(/datum/reagent/consumable/frostoil, 0.3*reac_volume)
- M.reagents.add_reagent(/datum/reagent/consumable/ice, 0.3*reac_volume)
- M.reagents.add_reagent(/datum/reagent/blob/cryogenic_poison, 0.3*reac_volume)
- M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ if(exposed_mob.reagents)
+ exposed_mob.reagents.add_reagent(/datum/reagent/consumable/frostoil, 0.3*reac_volume)
+ exposed_mob.reagents.add_reagent(/datum/reagent/consumable/ice, 0.3*reac_volume)
+ exposed_mob.reagents.add_reagent(/datum/reagent/blob/cryogenic_poison, 0.3*reac_volume)
+ exposed_mob.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
-/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/M)
- M.adjustBruteLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE)
- M.adjustFireLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE)
- M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE)
+/datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/exposed_mob)
+ exposed_mob.adjustBruteLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE)
+ exposed_mob.adjustFireLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE)
+ exposed_mob.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER, FALSE)
. = 1
..()
diff --git a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm
index 4f2f802f78b..59b14d611b7 100644
--- a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm
+++ b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm
@@ -24,17 +24,17 @@
name = "Distributed Neurons"
color = "#E88D5D"
-/datum/reagent/blob/distributed_neurons/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/distributed_neurons/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.apply_damage(0.6*reac_volume, TOX)
- if(O && ishuman(M))
- if(M.stat == UNCONSCIOUS || M.stat == HARD_CRIT)
- M.death() //sleeping in a fight? bad plan.
- if(M.stat == DEAD && O.can_buy(5))
- var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore(get_turf(M))
- BS.overmind = O
- BS.update_icons()
- O.blob_mobs.Add(BS)
- BS.Zombify(M)
- O.add_points(-5)
- to_chat(O, "Spent 5 resources for the zombification of [M].")
+ exposed_mob.apply_damage(0.6*reac_volume, TOX)
+ if(overmind && ishuman(exposed_mob))
+ if(exposed_mob.stat == UNCONSCIOUS || exposed_mob.stat == HARD_CRIT)
+ exposed_mob.death() //sleeping in a fight? bad plan.
+ if(exposed_mob.stat == DEAD && overmind.can_buy(5))
+ var/mob/living/simple_animal/hostile/blob/blobspore/spore = new/mob/living/simple_animal/hostile/blob/blobspore(get_turf(exposed_mob))
+ spore.overmind = overmind
+ spore.update_icons()
+ overmind.blob_mobs.Add(spore)
+ spore.Zombify(exposed_mob)
+ overmind.add_points(-5)
+ to_chat(overmind, "Spent 5 resources for the zombification of [exposed_mob].")
diff --git a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm
index 02a8c914d12..f92f71c5388 100644
--- a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm
+++ b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm
@@ -29,9 +29,9 @@
taste_description = "pop rocks"
color = "#83ECEC"
-/datum/reagent/blob/electromagnetic_web/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/electromagnetic_web/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
if(prob(reac_volume*2))
- M.emp_act(EMP_LIGHT)
- if(M)
- M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND)
+ exposed_mob.emp_act(EMP_LIGHT)
+ if(exposed_mob)
+ exposed_mob.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND)
diff --git a/code/modules/antagonists/blob/blobstrains/energized_jelly.dm b/code/modules/antagonists/blob/blobstrains/energized_jelly.dm
index 1bf4b0b54f4..305d22d540f 100644
--- a/code/modules/antagonists/blob/blobstrains/energized_jelly.dm
+++ b/code/modules/antagonists/blob/blobstrains/energized_jelly.dm
@@ -26,9 +26,9 @@
taste_description = "gelatin"
color = "#EFD65A"
-/datum/reagent/blob/energized_jelly/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/energized_jelly/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.losebreath += round(0.2*reac_volume)
- M.adjustStaminaLoss(reac_volume * 1.2)
- if(M)
- M.apply_damage(0.6*reac_volume, OXY)
+ exposed_mob.losebreath += round(0.2*reac_volume)
+ exposed_mob.adjustStaminaLoss(reac_volume * 1.2)
+ if(exposed_mob)
+ exposed_mob.apply_damage(0.6*reac_volume, OXY)
diff --git a/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm
index 3324df30f9b..c49a103f6d6 100644
--- a/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm
+++ b/code/modules/antagonists/blob/blobstrains/explosive_lattice.dm
@@ -17,7 +17,7 @@
else if(damage_flag != MELEE && damage_flag != BULLET && damage_flag != LASER)
return damage * 1.5
return ..()
-
+
/datum/blobstrain/reagent/explosive_lattice/on_sporedeath(mob/living/spore)
var/obj/effect/temp_visual/explosion/fast/effect = new /obj/effect/temp_visual/explosion/fast(get_turf(spore))
effect.alpha = 150
@@ -31,18 +31,23 @@
taste_description = "the bomb"
color = "#8B2500"
-/datum/reagent/blob/explosive_lattice/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/explosive_lattice/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
var/initial_volume = reac_volume
reac_volume = ..()
if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming
- var/obj/effect/temp_visual/explosion/fast/E = new /obj/effect/temp_visual/explosion/fast(get_turf(M))
- E.alpha = 150
- for(var/mob/living/L in orange(get_turf(M), 1))
- if(ROLE_BLOB in L.faction) //no friendly fire
+ var/obj/effect/temp_visual/explosion/fast/ex_effect = new /obj/effect/temp_visual/explosion/fast(get_turf(exposed_mob))
+ ex_effect.alpha = 150
+ for(var/mob/living/nearby_mob in orange(get_turf(exposed_mob), 1))
+ if(ROLE_BLOB in nearby_mob.faction) //no friendly fire
continue
- var/aoe_volume = ..(L, TOUCH, initial_volume, 0, L.get_permeability_protection(), O)
- L.apply_damage(0.4*aoe_volume, BRUTE, wound_bonus=CANT_WOUND)
- if(M)
- M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ exposed_mob = nearby_mob
+ methods = TOUCH
+ reac_volume = initial_volume
+ show_message = FALSE
+ touch_protection = nearby_mob.get_permeability_protection()
+ var/aoe_volume = ..()
+ nearby_mob.apply_damage(0.4*aoe_volume, BRUTE, wound_bonus=CANT_WOUND)
+ if(exposed_mob)
+ exposed_mob.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
else
- M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ exposed_mob.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
diff --git a/code/modules/antagonists/blob/blobstrains/networked_fibers.dm b/code/modules/antagonists/blob/blobstrains/networked_fibers.dm
index cc08a4a197d..f559e722f40 100644
--- a/code/modules/antagonists/blob/blobstrains/networked_fibers.dm
+++ b/code/modules/antagonists/blob/blobstrains/networked_fibers.dm
@@ -36,8 +36,8 @@
taste_description = "efficiency"
color = "#4F4441"
-/datum/reagent/blob/networked_fibers/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/networked_fibers/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
- if(!QDELETED(M))
- M.apply_damage(0.6*reac_volume, BURN, wound_bonus=CANT_WOUND)
+ exposed_mob.apply_damage(0.6*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ if(!QDELETED(exposed_mob))
+ exposed_mob.apply_damage(0.6*reac_volume, BURN, wound_bonus=CANT_WOUND)
diff --git a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm
index 2281e1b59be..a8fd6c45b6b 100644
--- a/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm
+++ b/code/modules/antagonists/blob/blobstrains/pressurized_slime.dm
@@ -39,14 +39,13 @@
taste_description = "a sponge"
color = "#AAAABB"
-/datum/reagent/blob/pressurized_slime/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/pressurized_slime/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- var/turf/open/T = get_turf(M)
- if(istype(T) && prob(reac_volume))
- T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
- M.adjust_fire_stacks(-(reac_volume / 10))
- M.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
- if(M)
- M.apply_damage(0.4*reac_volume, OXY)
- if(M)
- M.adjustStaminaLoss(reac_volume)
+ var/turf/open/location_turf = get_turf(exposed_mob)
+ if(istype(location_turf) && prob(reac_volume))
+ location_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
+ exposed_mob.adjust_fire_stacks(-(reac_volume / 10))
+ exposed_mob.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ if(exposed_mob)
+ exposed_mob.adjustStaminaLoss(reac_volume, FALSE)
+ exposed_mob.apply_damage(0.4 * reac_volume, OXY)
diff --git a/code/modules/antagonists/blob/blobstrains/reactive_spines.dm b/code/modules/antagonists/blob/blobstrains/reactive_spines.dm
index 8286bb63fe9..24d344e328b 100644
--- a/code/modules/antagonists/blob/blobstrains/reactive_spines.dm
+++ b/code/modules/antagonists/blob/blobstrains/reactive_spines.dm
@@ -24,7 +24,8 @@
taste_description = "rock"
color = "#9ACD32"
-/datum/reagent/blob/reactive_spines/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
- if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
+/datum/reagent/blob/reactive_spines/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
+ ..()
+ if(exposed_mob.stat == DEAD || istype(exposed_mob, /mob/living/simple_animal/hostile/blob))
return 0 //the dead, and blob mobs, don't cause reactions
- M.adjustBruteLoss(reac_volume)
+ exposed_mob.adjustBruteLoss(reac_volume)
diff --git a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm
index 499f29da3c1..0df84417c6d 100644
--- a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm
+++ b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm
@@ -15,13 +15,13 @@
taste_description = "heaven"
color = "#A88FB7"
-/datum/reagent/blob/regenerative_materia/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/regenerative_materia/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.adjust_drugginess(reac_volume)
- if(M.reagents)
- M.reagents.add_reagent(/datum/reagent/blob/regenerative_materia, 0.2*reac_volume)
- M.reagents.add_reagent(/datum/reagent/toxin/spore, 0.2*reac_volume)
- M.apply_damage(0.7*reac_volume, TOX)
+ exposed_mob.adjust_drugginess(reac_volume)
+ if(exposed_mob.reagents)
+ exposed_mob.reagents.add_reagent(/datum/reagent/blob/regenerative_materia, 0.2*reac_volume)
+ exposed_mob.reagents.add_reagent(/datum/reagent/toxin/spore, 0.2*reac_volume)
+ exposed_mob.apply_damage(0.7*reac_volume, TOX)
/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/carbon/C)
C.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER)
diff --git a/code/modules/antagonists/blob/blobstrains/replicating_foam.dm b/code/modules/antagonists/blob/blobstrains/replicating_foam.dm
index a31426ca060..236d7dea737 100644
--- a/code/modules/antagonists/blob/blobstrains/replicating_foam.dm
+++ b/code/modules/antagonists/blob/blobstrains/replicating_foam.dm
@@ -30,6 +30,6 @@
taste_description = "duplication"
color = "#7B5A57"
-/datum/reagent/blob/replicating_foam/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/replicating_foam/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ exposed_mob.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
diff --git a/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm
index 85ae2fd5df1..95be6543526 100644
--- a/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm
+++ b/code/modules/antagonists/blob/blobstrains/shifting_fragments.dm
@@ -31,6 +31,6 @@
name = "Shifting Fragments"
color = "#C8963C"
-/datum/reagent/blob/shifting_fragments/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/shifting_fragments/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ exposed_mob.apply_damage(0.7*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
diff --git a/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm
index f0645badf29..c39728ad1dc 100644
--- a/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm
+++ b/code/modules/antagonists/blob/blobstrains/synchronous_mesh.dm
@@ -29,11 +29,11 @@
taste_description = "toxic mold"
color = "#65ADA2"
-/datum/reagent/blob/synchronous_mesh/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
+/datum/reagent/blob/synchronous_mesh/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind)
reac_volume = ..()
- M.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
- if(M && reac_volume)
- for(var/obj/structure/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume
- if(M)
- B.blob_attack_animation(M) //show them they're getting a bad time
- M.apply_damage(0.3*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ exposed_mob.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
+ if(exposed_mob && reac_volume)
+ for(var/obj/structure/blob/nearby_blob in range(1, exposed_mob)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.6*reac_volume
+ if(exposed_mob)
+ nearby_blob.blob_attack_animation(exposed_mob) //show them they're getting a bad time
+ exposed_mob.apply_damage(0.3*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 9206971bbd7..5ac84779aca 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -602,27 +602,27 @@
reagent_state = LIQUID
color = "#FFEBEB"
-/datum/reagent/flightpotion/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message = 1)
- if(iscarbon(M) && M.stat != DEAD)
- var/mob/living/carbon/C = M
- var/holycheck = ishumanbasic(C)
- if(reac_volume < 5 || !(holycheck || islizard(C) || (ismoth(C) && C.dna.features["moth_wings"] != "Burnt Off"))) // implying xenohumans are holy //as with all things,
+/datum/reagent/flightpotion/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE)
+ . = ..()
+ if(iscarbon(exposed_mob) && exposed_mob.stat != DEAD)
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ var/holycheck = ishumanbasic(exposed_carbon)
+ if(reac_volume < 5 || !(holycheck || islizard(exposed_carbon) || (ismoth(exposed_carbon) && exposed_carbon.dna.features["moth_wings"] != "Burnt Off"))) // implying xenohumans are holy //as with all things,
if((methods & INGEST) && show_message)
- to_chat(C, "You feel nothing but a terrible aftertaste.")
- return ..()
- if(C.dna.species.has_innate_wings)
- to_chat(C, "A terrible pain travels down your back as your wings change shape!")
- C.dna.features["moth_wings"] = "None"
+ to_chat(exposed_carbon, "You feel nothing but a terrible aftertaste.")
+ return
+ if(exposed_carbon.dna.species.has_innate_wings)
+ to_chat(exposed_carbon, "A terrible pain travels down your back as your wings change shape!")
+ exposed_carbon.dna.features["moth_wings"] = "None"
else
- to_chat(C, "A terrible pain travels down your back as wings burst out!")
- C.dna.species.GiveSpeciesFlight(C)
+ to_chat(exposed_carbon, "A terrible pain travels down your back as wings burst out!")
+ exposed_carbon.dna.species.GiveSpeciesFlight(exposed_carbon)
if(holycheck)
- to_chat(C, "You feel blessed!")
- ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
- playsound(C.loc, 'sound/items/poster_ripped.ogg', 50, TRUE, -1)
- C.adjustBruteLoss(20)
- C.emote("scream")
- ..()
+ to_chat(exposed_carbon, "You feel blessed!")
+ ADD_TRAIT(exposed_carbon, TRAIT_HOLY, SPECIES_TRAIT)
+ playsound(exposed_carbon.loc, 'sound/items/poster_ripped.ogg', 50, TRUE, -1)
+ exposed_carbon.adjustBruteLoss(20)
+ exposed_carbon.emote("scream")
/obj/item/jacobs_ladder
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 4b175560a2d..1b45653fa03 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -156,7 +156,7 @@ Doesn't work on other aliens/AI.*/
/obj/effect/proc_holder/alien/acid/proc/corrode(atom/target,mob/living/carbon/user = usr)
if(target in oview(1,user))
- if(target.acid_act(200, 100))
+ if(target.acid_act(200, 1000))
user.visible_message("[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!")
return TRUE
else
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index cdfb56181f8..5318df68098 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -948,7 +948,7 @@
/mob/living/carbon/extinguish_mob()
for(var/X in get_equipped_items())
var/obj/item/I = X
- I.acid_level = 0 //washes off the acid on our clothes
+ I.wash(CLEAN_TYPE_ACID) //washes off the acid on our clothes
I.extinguish() //extinguishes our clothes
..()
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 86ac018a071..5cbc75c2467 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -617,9 +617,9 @@
inventory_items_to_kill += held_items
- for(var/obj/item/I in inventory_items_to_kill)
- I.acid_act(acidpwr, acid_volume)
- return 1
+ for(var/obj/item/inventory_item in inventory_items_to_kill)
+ inventory_item.acid_act(acidpwr, acid_volume)
+ return TRUE
///Overrides the point value that the mob is worth
/mob/living/carbon/human/singularity_act()
diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm
index e9ca82318d1..eae689588f9 100644
--- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm
@@ -145,7 +145,7 @@
apply_damage(damage, BRUTE, affecting)
/mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit)
- . = 1
+ . = TRUE
if(!bodyzone_hit || bodyzone_hit == BODY_ZONE_HEAD)
if(wear_mask)
if(!(wear_mask.resistance_flags & UNACIDABLE))
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 528ae40753e..d5df01524bf 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -316,7 +316,7 @@
/mob/living/acid_act(acidpwr, acid_volume)
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
- return 1
+ return TRUE
///As the name suggests, this should be called to apply electric shocks.
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 7f722b9eae1..0003b3cc12d 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -74,6 +74,8 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
var/datum/material/material
///A list of causes why this chem should skip being removed, if the length is 0 it will be removed from holder naturally, if this is >0 it will not be removed from the holder.
var/list/reagent_removal_skip_list = list()
+ ///The set of exposure methods this penetrates skin with.
+ var/penetrates_skin = VAPOR
/datum/reagent/New()
SHOULD_CALL_PARENT(TRUE)
@@ -90,28 +92,37 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
holder = null
/// Applies this reagent to an [/atom]
-/datum/reagent/proc/expose_atom(atom/A, volume)
- return
+/datum/reagent/proc/expose_atom(atom/exposed_atom, reac_volume)
+ SHOULD_CALL_PARENT(TRUE)
+
+ SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_ATOM, exposed_atom, reac_volume)
+ SEND_SIGNAL(exposed_atom, COMSIG_ATOM_EXPOSE_REAGENT, src, reac_volume)
+ return TRUE
/// Applies this reagent to a [/mob/living]
-/datum/reagent/proc/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
- if(!istype(M))
- return FALSE
- if(methods & VAPOR) //smoke, foam, spray
- if(M.reagents)
- var/modifier = clamp((1 - touch_protection), 0, 1)
- var/amount = round(reac_volume*modifier, 0.1)
- if(amount >= 0.5)
- M.reagents.add_reagent(type, amount)
+/datum/reagent/proc/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ SHOULD_CALL_PARENT(TRUE)
+
+ SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_MOB, exposed_mob, methods, reac_volume, show_message, touch_protection)
+ if((methods & penetrates_skin) && exposed_mob.reagents) //smoke, foam, spray
+ var/amount = round(reac_volume*clamp((1 - touch_protection), 0, 1), 0.1)
+ if(amount >= 0.5)
+ exposed_mob.reagents.add_reagent(type, amount)
return TRUE
/// Applies this reagent to an [/obj]
-/datum/reagent/proc/expose_obj(obj/O, volume)
- return
+/datum/reagent/proc/expose_obj(obj/exposed_obj, reac_volume)
+ SHOULD_CALL_PARENT(TRUE)
+
+ SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_OBJ, exposed_obj, reac_volume)
+ return TRUE
/// Applies this reagent to a [/turf]
-/datum/reagent/proc/expose_turf(turf/T, volume)
- return
+/datum/reagent/proc/expose_turf(turf/exposed_turf, reac_volume)
+ SHOULD_CALL_PARENT(TRUE)
+
+ SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_TURF, exposed_turf, reac_volume)
+ return TRUE
/// Called from [/datum/reagents/proc/metabolize]
/datum/reagent/proc/on_mob_life(mob/living/carbon/M)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index e64b8145f77..855f7cc84d6 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -48,35 +48,36 @@ All effects don't start immediately, but rather get worse over time; the rate is
L.applyOrganDamage(((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * L.alcohol_tolerance, 0))/150))
return ..()
-/datum/reagent/consumable/ethanol/expose_obj(obj/O, reac_volume)
- if(istype(O, /obj/item/paper))
- var/obj/item/paper/paperaffected = O
+/datum/reagent/consumable/ethanol/expose_obj(obj/exposed_obj, reac_volume)
+ if(istype(exposed_obj, /obj/item/paper))
+ var/obj/item/paper/paperaffected = exposed_obj
paperaffected.clearpaper()
to_chat(usr, "[paperaffected]'s ink washes away.")
- if(istype(O, /obj/item/book))
+ if(istype(exposed_obj, /obj/item/book))
if(reac_volume >= 5)
- var/obj/item/book/affectedbook = O
+ var/obj/item/book/affectedbook = exposed_obj
affectedbook.dat = null
- O.visible_message("[O]'s writing is washed away by [name]!")
+ exposed_obj.visible_message("[exposed_obj]'s writing is washed away by [name]!")
else
- O.visible_message("[O]'s ink is smeared by [name], but doesn't wash away!")
- return
+ exposed_obj.visible_message("[exposed_obj]'s ink is smeared by [name], but doesn't wash away!")
+ return ..()
-/datum/reagent/consumable/ethanol/expose_mob(mob/living/M, methods=TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel.
- if(!isliving(M))
+/datum/reagent/consumable/ethanol/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel.
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR|PATCH)))
return
- if(methods & (TOUCH|VAPOR|PATCH))
- M.adjust_fire_stacks(reac_volume / 15)
+ exposed_mob.adjust_fire_stacks(reac_volume / 15)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- var/power_multiplier = boozepwr / 65 // Weak alcohol has less sterilizing power
+ if(!iscarbon(exposed_mob))
+ return
- for(var/s in C.surgeries)
- var/datum/surgery/S = s
- S.speed_modifier = max(0.1*power_multiplier, S.speed_modifier)
- return ..()
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ var/power_multiplier = boozepwr / 65 // Weak alcohol has less sterilizing power
+
+ for(var/s in exposed_carbon.surgeries)
+ var/datum/surgery/surgery = s
+ surgery.speed_modifier = max(0.1*power_multiplier, surgery.speed_modifier)
/datum/reagent/consumable/ethanol/beer
name = "Beer"
diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
index 622bd73c77e..85a8754e771 100644
--- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm
@@ -189,16 +189,15 @@
..()
. = TRUE
-/datum/reagent/medicine/c2/hercuri/expose_mob(mob/living/carbon/M, methods=VAPOR, reac_volume)
+/datum/reagent/medicine/c2/hercuri/expose_mob(mob/living/carbon/exposed_mob, methods=VAPOR, reac_volume)
+ . = ..()
if(!(methods & VAPOR))
return
- M.adjust_bodytemperature(-reac_volume * TEMPERATURE_DAMAGE_COEFFICIENT, 50)
- M.adjust_fire_stacks(-reac_volume / 2)
+ exposed_mob.adjust_bodytemperature(-reac_volume * TEMPERATURE_DAMAGE_COEFFICIENT, 50)
+ exposed_mob.adjust_fire_stacks(-reac_volume / 2)
if(reac_volume >= metabolization_rate)
- M.extinguish_mob()
-
- ..()
+ exposed_mob.extinguish_mob()
/datum/reagent/medicine/c2/hercuri/overdose_process(mob/living/carbon/M)
M.adjust_bodytemperature(-10*TEMPERATURE_DAMAGE_COEFFICIENT*REM,50) //chilly chilly
@@ -412,25 +411,27 @@
reagent_state = LIQUID
color = "#FFEBEB"
-/datum/reagent/medicine/c2/synthflesh/expose_mob(mob/living/M, methods=TOUCH, reac_volume,show_message = 1)
- if(iscarbon(M))
- var/mob/living/carbon/carbies = M
- if (carbies.stat == DEAD)
- show_message = 0
- if(methods & (PATCH|TOUCH|VAPOR))
- var/harmies = min(carbies.getBruteLoss(),carbies.adjustBruteLoss(-1.25 * reac_volume)*-1)
- var/burnies = min(carbies.getFireLoss(),carbies.adjustFireLoss(-1.25 * reac_volume)*-1)
- for(var/i in carbies.all_wounds)
- var/datum/wound/iter_wound = i
- iter_wound.on_synthflesh(reac_volume)
- carbies.adjustToxLoss((harmies+burnies)*0.66)
- if(show_message)
- to_chat(carbies, "You feel your burns and bruises healing! It stings like hell!")
- SEND_SIGNAL(carbies, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
- if(HAS_TRAIT_FROM(M, TRAIT_HUSK, "burn") && carbies.getFireLoss() < THRESHOLD_UNHUSK && (carbies.reagents.get_reagent_amount(/datum/reagent/medicine/c2/synthflesh) + reac_volume >= 100))
- carbies.cure_husk("burn")
- carbies.visible_message("A rubbery liquid coats [carbies]'s burns. [carbies] looks a lot healthier!") //we're avoiding using the phrases "burnt flesh" and "burnt skin" here because carbies could be a skeleton or a golem or something
- ..()
+/datum/reagent/medicine/c2/synthflesh/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE)
+ . = ..()
+ if(!iscarbon(exposed_mob))
+ return TRUE
+ var/mob/living/carbon/carbies = exposed_mob
+ if(carbies.stat == DEAD)
+ show_message = 0
+ if(!(methods & (PATCH|TOUCH|VAPOR)))
+ return TRUE
+ var/harmies = min(carbies.getBruteLoss(),carbies.adjustBruteLoss(-1.25 * reac_volume)*-1)
+ var/burnies = min(carbies.getFireLoss(),carbies.adjustFireLoss(-1.25 * reac_volume)*-1)
+ for(var/i in carbies.all_wounds)
+ var/datum/wound/iter_wound = i
+ iter_wound.on_synthflesh(reac_volume)
+ carbies.adjustToxLoss((harmies+burnies)*0.66)
+ if(show_message)
+ to_chat(carbies, "You feel your burns and bruises healing! It stings like hell!")
+ SEND_SIGNAL(carbies, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ if(HAS_TRAIT_FROM(exposed_mob, TRAIT_HUSK, "burn") && carbies.getFireLoss() < THRESHOLD_UNHUSK && (carbies.reagents.get_reagent_amount(/datum/reagent/medicine/c2/synthflesh) + reac_volume >= 100))
+ carbies.cure_husk("burn")
+ carbies.visible_message("A rubbery liquid coats [carbies]'s burns. [carbies] looks a lot healthier!") //we're avoiding using the phrases "burnt flesh" and "burnt skin" here because carbies could be a skeleton or a golem or something
return TRUE
/******ORGAN HEALING******/
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index cc4eeac235b..d5fd7418e85 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -515,11 +515,11 @@
glass_name = "glass of Pwr Game"
glass_desc = "Goes well with a Vlad's salad."
-/datum/reagent/consumable/pwr_game/expose_mob(mob/living/C, methods=TOUCH, reac_volume)
- ..()
- if(C?.mind?.get_skill_level(/datum/skill/gaming) >= SKILL_LEVEL_LEGENDARY && (methods & INGEST) && !HAS_TRAIT(C, TRAIT_GAMERGOD))
- ADD_TRAIT(C, TRAIT_GAMERGOD, "pwr_game")
- to_chat(C, "As you imbibe the Pwr Game, your gamer third eye opens... \
+/datum/reagent/consumable/pwr_game/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(exposed_mob?.mind?.get_skill_level(/datum/skill/gaming) >= SKILL_LEVEL_LEGENDARY && (methods & INGEST) && !HAS_TRAIT(exposed_mob, TRAIT_GAMERGOD))
+ ADD_TRAIT(exposed_mob, TRAIT_GAMERGOD, "pwr_game")
+ to_chat(exposed_mob, "As you imbibe the Pwr Game, your gamer third eye opens... \
You feel as though a great secret of the universe has been made known to you...")
/datum/reagent/consumable/pwr_game/on_mob_life(mob/living/carbon/M)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 12f045771a0..07aa33cf5d8 100755
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -24,20 +24,21 @@
return
holder.remove_reagent(type, metabolization_rate)
-/datum/reagent/consumable/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if((methods & INGEST) && quality && !HAS_TRAIT(M, TRAIT_AGEUSIA))
- switch(quality)
- if (DRINK_NICE)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_nice)
- if (DRINK_GOOD)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_good)
- if (DRINK_VERYGOOD)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_verygood)
- if (DRINK_FANTASTIC)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic)
- if (FOOD_AMAZING)
- SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste)
- return ..()
+/datum/reagent/consumable/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!(methods & INGEST) || !quality || HAS_TRAIT(exposed_mob, TRAIT_AGEUSIA))
+ return
+ switch(quality)
+ if (DRINK_NICE)
+ SEND_SIGNAL(exposed_mob, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_nice)
+ if (DRINK_GOOD)
+ SEND_SIGNAL(exposed_mob, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_good)
+ if (DRINK_VERYGOOD)
+ SEND_SIGNAL(exposed_mob, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_verygood)
+ if (DRINK_FANTASTIC)
+ SEND_SIGNAL(exposed_mob, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic)
+ if (FOOD_AMAZING)
+ SEND_SIGNAL(exposed_mob, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste)
/datum/reagent/consumable/nutriment
name = "Nutriment"
@@ -124,49 +125,49 @@
taste_description = "oil"
nutriment_factor = 7 * REAGENTS_METABOLISM //Not very healthy on its own
metabolization_rate = 10 * REAGENTS_METABOLISM
+ penetrates_skin = NONE
var/fry_temperature = 450 //Around ~350 F (117 C) which deep fryers operate around in the real world
-/datum/reagent/consumable/cooking_oil/expose_obj(obj/O, reac_volume)
- if(holder && holder.chem_temp >= fry_temperature)
- if(isitem(O) && !istype(O, /obj/item/food/deepfryholder))
- O.loc.visible_message("[O] rapidly fries as it's splashed with hot oil! Somehow.")
- var/obj/item/food/deepfryholder/F = new(O.drop_location(), O)
- F.fry(volume)
- F.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume)
-
-/datum/reagent/consumable/cooking_oil/expose_mob(mob/living/M, methods = TOUCH, reac_volume, show_message = 1, touch_protection = 0)
- if(!istype(M))
+/datum/reagent/consumable/cooking_oil/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if(!holder || (holder.chem_temp <= fry_temperature))
return
- var/boiling = FALSE
- if(holder && holder.chem_temp >= fry_temperature)
- boiling = TRUE
- if(!(methods & (VAPOR|TOUCH))) //Directly coats the mob, and doesn't go into their bloodstream
- return ..()
- if(!boiling)
- return TRUE
+ if(!isitem(exposed_obj) || istype(exposed_obj, /obj/item/food/deepfryholder))
+ return
+ exposed_obj.loc.visible_message("[exposed_obj] rapidly fries as it's splashed with hot oil! Somehow.")
+ var/obj/item/food/deepfryholder/fry_target = new(exposed_obj.drop_location(), exposed_obj)
+ fry_target.fry(volume)
+ fry_target.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume)
+
+/datum/reagent/consumable/cooking_oil/expose_mob(mob/living/exposed_mob, methods = TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
+ if(!(methods & (VAPOR|TOUCH)) || isnull(holder) || (holder.chem_temp < fry_temperature)) //Directly coats the mob, and doesn't go into their bloodstream
+ return
+
var/oil_damage = ((holder.chem_temp / fry_temperature) * 0.33) //Damage taken per unit
if(methods & TOUCH)
- oil_damage *= 1 - M.get_permeability_protection()
+ oil_damage *= max(1 - touch_protection, 0)
var/FryLoss = round(min(38, oil_damage * reac_volume))
- if(!HAS_TRAIT(M, TRAIT_OIL_FRIED))
- M.visible_message("The boiling oil sizzles as it covers [M]!", \
+ if(!HAS_TRAIT(exposed_mob, TRAIT_OIL_FRIED))
+ exposed_mob.visible_message("The boiling oil sizzles as it covers [exposed_mob]!", \
"You're covered in boiling oil!")
if(FryLoss)
- M.emote("scream")
- playsound(M, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
- ADD_TRAIT(M, TRAIT_OIL_FRIED, "cooking_oil_react")
- addtimer(CALLBACK(M, /mob/living/proc/unfry_mob), 3)
+ exposed_mob.emote("scream")
+ playsound(exposed_mob, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
+ ADD_TRAIT(exposed_mob, TRAIT_OIL_FRIED, "cooking_oil_react")
+ addtimer(CALLBACK(exposed_mob, /mob/living/proc/unfry_mob), 3)
if(FryLoss)
- M.adjustFireLoss(FryLoss)
+ exposed_mob.adjustFireLoss(FryLoss)
return TRUE
-/datum/reagent/consumable/cooking_oil/expose_turf(turf/open/T, reac_volume)
- if(!istype(T) || isgroundlessturf(T))
+/datum/reagent/consumable/cooking_oil/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf) || isgroundlessturf(exposed_turf) || (reac_volume < 5))
return
- if(reac_volume >= 5)
- T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
- T.name = "deep-fried [initial(T.name)]"
- T.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
+
+ exposed_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
+ exposed_turf.name = "deep-fried [initial(exposed_turf.name)]"
+ exposed_turf.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
/datum/reagent/consumable/sugar
name = "Sugar"
@@ -289,27 +290,32 @@
M.adjust_bodytemperature(cooling, 50)
..()
-/datum/reagent/consumable/frostoil/expose_turf(turf/T, reac_volume)
- if(reac_volume >= 5)
- for(var/mob/living/simple_animal/slime/M in T)
- M.adjustToxLoss(rand(15,30))
- if(reac_volume >= 1) // Make Freezy Foam and anti-fire grenades!
- if(isopenturf(T))
- var/turf/open/OT = T
- OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
- OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
+/datum/reagent/consumable/frostoil/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(reac_volume < 1)
+ return
+ if(isopenturf(exposed_turf))
+ var/turf/open/exposed_open_turf = exposed_turf
+ exposed_open_turf.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
+ exposed_open_turf.air.temperature -= (MOLES_CELLSTANDARD * 100 * reac_volume) / exposed_open_turf.air.heat_capacity() // reduces environment temperature by 5K per unit.
+ if(reac_volume < 5)
+ return
+ for(var/mob/living/simple_animal/slime/exposed_slime in exposed_turf)
+ exposed_slime.adjustToxLoss(rand(15,30))
/datum/reagent/consumable/condensedcapsaicin
name = "Condensed Capsaicin"
description = "A chemical agent used for self-defense and in police work."
color = "#B31008" // rgb: 179, 16, 8
taste_description = "scorching agony"
+ penetrates_skin = NONE
-/datum/reagent/consumable/condensedcapsaicin/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(!ishuman(M) && !ismonkey(M))
+/datum/reagent/consumable/condensedcapsaicin/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!ishuman(exposed_mob) && !ismonkey(exposed_mob))
return
- var/mob/living/carbon/victim = M
+ var/mob/living/carbon/victim = exposed_mob
if(methods & (TOUCH|VAPOR))
var/pepper_proof = victim.is_pepper_proof()
@@ -320,7 +326,7 @@
victim.emote("scream")
victim.blur_eyes(5) // 10 seconds
victim.blind_eyes(3) // 6 seconds
- victim.set_confusion(max(M.get_confusion(), 5)) // 10 seconds
+ victim.set_confusion(max(exposed_mob.get_confusion(), 5)) // 10 seconds
victim.Knockdown(3 SECONDS)
victim.add_movespeed_modifier(/datum/movespeed_modifier/reagent/pepperspray)
addtimer(CALLBACK(victim, /mob.proc/remove_movespeed_modifier, /datum/movespeed_modifier/reagent/pepperspray), 10 SECONDS)
@@ -328,7 +334,7 @@
if(methods & INGEST)
if(!holder.has_reagent(/datum/reagent/consumable/milk))
if(prob(15))
- to_chat(M, "[pick("Your head pounds.", "Your mouth feels like it's on fire.", "You feel dizzy.")]")
+ to_chat(exposed_mob, "[pick("Your head pounds.", "Your mouth feels like it's on fire.", "You feel dizzy.")]")
if(prob(10))
victim.blur_eyes(1)
if(prob(10))
@@ -348,19 +354,19 @@
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255,255,255
taste_description = "salt"
+ penetrates_skin = NONE
-/datum/reagent/consumable/sodiumchloride/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(!istype(M))
- return
- if(M.has_bane(BANE_SALT))
- M.mind.disrupt_spells(-200)
+/datum/reagent/consumable/sodiumchloride/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
+ . = ..()
+ if(exposed_mob.has_bane(BANE_SALT))
+ exposed_mob.mind.disrupt_spells(-200)
-/datum/reagent/consumable/sodiumchloride/expose_turf(turf/T, reac_volume) //Creates an umbra-blocking salt pile
- if(!istype(T))
+/datum/reagent/consumable/sodiumchloride/expose_turf(turf/exposed_turf, reac_volume) //Creates an umbra-blocking salt pile
+ . = ..()
+ if(!istype(exposed_turf) || (reac_volume < 1))
return
- if(reac_volume < 1)
- return
- new/obj/effect/decal/cleanable/food/salt(T)
+
+ new/obj/effect/decal/cleanable/food/salt(exposed_turf)
/datum/reagent/consumable/blackpepper
name = "Black Pepper"
@@ -447,16 +453,17 @@
color = "#302000" // rgb: 48, 32, 0
taste_description = "slime"
-/datum/reagent/consumable/cornoil/expose_turf(turf/open/T, reac_volume)
- if (!istype(T))
+/datum/reagent/consumable/cornoil/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
- T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
- var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
+ exposed_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume*2 SECONDS)
+ var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in exposed_turf)
if(hotspot)
- var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles())
+ var/datum/gas_mixture/lowertemp = exposed_turf.remove_air(exposed_turf.air.total_moles())
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.react(src)
- T.assume_air(lowertemp)
+ exposed_turf.assume_air(lowertemp)
qdel(hotspot)
/datum/reagent/consumable/enzyme
@@ -497,8 +504,8 @@
color = "#302000" // rgb: 48, 32, 0
taste_description = "wet and cheap noodles on fire"
-/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/carbon/M)
- M.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT)
+/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/carbon/target_mob)
+ target_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT)
..()
/datum/reagent/consumable/flour
@@ -508,12 +515,15 @@
color = "#FFFFFF" // rgb: 0, 0, 0
taste_description = "chalky wheat"
-/datum/reagent/consumable/flour/expose_turf(turf/T, reac_volume)
- if(!isspaceturf(T))
- var/obj/effect/decal/cleanable/food/flour/reagentdecal = new(T)
- reagentdecal = locate() in T //Might have merged with flour already there.
- if(reagentdecal)
- reagentdecal.reagents.add_reagent(/datum/reagent/consumable/flour, reac_volume)
+/datum/reagent/consumable/flour/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(isspaceturf(exposed_turf))
+ return
+
+ var/obj/effect/decal/cleanable/food/flour/reagentdecal = new(exposed_turf)
+ reagentdecal = locate() in exposed_turf //Might have merged with flour already there.
+ if(reagentdecal)
+ reagentdecal.reagents.add_reagent(/datum/reagent/consumable/flour, reac_volume)
/datum/reagent/consumable/cherryjelly
name = "Cherry Jelly"
@@ -594,13 +604,15 @@
M.adjustToxLoss(-1*REM, 0)
..()
-/datum/reagent/consumable/honey/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(iscarbon(M) && (methods & (TOUCH|VAPOR|PATCH)))
- var/mob/living/carbon/C = M
- for(var/s in C.surgeries)
- var/datum/surgery/S = s
- S.speed_modifier = max(0.6, S.speed_modifier)
- ..()
+/datum/reagent/consumable/honey/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!iscarbon(exposed_mob) || !(methods & (TOUCH|VAPOR|PATCH)))
+ return
+
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ for(var/s in exposed_carbon.surgeries)
+ var/datum/surgery/surgery = s
+ surgery.speed_modifier = max(0.6, surgery.speed_modifier)
/datum/reagent/consumable/mayonnaise
name = "Mayonnaise"
@@ -620,21 +632,18 @@
color = "#c0c9a0"
taste_description = "bitterness"
-/datum/reagent/consumable/tearjuice/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(!istype(M))
+/datum/reagent/consumable/tearjuice/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!(methods & INGEST) || !((methods & (TOUCH|PATCH|VAPOR)) && (exposed_mob.is_mouth_covered() || exposed_mob.is_eyes_covered())))
return
- var/unprotected = FALSE
- if((methods & INGEST) || ((methods & (TOUCH|PATCH|VAPOR)) && !M.is_mouth_covered() && !M.is_eyes_covered()))
- unprotected = TRUE
- if(unprotected)
- if(!M.getorganslot(ORGAN_SLOT_EYES)) //can't blind somebody with no eyes
- to_chat(M, "Your eye sockets feel wet.")
- else
- if(!M.eye_blurry)
- to_chat(M, "Tears well up in your eyes!")
- M.blind_eyes(2)
- M.blur_eyes(5)
- ..()
+
+ if(!exposed_mob.getorganslot(ORGAN_SLOT_EYES)) //can't blind somebody with no eyes
+ to_chat(exposed_mob, "Your eye sockets feel wet.")
+ else
+ if(!exposed_mob.eye_blurry)
+ to_chat(exposed_mob, "Tears well up in your eyes!")
+ exposed_mob.blind_eyes(2)
+ exposed_mob.blur_eyes(5)
/datum/reagent/consumable/tearjuice/on_mob_life(mob/living/carbon/M)
..()
@@ -688,8 +697,9 @@
//Lazy list of mobs affected by the luminosity of this reagent.
var/list/mobs_affected
-/datum/reagent/consumable/tinlux/expose_mob(mob/living/M)
- add_reagent_light(M)
+/datum/reagent/consumable/tinlux/expose_mob(mob/living/exposed_mob)
+ . = ..()
+ add_reagent_light(exposed_mob)
/datum/reagent/consumable/tinlux/on_mob_end_metabolize(mob/living/M)
remove_reagent_light(M)
@@ -740,12 +750,15 @@
color = "#97ee63"
taste_description = "pure electricity"
-/datum/reagent/consumable/liquidelectricity/expose_mob(mob/living/M, methods=TOUCH, reac_volume) //can't be on life because of the way blood works.
- if((methods & (INGEST|INJECT|PATCH)) && iscarbon(M))
- var/mob/living/carbon/C = M
- var/obj/item/organ/stomach/ethereal/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
- if(istype(stomach))
- stomach.adjust_charge(reac_volume * REM)
+/datum/reagent/consumable/liquidelectricity/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) //can't be on life because of the way blood works.
+ . = ..()
+ if(!(methods & (INGEST|INJECT|PATCH)) || !iscarbon(exposed_mob))
+ return
+
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ var/obj/item/organ/stomach/ethereal/stomach = exposed_carbon.getorganslot(ORGAN_SLOT_STOMACH)
+ if(istype(stomach))
+ stomach.adjust_charge(reac_volume * REM)
/datum/reagent/consumable/liquidelectricity/on_mob_life(mob/living/carbon/M)
if(prob(25) && !isethereal(M))
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 41b87975455..b7b28965f72 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -232,13 +232,15 @@
..()
. = 1
-/datum/reagent/medicine/rezadone/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
+/datum/reagent/medicine/rezadone/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
. = ..()
- if(iscarbon(M))
- var/mob/living/carbon/patient = M
- if(reac_volume >= 5 && HAS_TRAIT_FROM(patient, TRAIT_HUSK, "burn") && patient.getFireLoss() < THRESHOLD_UNHUSK) //One carp yields 12u rezadone.
- patient.cure_husk("burn")
- patient.visible_message("[patient]'s body rapidly absorbs moisture from the environment, taking on a more healthy appearance.")
+ if(!iscarbon(exposed_mob))
+ return
+
+ var/mob/living/carbon/patient = exposed_mob
+ if(reac_volume >= 5 && HAS_TRAIT_FROM(patient, TRAIT_HUSK, "burn") && patient.getFireLoss() < THRESHOLD_UNHUSK) //One carp yields 12u rezadone.
+ patient.cure_husk("burn")
+ patient.visible_message("[patient]'s body rapidly absorbs moisture from the environment, taking on a more healthy appearance.")
/datum/reagent/medicine/spaceacillin
name = "Spaceacillin"
@@ -326,21 +328,24 @@
..()
return TRUE
-/datum/reagent/medicine/mine_salve/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message = 1)
- if(iscarbon(M) && M.stat != DEAD)
- if(methods & (INGEST|VAPOR|INJECT))
- M.adjust_nutrition(-5)
- if(show_message)
- to_chat(M, "Your stomach feels empty and cramps!")
- else
- var/mob/living/carbon/C = M
- for(var/s in C.surgeries)
- var/datum/surgery/S = s
- S.speed_modifier = max(0.1, S.speed_modifier)
+/datum/reagent/medicine/mine_salve/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE)
+ . = ..()
+ if(!iscarbon(exposed_mob) || (exposed_mob.stat == DEAD))
+ return
- if(show_message)
- to_chat(M, "You feel your injuries fade away to nothing!" )
- ..()
+ if(methods & (INGEST|VAPOR|INJECT))
+ exposed_mob.adjust_nutrition(-5)
+ if(show_message)
+ to_chat(exposed_mob, "Your stomach feels empty and cramps!")
+
+ if(methods & (PATCH|TOUCH))
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ for(var/s in exposed_carbon.surgeries)
+ var/datum/surgery/surgery = s
+ surgery.speed_modifier = max(0.1, surgery.speed_modifier)
+
+ if(show_message)
+ to_chat(exposed_carbon, "You feel your injuries fade away to nothing!" )
/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M)
if(iscarbon(M))
@@ -766,26 +771,26 @@
if(chems.has_reagent(type, 1))
mytray.spawnplant()
-/datum/reagent/medicine/strange_reagent/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(M.stat != DEAD)
+/datum/reagent/medicine/strange_reagent/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ if(exposed_mob.stat != DEAD)
return ..()
- if(M.suiciding || M.hellbound) //they are never coming back
- M.visible_message("[M]'s body does not react...")
+ if(exposed_mob.suiciding || exposed_mob.hellbound) //they are never coming back
+ exposed_mob.visible_message("[exposed_mob]'s body does not react...")
return
- if(iscarbon(M) && !(methods & INGEST)) //simplemobs can still be splashed
+ if(iscarbon(exposed_mob) && !(methods & INGEST)) //simplemobs can still be splashed
return ..()
- var/amount_to_revive = round((M.getBruteLoss()+M.getFireLoss())/20)
- if(M.getBruteLoss()+M.getFireLoss() >= 200 || HAS_TRAIT(M, TRAIT_HUSK) || reac_volume < amount_to_revive) //body will die from brute+burn on revive or you haven't provided enough to revive.
- M.visible_message("[M]'s body convulses a bit, and then falls still once more.")
- M.do_jitter_animation(10)
+ var/amount_to_revive = round((exposed_mob.getBruteLoss()+exposed_mob.getFireLoss())/20)
+ if(exposed_mob.getBruteLoss()+exposed_mob.getFireLoss() >= 200 || HAS_TRAIT(exposed_mob, TRAIT_HUSK) || reac_volume < amount_to_revive) //body will die from brute+burn on revive or you haven't provided enough to revive.
+ exposed_mob.visible_message("[exposed_mob]'s body convulses a bit, and then falls still once more.")
+ exposed_mob.do_jitter_animation(10)
return
- M.visible_message("[M]'s body starts convulsing!")
- M.notify_ghost_cloning("Your body is being revived with Strange Reagent!")
- M.do_jitter_animation(10)
+ exposed_mob.visible_message("[exposed_mob]'s body starts convulsing!")
+ exposed_mob.notify_ghost_cloning("Your body is being revived with Strange Reagent!")
+ exposed_mob.do_jitter_animation(10)
var/excess_healing = 5*(reac_volume-amount_to_revive) //excess reagent will heal blood and organs across the board
- addtimer(CALLBACK(M, /mob/living/carbon.proc/do_jitter_animation, 10), 40) //jitter immediately, then again after 4 and 8 seconds
- addtimer(CALLBACK(M, /mob/living/carbon.proc/do_jitter_animation, 10), 80)
- addtimer(CALLBACK(M, /mob/living.proc/revive, FALSE, FALSE, excess_healing), 79)
+ addtimer(CALLBACK(exposed_mob, /mob/living/carbon.proc/do_jitter_animation, 10), 40) //jitter immediately, then again after 4 and 8 seconds
+ addtimer(CALLBACK(exposed_mob, /mob/living/carbon.proc/do_jitter_animation, 10), 80)
+ addtimer(CALLBACK(exposed_mob, /mob/living.proc/revive, FALSE, FALSE, excess_healing), 79)
..()
/datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/carbon/M)
@@ -926,12 +931,15 @@
color = "#CC23FF"
taste_description = "jelly"
-/datum/reagent/medicine/regen_jelly/expose_mob(mob/living/M, reac_volume)
- if(M && ishuman(M) && reac_volume >= 0.5)
- var/mob/living/carbon/human/H = M
- H.hair_color = "C2F"
- H.facial_hair_color = "C2F"
- H.update_hair()
+/datum/reagent/medicine/regen_jelly/expose_mob(mob/living/exposed_mob, reac_volume)
+ . = ..()
+ if(!ishuman(exposed_mob) || (reac_volume < 0.5))
+ return
+
+ var/mob/living/carbon/human/exposed_human = exposed_mob
+ exposed_human.hair_color = "C2F"
+ exposed_human.facial_hair_color = "C2F"
+ exposed_human.update_hair()
/datum/reagent/medicine/regen_jelly/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(-1.5*REM, 0)
@@ -1267,18 +1275,18 @@
taste_description = "numbing bitterness"
/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all.
+ . = ..()
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25)
M.adjustBruteLoss(-0.35, 0)
- ..()
- . = 1
+ return TRUE
-/datum/reagent/medicine/polypyr/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(methods & (TOUCH|VAPOR))
- if(M && ishuman(M) && reac_volume >= 0.5)
- var/mob/living/carbon/human/H = M
- H.hair_color = "92f"
- H.facial_hair_color = "92f"
- H.update_hair()
+/datum/reagent/medicine/polypyr/expose_mob(mob/living/carbon/human/exposed_human, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_human) || (reac_volume < 0.5))
+ return
+ exposed_human.hair_color = "92f"
+ exposed_human.facial_hair_color = "92f"
+ exposed_human.update_hair()
/datum/reagent/medicine/polypyr/overdose_process(mob/living/M)
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index f0817aac95f..b5ac596877f 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -9,6 +9,7 @@
glass_name = "glass of tomato juice"
glass_desc = "Are you sure this is tomato juice?"
shot_glass_icon_state = "shotglassred"
+ penetrates_skin = NONE
// FEED ME
/datum/reagent/blood/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray)
@@ -16,26 +17,27 @@
if(chems.has_reagent(src.type, 1))
mytray.adjustPests(rand(2,3))
-/datum/reagent/blood/expose_mob(mob/living/L, methods=TOUCH, reac_volume)
+/datum/reagent/blood/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
+ . = ..()
if(data && data["viruses"])
for(var/thing in data["viruses"])
- var/datum/disease/D = thing
+ var/datum/disease/strain = thing
- if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
+ if((strain.spread_flags & DISEASE_SPREAD_SPECIAL) || (strain.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
continue
- if((methods & (TOUCH|VAPOR)) && (D.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS))
- L.ContactContractDisease(D)
+ if((methods & (TOUCH|VAPOR)) && (strain.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS))
+ exposed_mob.ContactContractDisease(strain)
else //ingest, patch or inject
- L.ForceContractDisease(D)
+ exposed_mob.ForceContractDisease(strain)
- if(iscarbon(L))
- var/mob/living/carbon/C = L
- if(C.get_blood_id() == /datum/reagent/blood && ((methods & INJECT) || ((methods & INGEST) && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
- if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type)))
- C.reagents.add_reagent(/datum/reagent/toxin, reac_volume * 0.5)
+ if(iscarbon(exposed_mob))
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ if(exposed_carbon.get_blood_id() == /datum/reagent/blood && ((methods & INJECT) || ((methods & INGEST) && exposed_carbon.dna && exposed_carbon.dna.species && (DRINKSBLOOD in exposed_carbon.dna.species.species_traits))))
+ if(!data || !(data["blood_type"] in get_safe_blood(exposed_carbon.dna.blood_type)))
+ exposed_carbon.reagents.add_reagent(/datum/reagent/toxin, reac_volume * 0.5)
else
- C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM)
+ exposed_carbon.blood_volume = min(exposed_carbon.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM)
/datum/reagent/blood/on_new(list/data)
@@ -75,17 +77,18 @@
var/datum/disease/D = thing
. += D
-/datum/reagent/blood/expose_turf(turf/T, reac_volume)//splash the blood all over the place
- if(!istype(T))
+/datum/reagent/blood/expose_turf(turf/exposed_turf, reac_volume)//splash the blood all over the place
+ . = ..()
+ if(!istype(exposed_turf))
return
if(reac_volume < 3)
return
- var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
- if(!B)
- B = new(T)
+ var/obj/effect/decal/cleanable/blood/bloodsplatter = locate() in exposed_turf //find some blood here
+ if(!bloodsplatter)
+ bloodsplatter = new(exposed_turf)
if(data["blood_DNA"])
- B.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+ bloodsplatter.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
/datum/reagent/blood/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray)
. = ..()
@@ -104,14 +107,18 @@
name = "Vaccine"
color = "#C81040" // rgb: 200, 16, 64
taste_description = "slime"
+ penetrates_skin = NONE
-/datum/reagent/vaccine/expose_mob(mob/living/L, methods=TOUCH, reac_volume)
- if(islist(data) && (methods & (INGEST|INJECT)))
- for(var/thing in L.diseases)
- var/datum/disease/D = thing
- if(D.GetDiseaseID() in data)
- D.cure()
- LAZYOR(L.disease_resistances, data)
+/datum/reagent/vaccine/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
+ . = ..()
+ if(!islist(data) || !(methods & (INGEST|INJECT)))
+ return
+
+ for(var/thing in exposed_mob.diseases)
+ var/datum/disease/infection = thing
+ if(infection.GetDiseaseID() in data)
+ infection.cure()
+ LAZYOR(exposed_mob.disease_resistances, data)
/datum/reagent/vaccine/on_merge(list/data)
if(istype(data))
@@ -144,48 +151,46 @@
* Water reaction to turf
*/
-/datum/reagent/water/expose_turf(turf/open/T, reac_volume)
- if(!istype(T))
+/datum/reagent/water/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
- var/CT = cooling_temperature
+ var/cool_temp = cooling_temperature
if(reac_volume >= 5)
- T.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS))
+ exposed_turf.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS))
- for(var/mob/living/simple_animal/slime/M in T)
- M.apply_water()
+ for(var/mob/living/simple_animal/slime/exposed_slime in exposed_turf)
+ exposed_slime.apply_water()
- var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
- if(hotspot && !isspaceturf(T))
- if(T.air)
- var/datum/gas_mixture/G = T.air
- G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),TCMB)
- G.react(src)
+ var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in exposed_turf)
+ if(hotspot && !isspaceturf(exposed_turf))
+ if(exposed_turf.air)
+ var/datum/gas_mixture/air = exposed_turf.air
+ air.temperature = max(min(air.temperature-(cool_temp*1000), air.temperature/cool_temp),TCMB)
+ air.react(src)
qdel(hotspot)
- //fixed
- var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)
- if(A)
- A.acid_level = max(A.acid_level - reac_volume*50, 0)
/*
* Water reaction to an object
*/
-/datum/reagent/water/expose_obj(obj/O, reac_volume)
- O.extinguish()
- O.acid_level = 0
+/datum/reagent/water/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ exposed_obj.extinguish()
+ exposed_obj.wash(CLEAN_TYPE_ACID)
// Monkey cube
- if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube))
- var/obj/item/reagent_containers/food/snacks/monkeycube/cube = O
+ if(istype(exposed_obj, /obj/item/reagent_containers/food/snacks/monkeycube))
+ var/obj/item/reagent_containers/food/snacks/monkeycube/cube = exposed_obj
cube.Expand()
// Dehydrated carp
- else if(istype(O, /obj/item/toy/plush/carpplushie/dehy_carp))
- var/obj/item/toy/plush/carpplushie/dehy_carp/dehy = O
+ else if(istype(exposed_obj, /obj/item/toy/plush/carpplushie/dehy_carp))
+ var/obj/item/toy/plush/carpplushie/dehy_carp/dehy = exposed_obj
dehy.Swell() // Makes a carp
- else if(istype(O, /obj/item/stack/sheet/hairlesshide))
- var/obj/item/stack/sheet/hairlesshide/HH = O
+ else if(istype(exposed_obj, /obj/item/stack/sheet/hairlesshide))
+ var/obj/item/stack/sheet/hairlesshide/HH = exposed_obj
new /obj/item/stack/sheet/wethide(get_turf(HH), HH.amount)
qdel(HH)
@@ -193,12 +198,10 @@
* Water reaction to a mob
*/
-/datum/reagent/water/expose_mob(mob/living/M, methods=TOUCH, reac_volume)//Splashing people with water can help put them out!
- if(!istype(M))
- return
+/datum/reagent/water/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people with water can help put them out!
+ . = ..()
if(methods & TOUCH)
- M.extinguish_mob() // extinguish removes all fire stacks
- ..()
+ exposed_mob.extinguish_mob() // extinguish removes all fire stacks
/datum/reagent/water/on_mob_life(mob/living/carbon/M)
. = ..()
@@ -237,10 +240,10 @@
REMOVE_TRAIT(L, TRAIT_HOLY, type)
..()
-/datum/reagent/water/holywater/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(iscultist(M))
- to_chat(M, "A vile holiness begins to spread its shining tendrils through your mind, purging the Geometer of Blood's influence!")
- ..()
+/datum/reagent/water/holywater/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(iscultist(exposed_mob))
+ to_chat(exposed_mob, "A vile holiness begins to spread its shining tendrils through your mind, purging the Geometer of Blood's influence!")
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
if(M.blood_volume)
@@ -275,14 +278,14 @@
return
holder.remove_reagent(type, 0.4) //fixed consumption to prevent balancing going out of whack
-/datum/reagent/water/holywater/expose_turf(turf/T, reac_volume)
- ..()
- if(!istype(T))
+/datum/reagent/water/holywater/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
if(reac_volume>=10)
- for(var/obj/effect/rune/R in T)
+ for(var/obj/effect/rune/R in exposed_turf)
qdel(R)
- T.Bless()
+ exposed_turf.Bless()
/datum/reagent/water/holywater/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray)
. = ..()
@@ -312,33 +315,27 @@
* Water reaction to turf
*/
-/datum/reagent/hydrogen_peroxide/expose_turf(turf/open/T, reac_volume)
- if(!istype(T))
+/datum/reagent/hydrogen_peroxide/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
if(reac_volume >= 5)
- T.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS))
+ exposed_turf.MakeSlippery(TURF_WET_WATER, 10 SECONDS, min(reac_volume*1.5 SECONDS, 60 SECONDS))
/*
* Water reaction to a mob
*/
-/datum/reagent/hydrogen_peroxide/expose_mob(mob/living/M, methods=TOUCH, reac_volume)//Splashing people with h2o2 can burn them !
- if(!istype(M))
- return
+/datum/reagent/hydrogen_peroxide/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people with h2o2 can burn them !
+ . = ..()
if(methods & TOUCH)
- M.adjustFireLoss(2, 0) // burns
- ..()
+ exposed_mob.adjustFireLoss(2, 0) // burns
/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke
name = "Unholy Water"
description = "Something that shouldn't exist on this plane of existence."
taste_description = "suffering"
metabolization_rate = 2.5 * REAGENTS_METABOLISM //1u/tick
-
-/datum/reagent/fuel/unholywater/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(methods & (TOUCH|VAPOR))
- M.reagents.add_reagent(type,reac_volume/4)
- return
- return ..()
+ penetrates_skin = TOUCH|VAPOR
/datum/reagent/fuel/unholywater/on_mob_life(mob/living/carbon/M)
if(iscultist(M))
@@ -385,11 +382,12 @@
taste_description = "cherry" // by popular demand
var/lube_kind = TURF_WET_LUBE ///What kind of slipperiness gets added to turfs.
-/datum/reagent/lube/expose_turf(turf/open/T, reac_volume)
- if (!istype(T))
+/datum/reagent/lube/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
if(reac_volume >= 1)
- T.MakeSlippery(lube_kind, 15 SECONDS, min(reac_volume * 2 SECONDS, 120))
+ exposed_turf.MakeSlippery(lube_kind, 15 SECONDS, min(reac_volume * 2 SECONDS, 120))
///Stronger kind of lube. Applies TURF_WET_SUPERLUBE.
/datum/reagent/lube/superlube
@@ -405,38 +403,39 @@
overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle.
taste_description = "sour oranges"
-/datum/reagent/spraytan/expose_mob(mob/living/M, methods=TOUCH, reac_volume, show_message = 1)
- if(ishuman(M))
+/datum/reagent/spraytan/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE)
+ . = ..()
+ if(ishuman(exposed_mob))
if(methods & (PATCH|VAPOR))
- var/mob/living/carbon/human/N = M
- if(N.dna.species.id == "human")
- switch(N.skin_tone)
+ var/mob/living/carbon/human/exposed_human = exposed_mob
+ if(exposed_human.dna.species.id == "human")
+ switch(exposed_human.skin_tone)
if("african1")
- N.skin_tone = "african2"
+ exposed_human.skin_tone = "african2"
if("indian")
- N.skin_tone = "african1"
+ exposed_human.skin_tone = "african1"
if("arab")
- N.skin_tone = "indian"
+ exposed_human.skin_tone = "indian"
if("asian2")
- N.skin_tone = "arab"
+ exposed_human.skin_tone = "arab"
if("asian1")
- N.skin_tone = "asian2"
+ exposed_human.skin_tone = "asian2"
if("mediterranean")
- N.skin_tone = "african1"
+ exposed_human.skin_tone = "african1"
if("latino")
- N.skin_tone = "mediterranean"
+ exposed_human.skin_tone = "mediterranean"
if("caucasian3")
- N.skin_tone = "mediterranean"
+ exposed_human.skin_tone = "mediterranean"
if("caucasian2")
- N.skin_tone = pick("caucasian3", "latino")
+ exposed_human.skin_tone = pick("caucasian3", "latino")
if("caucasian1")
- N.skin_tone = "caucasian2"
+ exposed_human.skin_tone = "caucasian2"
if ("albino")
- N.skin_tone = "caucasian1"
+ exposed_human.skin_tone = "caucasian1"
- if(MUTCOLORS in N.dna.species.species_traits) //take current alien color and darken it slightly
+ if(MUTCOLORS in exposed_human.dna.species.species_traits) //take current alien color and darken it slightly
var/newcolor = ""
- var/string = N.dna.features["mcolor"]
+ var/string = exposed_human.dna.features["mcolor"]
var/len = length(string)
var/char = ""
var/ascii = 0
@@ -459,14 +458,11 @@
else
break
if(ReadHSV(newcolor)[3] >= ReadHSV("#7F7F7F")[3])
- N.dna.features["mcolor"] = newcolor
- N.regenerate_icons()
-
-
+ exposed_human.dna.features["mcolor"] = newcolor
+ exposed_human.regenerate_icons()
if((methods & INGEST) && show_message)
- to_chat(M, "That tasted horrible.")
- ..()
+ to_chat(exposed_mob, "That tasted horrible.")
/datum/reagent/spraytan/overdose_process(mob/living/M)
@@ -688,10 +684,12 @@
description = "An advanced corruptive toxin produced by slimes."
color = "#13BC5E" // rgb: 19, 188, 94
taste_description = "slime"
+ penetrates_skin = NONE
-/datum/reagent/aslimetoxin/expose_mob(mob/living/L, methods=TOUCH, reac_volume)
+/datum/reagent/aslimetoxin/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
+ . = ..()
if(methods & ~TOUCH)
- L.ForceContractDisease(new /datum/disease/transformation/slime(), FALSE, TRUE)
+ exposed_mob.ForceContractDisease(new /datum/disease/transformation/slime(), FALSE, TRUE)
/datum/reagent/gluttonytoxin
name = "Gluttony's Blessing"
@@ -699,9 +697,11 @@
color = "#5EFF3B" //RGB: 94, 255, 59
can_synth = FALSE
taste_description = "decay"
+ penetrates_skin = NONE
-/datum/reagent/gluttonytoxin/expose_mob(mob/living/L, methods=TOUCH, reac_volume)
- L.ForceContractDisease(new /datum/disease/transformation/morph(), FALSE, TRUE)
+/datum/reagent/gluttonytoxin/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
+ . = ..()
+ exposed_mob.ForceContractDisease(new /datum/disease/transformation/morph(), FALSE, TRUE)
/datum/reagent/serotrotium
name = "Serotrotium"
@@ -723,17 +723,18 @@
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0 // oderless and tasteless
-/datum/reagent/oxygen/expose_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
+/datum/reagent/oxygen/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if((!exposed_obj) || (!reac_volume))
return 0
var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
+ exposed_obj.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
-/datum/reagent/oxygen/expose_turf(turf/open/T, reac_volume)
- if(istype(T))
+/datum/reagent/oxygen/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(istype(exposed_turf))
var/temp = holder ? holder.chem_temp : T20C
- T.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
- return
+ exposed_turf.atmos_spawn_air("o2=[reac_volume/2];TEMP=[temp]")
/datum/reagent/copper
name = "Copper"
@@ -742,12 +743,15 @@
color = "#6E3B08" // rgb: 110, 59, 8
taste_description = "metal"
-/datum/reagent/copper/expose_obj(obj/O, reac_volume)
- if(istype(O, /obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/M = O
- reac_volume = min(reac_volume, M.amount)
- new/obj/item/stack/tile/bronze(get_turf(M), reac_volume)
- M.use(reac_volume)
+/datum/reagent/copper/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if(!istype(exposed_obj, /obj/item/stack/sheet/metal))
+ return
+
+ var/obj/item/stack/sheet/metal/M = exposed_obj
+ reac_volume = min(reac_volume, M.amount)
+ new/obj/item/stack/tile/bronze(get_turf(M), reac_volume)
+ M.use(reac_volume)
/datum/reagent/nitrogen
name = "Nitrogen"
@@ -756,16 +760,18 @@
color = "#808080" // rgb: 128, 128, 128
taste_mult = 0
-/datum/reagent/nitrogen/expose_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
+/datum/reagent/nitrogen/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if((!exposed_obj) || (!reac_volume))
return 0
var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
+ exposed_obj.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
-/datum/reagent/nitrogen/expose_turf(turf/open/T, reac_volume)
- if(istype(T))
+/datum/reagent/nitrogen/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(istype(exposed_turf))
var/temp = holder ? holder.chem_temp : T20C
- T.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
+ exposed_turf.atmos_spawn_air("n2=[reac_volume/2];TEMP=[temp]")
return
/datum/reagent/hydrogen
@@ -810,11 +816,14 @@
color = "#1C1300" // rgb: 30, 20, 0
taste_description = "sour chalk"
-/datum/reagent/carbon/expose_turf(turf/T, reac_volume)
- if(!isspaceturf(T))
- var/obj/effect/decal/cleanable/dirt/D = locate() in T.contents
- if(!D)
- new /obj/effect/decal/cleanable/dirt(T)
+/datum/reagent/carbon/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(isspaceturf(exposed_turf))
+ return
+
+ var/obj/effect/decal/cleanable/dirt/dirt_decal = (locate() in exposed_turf.contents)
+ if(!dirt_decal)
+ dirt_decal = new(exposed_turf)
/datum/reagent/chlorine
name = "Chlorine"
@@ -909,12 +918,14 @@
color = "#D0EFEE" // space cleaner but lighter
taste_description = "bitterness"
-/datum/reagent/space_cleaner/sterilizine/expose_mob(mob/living/carbon/C, methods=TOUCH, reac_volume)
- if(methods & (TOUCH|VAPOR|PATCH))
- for(var/s in C.surgeries)
- var/datum/surgery/S = s
- S.speed_modifier = max(0.2, S.speed_modifier)
- ..()
+/datum/reagent/space_cleaner/sterilizine/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR|PATCH)))
+ return
+
+ for(var/s in exposed_carbon.surgeries)
+ var/datum/surgery/surgery = s
+ surgery.speed_modifier = max(0.2, surgery.speed_modifier)
/datum/reagent/iron
name = "Iron"
@@ -930,11 +941,14 @@
C.blood_volume += 0.5
..()
-/datum/reagent/iron/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(M.has_bane(BANE_IRON)) //If the target is weak to cold iron, then poison them.
- if(holder && holder.chem_temp < 100) // COLD iron.
- M.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
- ..()
+/datum/reagent/iron/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!exposed_mob.has_bane(BANE_IRON)) //If the target is weak to cold iron, then poison them.
+ return
+ if(!holder || (holder.chem_temp >= 100)) // COLD iron.
+ return
+
+ exposed_mob.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
/datum/reagent/gold
name = "Gold"
@@ -952,10 +966,10 @@
taste_description = "expensive yet reasonable metal"
material = /datum/material/silver
-/datum/reagent/silver/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(M.has_bane(BANE_SILVER))
- M.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
- ..()
+/datum/reagent/silver/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(exposed_mob.has_bane(BANE_SILVER))
+ exposed_mob.reagents.add_reagent(/datum/reagent/toxin, reac_volume)
/datum/reagent/uranium
name ="Uranium"
@@ -970,14 +984,16 @@
M.apply_effect(irradiation_level/M.metabolism_efficiency,EFFECT_IRRADIATE,0)
..()
-/datum/reagent/uranium/expose_turf(turf/T, reac_volume)
- if(reac_volume >= 3)
- if(!isspaceturf(T))
- var/obj/effect/decal/cleanable/greenglow/GG = locate() in T.contents
- if(!GG)
- GG = new/obj/effect/decal/cleanable/greenglow(T)
- if(!QDELETED(GG))
- GG.reagents.add_reagent(type, reac_volume)
+/datum/reagent/uranium/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if((reac_volume < 3) || isspaceturf(exposed_turf))
+ return
+
+ var/obj/effect/decal/cleanable/greenglow/glow = locate() in exposed_turf.contents
+ if(!glow)
+ glow = new(exposed_turf)
+ if(!QDELETED(glow))
+ glow.reagents.add_reagent(type, reac_volume)
//Mutagenic chem side-effects.
/datum/reagent/uranium/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
@@ -1010,10 +1026,10 @@
taste_description = "fizzling blue"
material = /datum/material/bluespace
-/datum/reagent/bluespace/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
+/datum/reagent/bluespace/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
if(methods & (TOUCH|VAPOR))
- do_teleport(M, get_turf(M), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal
- ..()
+ do_teleport(exposed_mob, get_turf(exposed_mob), (reac_volume / 5), asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) //4 tiles per crystal
/datum/reagent/bluespace/on_mob_life(mob/living/carbon/M)
if(current_cycle > 10 && prob(15))
@@ -1049,12 +1065,12 @@
glass_icon_state = "dr_gibb_glass"
glass_name = "glass of welder fuel"
glass_desc = "Unless you're an industrial tool, this is probably not safe for consumption."
+ penetrates_skin = NONE
-/datum/reagent/fuel/expose_mob(mob/living/M, methods=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite!
+/datum/reagent/fuel/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite!
+ . = ..()
if(methods & (TOUCH|VAPOR))
- M.adjust_fire_stacks(reac_volume / 10)
- return
- ..()
+ exposed_mob.adjust_fire_stacks(reac_volume / 10)
/datum/reagent/fuel/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(1, 0)
@@ -1067,32 +1083,39 @@
color = "#A5F0EE" // rgb: 165, 240, 238
taste_description = "sourness"
reagent_weight = 0.6 //so it sprays further
+ penetrates_skin = NONE
var/clean_types = CLEAN_WASH
-/datum/reagent/space_cleaner/expose_obj(obj/O, reac_volume)
- O?.wash(clean_types)
+/datum/reagent/space_cleaner/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ exposed_obj?.wash(clean_types)
-/datum/reagent/space_cleaner/expose_turf(turf/T, reac_volume)
- if(reac_volume >= 1)
- T.wash(clean_types)
- for(var/am in T)
- var/atom/movable/movable_content = am
- if(ismopable(movable_content)) // Mopables will be cleaned anyways by the turf wash
- continue
- movable_content.wash(clean_types)
+/datum/reagent/space_cleaner/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(reac_volume < 1)
+ return
- for(var/mob/living/simple_animal/slime/M in T)
- M.adjustToxLoss(rand(5,10))
+ exposed_turf.wash(clean_types)
+ for(var/am in exposed_turf)
+ var/atom/movable/movable_content = am
+ if(ismopable(movable_content)) // Mopables will be cleaned anyways by the turf wash
+ continue
+ movable_content.wash(clean_types)
-/datum/reagent/space_cleaner/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
+ for(var/mob/living/simple_animal/slime/exposed_slime in exposed_turf)
+ exposed_slime.adjustToxLoss(rand(5,10))
+
+/datum/reagent/space_cleaner/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=0)
+ . = ..()
if(methods & (TOUCH|VAPOR))
- M.wash(clean_types)
+ exposed_mob.wash(clean_types)
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected."
metabolization_rate = 1.5 * REAGENTS_METABOLISM
taste_description = "acid"
+ penetrates_skin = VAPOR
/datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/carbon/M)
M.adjustBruteLoss(3.33)
@@ -1100,11 +1123,11 @@
M.adjustToxLoss(3.33)
..()
-/datum/reagent/space_cleaner/ez_clean/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- ..()
- if((methods & (TOUCH|VAPOR)) && !issilicon(M))
- M.adjustBruteLoss(1.5)
- M.adjustFireLoss(1.5)
+/datum/reagent/space_cleaner/ez_clean/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if((methods & (TOUCH|VAPOR)) && !issilicon(exposed_mob))
+ exposed_mob.adjustBruteLoss(1.5)
+ exposed_mob.adjustFireLoss(1.5)
/datum/reagent/cryptobiolin
name = "Cryptobiolin"
@@ -1140,10 +1163,12 @@
color = "#535E66" // rgb: 83, 94, 102
can_synth = FALSE
taste_description = "sludge"
+ penetrates_skin = NONE
-/datum/reagent/nanomachines/expose_mob(mob/living/L, methods=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
+/datum/reagent/nanomachines/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
if((methods & (PATCH|INGEST|INJECT)) || ((methods & VAPOR) && prob(min(reac_volume,100)*(1 - touch_protection))))
- L.ForceContractDisease(new /datum/disease/transformation/robot(), FALSE, TRUE)
+ exposed_mob.ForceContractDisease(new /datum/disease/transformation/robot(), FALSE, TRUE)
/datum/reagent/xenomicrobes
name = "Xenomicrobes"
@@ -1151,10 +1176,12 @@
color = "#535E66" // rgb: 83, 94, 102
can_synth = FALSE
taste_description = "sludge"
+ penetrates_skin = NONE
-/datum/reagent/xenomicrobes/expose_mob(mob/living/L, methods=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
+/datum/reagent/xenomicrobes/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
if((methods & (PATCH|INGEST|INJECT)) || ((methods & VAPOR) && prob(min(reac_volume,100)*(1 - touch_protection))))
- L.ForceContractDisease(new /datum/disease/transformation/xeno(), FALSE, TRUE)
+ exposed_mob.ForceContractDisease(new /datum/disease/transformation/xeno(), FALSE, TRUE)
/datum/reagent/fungalspores
name = "Tubercle bacillus Cosmosis microbes"
@@ -1162,10 +1189,12 @@
color = "#92D17D" // rgb: 146, 209, 125
can_synth = FALSE
taste_description = "slime"
+ penetrates_skin = NONE
-/datum/reagent/fungalspores/expose_mob(mob/living/L, methods=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
+/datum/reagent/fungalspores/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
if((methods & (PATCH|INGEST|INJECT)) || ((methods & VAPOR) && prob(min(reac_volume,100)*(1 - touch_protection))))
- L.ForceContractDisease(new /datum/disease/tuberculosis(), FALSE, TRUE)
+ exposed_mob.ForceContractDisease(new /datum/disease/tuberculosis(), FALSE, TRUE)
/datum/reagent/snail
name = "Agent-S"
@@ -1173,10 +1202,12 @@
color = "#003300" // rgb(0, 51, 0)
taste_description = "goo"
can_synth = FALSE //special orange man request
+ penetrates_skin = NONE
-/datum/reagent/snail/expose_mob(mob/living/L, methods=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
+/datum/reagent/snail/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
if((methods & (PATCH|INGEST|INJECT)) || ((methods & VAPOR) && prob(min(reac_volume,100)*(1 - touch_protection))))
- L.ForceContractDisease(new /datum/disease/gastrolosis(), FALSE, TRUE)
+ exposed_mob.ForceContractDisease(new /datum/disease/gastrolosis(), FALSE, TRUE)
/datum/reagent/fluorosurfactant//foam precursor
name = "Fluorosurfactant"
@@ -1237,17 +1268,18 @@
color = "#B0B0B0" // rgb : 192, 192, 192
taste_description = "something unknowable"
-/datum/reagent/carbondioxide/expose_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
+/datum/reagent/carbondioxide/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if((!exposed_obj) || (!reac_volume))
return 0
var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
+ exposed_obj.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
-/datum/reagent/carbondioxide/expose_turf(turf/open/T, reac_volume)
- if(istype(T))
+/datum/reagent/carbondioxide/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(istype(exposed_turf))
var/temp = holder ? holder.chem_temp : T20C
- T.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
- return
+ exposed_turf.atmos_spawn_air("co2=[reac_volume/5];TEMP=[temp]")
/datum/reagent/nitrous_oxide
name = "Nitrous Oxide"
@@ -1257,20 +1289,23 @@
color = "#808080"
taste_description = "sweetness"
-/datum/reagent/nitrous_oxide/expose_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
+/datum/reagent/nitrous_oxide/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if((!exposed_obj) || (!reac_volume))
return 0
var/temp = holder ? holder.chem_temp : T20C
- O.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
+ exposed_obj.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
-/datum/reagent/nitrous_oxide/expose_turf(turf/open/T, reac_volume)
- if(istype(T))
+/datum/reagent/nitrous_oxide/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(istype(exposed_turf))
var/temp = holder ? holder.chem_temp : T20C
- T.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
+ exposed_turf.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[temp]")
-/datum/reagent/nitrous_oxide/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
+/datum/reagent/nitrous_oxide/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
if(methods & VAPOR)
- M.drowsyness += max(round(reac_volume, 1), 2)
+ exposed_mob.drowsyness += max(round(reac_volume, 1), 2)
/datum/reagent/nitrous_oxide/on_mob_life(mob/living/carbon/M)
M.drowsyness += 2
@@ -1581,10 +1616,10 @@
taste_description = "carpet" // Your tounge feels furry.
var/carpet_type = /turf/open/floor/carpet
-/datum/reagent/carpet/expose_turf(turf/T, reac_volume)
- if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
- var/turf/open/floor/F = T
- F.PlaceOnTop(carpet_type, flags = CHANGETURF_INHERIT_AIR)
+/datum/reagent/carpet/expose_turf(turf/exposed_turf, reac_volume)
+ if(isplatingturf(exposed_turf) || istype(exposed_turf, /turf/open/floor/plasteel))
+ var/turf/open/floor/target_floor = exposed_turf
+ target_floor.PlaceOnTop(carpet_type, flags = CHANGETURF_INHERIT_AIR)
..()
/datum/reagent/carpet/black
@@ -1697,13 +1732,11 @@
taste_description = "acid"
-/datum/reagent/acetone_oxide/expose_mob(mob/living/M, methods=TOUCH, reac_volume)//Splashing people kills people!
- if(!istype(M))
- return
+/datum/reagent/acetone_oxide/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people kills people!
+ . = ..()
if(methods & TOUCH)
- M.adjustFireLoss(2, FALSE) // burns,
- M.adjust_fire_stacks((reac_volume / 10))
- ..()
+ exposed_mob.adjustFireLoss(2, FALSE) // burns,
+ exposed_mob.adjust_fire_stacks((reac_volume / 10))
@@ -1757,10 +1790,10 @@
return ..()
/// Colors anything it touches a random color.
-/datum/reagent/colorful_reagent/expose_atom(mob/living/M, reac_volume)
- if(can_colour_mobs)
- M.add_atom_colour(pick(random_color_list), WASHABLE_COLOUR_PRIORITY)
- ..()
+/datum/reagent/colorful_reagent/expose_atom(atom/exposed_atom, reac_volume)
+ . = ..()
+ if(!isliving(exposed_atom) || can_colour_mobs)
+ exposed_atom.add_atom_colour(pick(random_color_list), WASHABLE_COLOUR_PRIORITY)
/datum/reagent/hair_dye
name = "Quantum Hair Dye"
@@ -1769,6 +1802,7 @@
var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code
color = "#C8A5DC"
taste_description = "sourness"
+ penetrates_skin = NONE
/datum/reagent/hair_dye/New()
SSticker.OnRoundstart(CALLBACK(src,.proc/UpdateColor))
@@ -1777,13 +1811,15 @@
/datum/reagent/hair_dye/proc/UpdateColor()
color = pick(potential_colors)
-/datum/reagent/hair_dye/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(methods & (TOUCH|VAPOR))
- if(M && ishuman(M))
- var/mob/living/carbon/human/H = M
- H.hair_color = pick(potential_colors)
- H.facial_hair_color = pick(potential_colors)
- H.update_hair()
+/datum/reagent/hair_dye/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob))
+ return
+
+ var/mob/living/carbon/human/exposed_human = exposed_mob
+ exposed_human.hair_color = pick(potential_colors)
+ exposed_human.facial_hair_color = pick(potential_colors)
+ exposed_human.update_hair()
/datum/reagent/barbers_aid
name = "Barber's Aid"
@@ -1791,16 +1827,20 @@
reagent_state = LIQUID
color = "#A86B45" //hair is brown
taste_description = "sourness"
+ penetrates_skin = NONE
-/datum/reagent/barbers_aid/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if((methods & (TOUCH|VAPOR)) && ishuman(M) && !HAS_TRAIT(M, TRAIT_BALD))
- var/mob/living/carbon/human/exposed_human = M
- var/datum/sprite_accessory/hair/picked_hair = pick(GLOB.hairstyles_list)
- var/datum/sprite_accessory/facial_hair/picked_beard = pick(GLOB.facial_hairstyles_list)
- to_chat(exposed_human, "Hair starts sprouting from your scalp.")
- exposed_human.hairstyle = picked_hair
- exposed_human.facial_hairstyle = picked_beard
- exposed_human.update_hair()
+/datum/reagent/barbers_aid/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob) || HAS_TRAIT(exposed_mob, TRAIT_BALD))
+ return
+
+ var/mob/living/carbon/human/exposed_human = exposed_mob
+ var/datum/sprite_accessory/hair/picked_hair = pick(GLOB.hairstyles_list)
+ var/datum/sprite_accessory/facial_hair/picked_beard = pick(GLOB.facial_hairstyles_list)
+ to_chat(exposed_human, "Hair starts sprouting from your scalp.")
+ exposed_human.hairstyle = picked_hair
+ exposed_human.facial_hairstyle = picked_beard
+ exposed_human.update_hair()
/datum/reagent/concentrated_barbers_aid
name = "Concentrated Barber's Aid"
@@ -1808,15 +1848,18 @@
reagent_state = LIQUID
color = "#7A4E33" //hair is dark browmn
taste_description = "sourness"
+ penetrates_skin = NONE
-/datum/reagent/concentrated_barbers_aid/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(methods & (TOUCH|VAPOR))
- if(M && ishuman(M) && !HAS_TRAIT(M, TRAIT_BALD))
- var/mob/living/carbon/human/H = M
- to_chat(H, "Your hair starts growing at an incredible speed!")
- H.hairstyle = "Very Long Hair"
- H.facial_hairstyle = "Beard (Very Long)"
- H.update_hair()
+/datum/reagent/concentrated_barbers_aid/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob) || HAS_TRAIT(exposed_mob, TRAIT_BALD))
+ return
+
+ var/mob/living/carbon/human/exposed_human = exposed_mob
+ to_chat(exposed_human, "Your hair starts growing at an incredible speed!")
+ exposed_human.hairstyle = "Very Long Hair"
+ exposed_human.facial_hairstyle = "Beard (Very Long)"
+ exposed_human.update_hair()
/datum/reagent/baldium
name = "Baldium"
@@ -1824,14 +1867,18 @@
reagent_state = LIQUID
color = "#ecb2cf"
taste_description = "bitterness"
+ penetrates_skin = NONE
-/datum/reagent/baldium/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if((methods & (TOUCH|VAPOR)) && ishuman(M))
- var/mob/living/carbon/human/exposed_human = M
- to_chat(exposed_human, "Your hair is falling out in clumps!")
- exposed_human.hairstyle = "Bald"
- exposed_human.facial_hairstyle = "Shaved"
- exposed_human.update_hair()
+/datum/reagent/baldium/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE)
+ . = ..()
+ if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob))
+ return
+
+ var/mob/living/carbon/human/exposed_human = exposed_mob
+ to_chat(exposed_human, "Your hair is falling out in clumps!")
+ exposed_human.hairstyle = "Bald"
+ exposed_human.facial_hairstyle = "Shaved"
+ exposed_human.update_hair()
/datum/reagent/saltpetre
name = "Saltpetre"
@@ -1864,15 +1911,19 @@
color = "#A70FFF"
taste_description = "dryness"
-/datum/reagent/drying_agent/expose_turf(turf/open/T, reac_volume)
- if(istype(T))
- T.MakeDry(ALL, TRUE, reac_volume * 5 SECONDS) //50 deciseconds per unit
+/datum/reagent/drying_agent/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
+ return
+ exposed_turf.MakeDry(ALL, TRUE, reac_volume * 5 SECONDS) //50 deciseconds per unit
-/datum/reagent/drying_agent/expose_obj(obj/O, reac_volume)
- if(O.type == /obj/item/clothing/shoes/galoshes)
- var/t_loc = get_turf(O)
- qdel(O)
- new /obj/item/clothing/shoes/galoshes/dry(t_loc)
+/datum/reagent/drying_agent/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if(exposed_obj.type != /obj/item/clothing/shoes/galoshes)
+ return
+ var/t_loc = get_turf(exposed_obj)
+ qdel(exposed_obj)
+ new /obj/item/clothing/shoes/galoshes/dry(t_loc)
// Virology virus food chems.
@@ -1946,12 +1997,12 @@
can_synth = FALSE
taste_description = "brains"
-/datum/reagent/romerol/expose_mob(mob/living/carbon/human/H, methods=TOUCH, reac_volume)
+/datum/reagent/romerol/expose_mob(mob/living/carbon/human/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
// Silently add the zombie infection organ to be activated upon death
- if(!H.getorganslot(ORGAN_SLOT_ZOMBIE))
+ if(!exposed_mob.getorganslot(ORGAN_SLOT_ZOMBIE))
var/obj/item/organ/zombie_infection/nodamage/ZI = new()
- ZI.Insert(H)
- ..()
+ ZI.Insert(exposed_mob)
/datum/reagent/magillitis
name = "Magillitis"
@@ -2010,10 +2061,11 @@
reagent_state = SOLID
var/glitter_type = /obj/effect/decal/cleanable/glitter
-/datum/reagent/glitter/expose_turf(turf/T, reac_volume)
- if(!istype(T))
+/datum/reagent/glitter/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
- new glitter_type(T)
+ new glitter_type(exposed_turf)
/datum/reagent/glitter/pink
name = "pink glitter"
@@ -2114,10 +2166,12 @@
color = "#9A6750" //RGB: 154, 103, 80
taste_description = "inner peace"
can_synth = FALSE
+ penetrates_skin = NONE
-/datum/reagent/tranquility/expose_mob(mob/living/L, methods=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
+/datum/reagent/tranquility/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
+ . = ..()
if((methods & (PATCH|INGEST|INJECT)) || ((methods & VAPOR) && prob(min(reac_volume,100)*(1 - touch_protection))))
- L.ForceContractDisease(new /datum/disease/transformation/gondola(), FALSE, TRUE)
+ exposed_mob.ForceContractDisease(new /datum/disease/transformation/gondola(), FALSE, TRUE)
/datum/reagent/spider_extract
@@ -2214,13 +2268,13 @@
var/applied_material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
var/minumum_material_amount = 100
-/datum/reagent/metalgen/expose_obj(obj/O, volume)
- metal_morph(O)
- return
+/datum/reagent/metalgen/expose_obj(obj/exposed_obj, volume)
+ . = ..()
+ metal_morph(exposed_obj)
-/datum/reagent/metalgen/expose_turf(turf/T, volume)
- metal_morph(T)
- return
+/datum/reagent/metalgen/expose_turf(turf/exposed_turf, volume)
+ . = ..()
+ metal_morph(exposed_turf)
///turn an object into a special material
/datum/reagent/metalgen/proc/metal_morph(atom/A)
@@ -2249,10 +2303,10 @@
metabolization_rate = 0.1 * REAGENTS_METABOLISM //20 times as long, so it's actually viable to use
var/time_multiplier = 1 MINUTES //1 minute per unit of gravitum on objects. Seems overpowered, but the whole thing is very niche
-/datum/reagent/gravitum/expose_obj(obj/O, volume)
- O.AddElement(/datum/element/forced_gravity, 0)
-
- addtimer(CALLBACK(O, .proc/_RemoveElement, list(/datum/element/forced_gravity, 0)), volume * time_multiplier)
+/datum/reagent/gravitum/expose_obj(obj/exposed_obj, volume)
+ . = ..()
+ exposed_obj.AddElement(/datum/element/forced_gravity, 0)
+ addtimer(CALLBACK(exposed_obj, .proc/_RemoveElement, list(/datum/element/forced_gravity, 0)), volume * time_multiplier)
/datum/reagent/gravitum/on_mob_add(mob/living/L)
L.AddElement(/datum/element/forced_gravity, 0) //0 is the gravity, and in this case weightless
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index f4125263d55..bb48951d06f 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -6,9 +6,10 @@
color = "#550000"
taste_description = "sweet tasting metal"
-/datum/reagent/thermite/expose_turf(turf/T, reac_volume)
+/datum/reagent/thermite/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
if(reac_volume >= 1)
- T.AddComponent(/datum/component/thermite, reac_volume)
+ exposed_turf.AddComponent(/datum/component/thermite, reac_volume)
/datum/reagent/thermite/on_mob_life(mob/living/carbon/M)
M.adjustFireLoss(1, 0)
@@ -41,6 +42,7 @@
color = "#FFC8C8"
metabolization_rate = 4
taste_description = "burning"
+ penetrates_skin = NONE
/datum/reagent/clf3/on_mob_life(mob/living/carbon/M)
M.adjust_fire_stacks(2)
@@ -49,33 +51,33 @@
..()
return TRUE
-/datum/reagent/clf3/expose_turf(turf/T, reac_volume)
- if(isplatingturf(T))
- var/turf/open/floor/plating/F = T
- if(prob(10 + F.burnt + 5*F.broken)) //broken or burnt plating is more susceptible to being destroyed
- F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
- if(isfloorturf(T))
- var/turf/open/floor/F = T
+/datum/reagent/clf3/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(isplatingturf(exposed_turf))
+ var/turf/open/floor/plating/target_plating = exposed_turf
+ if(prob(10 + target_plating.burnt + 5*target_plating.broken)) //broken or burnt plating is more susceptible to being destroyed
+ target_plating.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
+ if(isfloorturf(exposed_turf))
+ var/turf/open/floor/target_floor = exposed_turf
if(prob(reac_volume))
- F.make_plating()
+ target_floor.make_plating()
else if(prob(reac_volume))
- F.burn_tile()
- if(isfloorturf(F))
- for(var/turf/turf in range(1,F))
- if(!locate(/obj/effect/hotspot) in turf)
- new /obj/effect/hotspot(F)
- if(iswallturf(T))
- var/turf/closed/wall/W = T
+ target_floor.burn_tile()
+ if(isfloorturf(target_floor))
+ for(var/turf/nearby_turf in range(1, target_floor))
+ if(!locate(/obj/effect/hotspot) in nearby_turf)
+ new /obj/effect/hotspot(nearby_turf)
+ if(iswallturf(exposed_turf))
+ var/turf/closed/wall/target_wall = exposed_turf
if(prob(reac_volume))
- W.ScrapeAway()
+ target_wall.ScrapeAway()
-/datum/reagent/clf3/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(istype(M))
- if(methods & (TOUCH|VAPOR|PATCH))
- M.adjust_fire_stacks(min(reac_volume/5, 10))
- M.IgniteMob()
- if(!locate(/obj/effect/hotspot) in M.loc)
- new /obj/effect/hotspot(M.loc)
+/datum/reagent/clf3/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ exposed_mob.adjust_fire_stacks(min(reac_volume/5, 10))
+ exposed_mob.IgniteMob()
+ if(!locate(/obj/effect/hotspot) in exposed_mob.loc)
+ new /obj/effect/hotspot(exposed_mob.loc)
/datum/reagent/sorium
name = "Sorium"
@@ -158,17 +160,17 @@
taste_description = "burning"
self_consuming = TRUE
-/datum/reagent/phlogiston/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- M.adjust_fire_stacks(1)
- var/burndmg = max(0.3*M.fire_stacks, 0.3)
- M.adjustFireLoss(burndmg, 0)
- M.IgniteMob()
- ..()
+/datum/reagent/phlogiston/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ exposed_mob.adjust_fire_stacks(1)
+ var/burndmg = max(0.3*exposed_mob.fire_stacks, 0.3)
+ exposed_mob.adjustFireLoss(burndmg, 0)
+ exposed_mob.IgniteMob()
-/datum/reagent/phlogiston/on_mob_life(mob/living/carbon/M)
- M.adjust_fire_stacks(1)
- var/burndmg = max(0.3*M.fire_stacks, 0.3)
- M.adjustFireLoss(burndmg, 0)
+/datum/reagent/phlogiston/on_mob_life(mob/living/carbon/exposed_mob)
+ exposed_mob.adjust_fire_stacks(1)
+ var/burndmg = max(0.3*exposed_mob.fire_stacks, 0.3)
+ exposed_mob.adjustFireLoss(burndmg, 0)
..()
return TRUE
@@ -179,6 +181,7 @@
color = "#FA00AF"
taste_description = "burning"
self_consuming = TRUE
+ penetrates_skin = NONE
// why, just why
/datum/reagent/napalm/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
@@ -193,10 +196,10 @@
M.adjust_fire_stacks(1)
..()
-/datum/reagent/napalm/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(istype(M))
- if(methods & (TOUCH|VAPOR|PATCH))
- M.adjust_fire_stacks(min(reac_volume/4, 20))
+/datum/reagent/napalm/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(istype(exposed_mob) && (methods & (TOUCH|VAPOR|PATCH)))
+ exposed_mob.adjust_fire_stacks(min(reac_volume/4, 20))
/datum/reagent/cryostylane
name = "Cryostylane"
@@ -213,10 +216,12 @@
M.adjust_bodytemperature(-15)
..()
-/datum/reagent/cryostylane/expose_turf(turf/T, reac_volume)
- if(reac_volume >= 5)
- for(var/mob/living/simple_animal/slime/M in T)
- M.adjustToxLoss(rand(15,30))
+/datum/reagent/cryostylane/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if(reac_volume < 5)
+ return
+ for(var/mob/living/simple_animal/slime/exposed_slime in exposed_turf)
+ exposed_slime.adjustToxLoss(rand(15,30))
/datum/reagent/pyrosium
name = "Pyrosium"
@@ -287,30 +292,31 @@
color = "#A6FAFF55"
taste_description = "the inside of a fire extinguisher"
-/datum/reagent/firefighting_foam/expose_turf(turf/open/T, reac_volume)
- if (!istype(T))
+/datum/reagent/firefighting_foam/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if (!istype(exposed_turf))
return
if(reac_volume >= 1)
- var/obj/effect/particle_effect/foam/firefighting/F = (locate(/obj/effect/particle_effect/foam) in T)
- if(!F)
- F = new(T)
- else if(istype(F))
- F.lifetime = initial(F.lifetime) //reduce object churn a little bit when using smoke by keeping existing foam alive a bit longer
+ var/obj/effect/particle_effect/foam/firefighting/foam = (locate(/obj/effect/particle_effect/foam) in exposed_turf)
+ if(!foam)
+ foam = new(exposed_turf)
+ else if(istype(foam))
+ foam.lifetime = initial(foam.lifetime) //reduce object churn a little bit when using smoke by keeping existing foam alive a bit longer
- var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
- if(hotspot && !isspaceturf(T))
- if(T.air)
- var/datum/gas_mixture/G = T.air
- if(G.temperature > T20C)
- G.temperature = max(G.temperature/2,T20C)
- G.react(src)
- qdel(hotspot)
+ var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in exposed_turf)
+ if(hotspot && !isspaceturf(exposed_turf) && exposed_turf.air)
+ var/datum/gas_mixture/air = exposed_turf.air
+ if(air.temperature > T20C)
+ air.temperature = max(air.temperature/2,T20C)
+ air.react(src)
+ qdel(hotspot)
-/datum/reagent/firefighting_foam/expose_obj(obj/O, reac_volume)
- O.extinguish()
+/datum/reagent/firefighting_foam/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ exposed_obj.extinguish()
-/datum/reagent/firefighting_foam/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
+/datum/reagent/firefighting_foam/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
if(methods & (TOUCH|VAPOR))
- M.extinguish_mob() //All stacks are removed
- ..()
+ exposed_mob.extinguish_mob() //All stacks are removed
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 4da66edc3c0..32db835f22d 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -38,20 +38,18 @@
taste_description = "slime"
taste_mult = 0.9
-/datum/reagent/toxin/mutagen/expose_mob(mob/living/carbon/M, methods=TOUCH, reac_volume)
- if(!..())
- return
- if(!M.has_dna() || HAS_TRAIT(M, TRAIT_GENELESS) || HAS_TRAIT(M, TRAIT_BADDNA))
+/datum/reagent/toxin/mutagen/expose_mob(mob/living/carbon/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!. || !exposed_mob.has_dna() || HAS_TRAIT(exposed_mob, TRAIT_GENELESS) || HAS_TRAIT(exposed_mob, TRAIT_BADDNA))
return //No robots, AIs, aliens, Ians or other mobs should be affected by this.
if(((methods & VAPOR) && prob(min(33, reac_volume))) || (methods & (INGEST|PATCH|INJECT)))
- M.randmuti()
+ exposed_mob.randmuti()
if(prob(98))
- M.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
+ exposed_mob.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
else
- M.easy_randmut(POSITIVE)
- M.updateappearance()
- M.domutcheck()
- ..()
+ exposed_mob.easy_randmut(POSITIVE)
+ exposed_mob.updateappearance()
+ exposed_mob.domutcheck()
/datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/C)
C.apply_effect(5,EFFECT_IRRADIATE,0)
@@ -73,6 +71,7 @@
color = "#8228A0"
toxpwr = 3
material = /datum/material/plasma
+ penetrates_skin = NONE
/datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C)
if(holder.has_reagent(/datum/reagent/medicine/epinephrine))
@@ -88,25 +87,27 @@
A.atmos_spawn_air("plasma=[volume];TEMP=[holder.chem_temp]")
holder.del_reagent(type)
-/datum/reagent/toxin/plasma/expose_obj(obj/O, reac_volume)
- if((!O) || (!reac_volume))
+/datum/reagent/toxin/plasma/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if((!exposed_obj) || (!reac_volume))
return 0
var/temp = holder ? holder.chem_temp : T20C
if(temp >= LIQUID_PLASMA_BP)
- O.atmos_spawn_air("plasma=[reac_volume];TEMP=[temp]")
+ exposed_obj.atmos_spawn_air("plasma=[reac_volume];TEMP=[temp]")
-/datum/reagent/toxin/plasma/expose_turf(turf/open/T, reac_volume)
- if(!istype(T))
+/datum/reagent/toxin/plasma/expose_turf(turf/open/exposed_turf, reac_volume)
+ . = ..()
+ if(!istype(exposed_turf))
return
var/temp = holder ? holder.chem_temp : T20C
if(temp >= LIQUID_PLASMA_BP)
- T.atmos_spawn_air("plasma=[reac_volume];TEMP=[temp]")
+ exposed_turf.atmos_spawn_air("plasma=[reac_volume];TEMP=[temp]")
-/datum/reagent/toxin/plasma/expose_mob(mob/living/M, methods=TOUCH, reac_volume)//Splashing people with plasma is stronger than fuel!
+/datum/reagent/toxin/plasma/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)//Splashing people with plasma is stronger than fuel!
+ . = ..()
if(methods & (TOUCH|VAPOR))
- M.adjust_fire_stacks(reac_volume / 5)
+ exposed_mob.adjust_fire_stacks(reac_volume / 5)
return
- ..()
/datum/reagent/toxin/hot_ice
name = "Hot Ice Slush"
@@ -196,6 +197,7 @@
color = "#669900" // rgb: 102, 153, 0
toxpwr = 0.5
taste_description = "death"
+ penetrates_skin = NONE
var/fakedeath_active = FALSE
/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L)
@@ -208,12 +210,13 @@
L.cure_fakedeath(type)
..()
-/datum/reagent/toxin/zombiepowder/expose_mob(mob/living/L, methods=TOUCH, reac_volume)
- L.adjustOxyLoss(0.5*REM, 0)
+/datum/reagent/toxin/zombiepowder/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ exposed_mob.adjustOxyLoss(0.5*REM, 0)
if(methods & INGEST)
- var/datum/reagent/toxin/zombiepowder/Z = L.reagents.has_reagent(/datum/reagent/toxin/zombiepowder)
- if(istype(Z))
- Z.fakedeath_active = TRUE
+ var/datum/reagent/toxin/zombiepowder/zombiepowder = exposed_mob.reagents.has_reagent(/datum/reagent/toxin/zombiepowder)
+ if(istype(zombiepowder))
+ zombiepowder.fakedeath_active = TRUE
/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/M)
..()
@@ -268,6 +271,7 @@
color = "#49002E" // rgb: 73, 0, 46
toxpwr = 1
taste_mult = 1
+ penetrates_skin = NONE
// Plant-B-Gone is just as bad
/datum/reagent/toxin/plantbgone/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
@@ -277,21 +281,24 @@
mytray.adjustToxic(round(chems.get_reagent_amount(type) * 6))
mytray.adjustWeeds(-rand(4,8))
-/datum/reagent/toxin/plantbgone/expose_obj(obj/O, reac_volume)
- if(istype(O, /obj/structure/alien/weeds))
- var/obj/structure/alien/weeds/alien_weeds = O
+/datum/reagent/toxin/plantbgone/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if(istype(exposed_obj, /obj/structure/alien/weeds))
+ var/obj/structure/alien/weeds/alien_weeds = exposed_obj
alien_weeds.take_damage(rand(15,35), BRUTE, 0) // Kills alien weeds pretty fast
- else if(istype(O, /obj/structure/glowshroom)) //even a small amount is enough to kill it
- qdel(O)
- else if(istype(O, /obj/structure/spacevine))
- var/obj/structure/spacevine/SV = O
+ else if(istype(exposed_obj, /obj/structure/glowshroom)) //even a small amount is enough to kill it
+ qdel(exposed_obj)
+ else if(istype(exposed_obj, /obj/structure/spacevine))
+ var/obj/structure/spacevine/SV = exposed_obj
SV.on_chem_effect(src)
-/datum/reagent/toxin/plantbgone/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if((methods & VAPOR) && iscarbon(M))
- var/mob/living/carbon/exposed_carbon = M
- if(!exposed_carbon.wear_mask)
- exposed_carbon.adjustToxLoss(min(round(0.4 * reac_volume, 0.1), 10))
+/datum/reagent/toxin/plantbgone/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!(methods & VAPOR) || !iscarbon(exposed_mob))
+ return
+ var/mob/living/carbon/exposed_carbon = exposed_mob
+ if(!exposed_carbon.wear_mask)
+ exposed_carbon.adjustToxLoss(min(round(0.4 * reac_volume, 0.1), 10))
/datum/reagent/toxin/plantbgone/weedkiller
name = "Weed Killer"
@@ -320,11 +327,11 @@
mytray.adjustToxic(round(chems.get_reagent_amount(type) * 1))
mytray.adjustPests(-rand(1,2))
-/datum/reagent/toxin/pestkiller/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- ..()
- if(M.mob_biotypes & MOB_BUG)
+/datum/reagent/toxin/pestkiller/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume)
+ . = ..()
+ if(exposed_mob.mob_biotypes & MOB_BUG)
var/damage = min(round(0.4*reac_volume, 0.1),10)
- M.adjustToxLoss(damage)
+ exposed_mob.adjustToxLoss(damage)
/datum/reagent/toxin/pestkiller/organic
name = "Natural Pest Killer"
@@ -580,10 +587,7 @@
color = "#C8C8C8"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
toxpwr = 0
-
-/datum/reagent/toxin/itching_powder/expose_mob(mob/living/M, methods=TOUCH, reac_volume)
- if(methods & (TOUCH|VAPOR))
- M.reagents?.add_reagent(/datum/reagent/toxin/itching_powder, reac_volume)
+ penetrates_skin = TOUCH|VAPOR
/datum/reagent/toxin/itching_powder/on_mob_life(mob/living/carbon/M)
if(prob(15))
@@ -839,29 +843,32 @@
mytray.adjustToxic(round(chems.get_reagent_amount(type) * 1.5))
mytray.adjustWeeds(-rand(1,2))
-/datum/reagent/toxin/acid/expose_mob(mob/living/carbon/C, methods=TOUCH, reac_volume)
- if(!istype(C))
+/datum/reagent/toxin/acid/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume)
+ . = ..()
+ if(!istype(exposed_carbon))
return
reac_volume = round(reac_volume,0.1)
if(methods & INGEST)
- C.adjustBruteLoss(min(6*toxpwr, reac_volume * toxpwr))
+ exposed_carbon.adjustBruteLoss(min(6*toxpwr, reac_volume * toxpwr))
return
if(methods & INJECT)
- C.adjustBruteLoss(1.5 * min(6*toxpwr, reac_volume * toxpwr))
+ exposed_carbon.adjustBruteLoss(1.5 * min(6*toxpwr, reac_volume * toxpwr))
return
- C.acid_act(acidpwr, reac_volume)
+ exposed_carbon.acid_act(acidpwr, reac_volume)
-/datum/reagent/toxin/acid/expose_obj(obj/O, reac_volume)
- if(ismob(O.loc)) //handled in human acid_act()
+/datum/reagent/toxin/acid/expose_obj(obj/exposed_obj, reac_volume)
+ . = ..()
+ if(ismob(exposed_obj.loc)) //handled in human acid_act()
return
reac_volume = round(reac_volume,0.1)
- O.acid_act(acidpwr, reac_volume)
+ exposed_obj.acid_act(acidpwr, reac_volume)
-/datum/reagent/toxin/acid/expose_turf(turf/T, reac_volume)
- if (!istype(T))
+/datum/reagent/toxin/acid/expose_turf(turf/exposed_turf, reac_volume)
+ . = ..()
+ if (!istype(exposed_turf))
return
reac_volume = round(reac_volume,0.1)
- T.acid_act(acidpwr, reac_volume)
+ exposed_turf.acid_act(acidpwr, reac_volume)
/datum/reagent/toxin/acid/fluacid
name = "Fluorosulfuric acid"
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index e7e1e04a414..711f68c6a23 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -597,7 +597,7 @@
var/obj/O = owner.get_active_held_item()
if(O)
O.extinguish() //All shamelessly copied from water's expose_obj, since I didn't seem to be able to get it here for some reason.
- O.acid_level = 0
+ O.wash(CLEAN_TYPE_ACID)
// Monkey cube
if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube))
to_chat(owner, "[linked_extract] kept your hands wet! It makes [O] expand!")
diff --git a/icons/effects/acid.dmi b/icons/effects/acid.dmi
new file mode 100644
index 00000000000..284df8e536f
Binary files /dev/null and b/icons/effects/acid.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index f306db41934..706cad3f5c8 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 2cfb0f0c635..8f44e450acd 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -23,6 +23,7 @@
#include "code\__DEFINES\_tick.dm"
#include "code\__DEFINES\access.dm"
#include "code\__DEFINES\achievements.dm"
+#include "code\__DEFINES\acid.dm"
#include "code\__DEFINES\actionspeed_modification.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\antagonists.dm"
@@ -259,7 +260,6 @@
#include "code\controllers\configuration\entries\general.dm"
#include "code\controllers\configuration\entries\resources.dm"
#include "code\controllers\subsystem\achievements.dm"
-#include "code\controllers\subsystem\acid.dm"
#include "code\controllers\subsystem\adjacent_air.dm"
#include "code\controllers\subsystem\air.dm"
#include "code\controllers\subsystem\assets.dm"
@@ -322,6 +322,7 @@
#include "code\controllers\subsystem\vis_overlays.dm"
#include "code\controllers\subsystem\vote.dm"
#include "code\controllers\subsystem\weather.dm"
+#include "code\controllers\subsystem\processing\acid.dm"
#include "code\controllers\subsystem\processing\fastprocess.dm"
#include "code\controllers\subsystem\processing\fields.dm"
#include "code\controllers\subsystem\processing\fluids.dm"
@@ -399,6 +400,7 @@
#include "code\datums\brain_damage\special.dm"
#include "code\datums\brain_damage\split_personality.dm"
#include "code\datums\components\_component.dm"
+#include "code\datums\components\acid.dm"
#include "code\datums\components\anti_magic.dm"
#include "code\datums\components\areabound.dm"
#include "code\datums\components\armor_plate.dm"
@@ -602,6 +604,7 @@
#include "code\datums\keybinding\movement.dm"
#include "code\datums\keybinding\robot.dm"
#include "code\datums\looping_sounds\_looping_sound.dm"
+#include "code\datums\looping_sounds\acid.dm"
#include "code\datums\looping_sounds\item_sounds.dm"
#include "code\datums\looping_sounds\machinery_sounds.dm"
#include "code\datums\looping_sounds\weather.dm"
@@ -892,7 +895,6 @@
#include "code\game\objects\obj_defense.dm"
#include "code\game\objects\objs.dm"
#include "code\game\objects\structures.dm"
-#include "code\game\objects\effects\alien_acid.dm"
#include "code\game\objects\effects\anomalies.dm"
#include "code\game\objects\effects\blessing.dm"
#include "code\game\objects\effects\bump_teleporter.dm"