Attempts to make transferring reagents a bit more logical

Attempts to give trans_to, touch, and trans_to_* procs more distinct
purposes.
Applying reagents to things now calls touch() before attempting to
transfer reagents.
Reagents that affect fire stacks now do so from touch. Fixes #9750 when
combined with the above.
Also fixes acid affect_touch dealing brute instead of burn.
This commit is contained in:
mwerezak
2015-06-09 21:39:45 -04:00
parent bb824dba42
commit 72a716b66c
7 changed files with 104 additions and 67 deletions
+60 -37
View File
@@ -288,43 +288,13 @@
/* Holder-to-atom and similar procs */
/datum/reagents/proc/touch(var/atom/target) // This picks the appropriate reaction. Reagents are not guaranteed to transfer to the target.
if(ismob(target))
touch_mob(target)
if(isturf(target))
touch_turf(target)
if(isobj(target))
touch_obj(target)
return
/datum/reagents/proc/touch_mob(var/mob/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_mob(target)
update_total()
/datum/reagents/proc/touch_turf(var/turf/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_turf(target)
update_total()
/datum/reagents/proc/touch_obj(var/obj/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_obj(target)
update_total()
//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally,
//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob().
//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person),
//call the appropriate trans_to_*() proc.
/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
touch(target) //First, handle mere touch effects
if(ismob(target))
//warning("[my_atom] is trying to transfer reagents to [target], which is a mob, using trans_to()")
//return trans_to_mob(target, amount, multiplier, copy)
@@ -351,9 +321,62 @@
return F.trans_to(target, amount) // Let this proc check the atom's type
// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent.
// This does not handle transferring reagents to things.
// For example, splashing someone with water will get them wet and extinguish them if they are on fire,
// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin.
/datum/reagents/proc/touch(var/atom/target)
if(ismob(target))
touch_mob(target)
if(isturf(target))
touch_turf(target)
if(isobj(target))
touch_obj(target)
return
/datum/reagents/proc/touch_mob(var/mob/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_mob(target, current.volume)
update_total()
/datum/reagents/proc/touch_turf(var/turf/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_turf(target, current.volume)
update_total()
/datum/reagents/proc/touch_obj(var/obj/target)
if(!target || !istype(target))
return
for(var/datum/reagent/current in reagent_list)
current.touch_obj(target, current.volume)
update_total()
// Attempts to place a reagent on the mob's skin.
// Reagents are not guaranteed to transfer to the target.
/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/clothes = 1)
var/perm = 0
var/list/L = list("head" = THERMAL_PROTECTION_HEAD, "upper_torso" = THERMAL_PROTECTION_UPPER_TORSO, "lower_torso" = THERMAL_PROTECTION_LOWER_TORSO, "legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT, "feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT, "arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT, "hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT)
//this all seems very human-specific
var/list/L = list(
"head" = THERMAL_PROTECTION_HEAD,
"upper_torso" = THERMAL_PROTECTION_UPPER_TORSO,
"lower_torso" = THERMAL_PROTECTION_LOWER_TORSO,
"legs" = THERMAL_PROTECTION_LEG_LEFT + THERMAL_PROTECTION_LEG_RIGHT,
"feet" = THERMAL_PROTECTION_FOOT_LEFT + THERMAL_PROTECTION_FOOT_RIGHT,
"arms" = THERMAL_PROTECTION_ARM_LEFT + THERMAL_PROTECTION_ARM_RIGHT,
"hands" = THERMAL_PROTECTION_HAND_LEFT + THERMAL_PROTECTION_HAND_RIGHT
)
if(clothes)
for(var/obj/item/clothing/C in target.get_equipped_items())
if(C.permeability_coefficient == 1 || C.body_parts_covered == 0)
+11 -2
View File
@@ -88,7 +88,12 @@ About the Holder:
Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead.
touch(var/atom/target)
Not recommended to use. Calls touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type.
When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent.
This does not handle transferring reagents to things.
For example, splashing someone with water will get them wet and extinguish them if they are on fire,
even if they are wearing an impermeable suit that prevents the reagents from contacting the skin.
Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type.
Not recommended to use this directly, since trans_to() calls it before attempting to transfer.
touch_mob(var/mob/target)
Calls each reagent's touch_mob(target).
@@ -100,7 +105,11 @@ About the Holder:
Calls each reagent's touch_obj(target).
trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
Checks the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy).
The general proc for applying reagents to things externally (as opposed to directly injected into the contents).
It first calls touch, then the appropriate trans_to_*() or splash_mob().
If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc.
Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy).
trans_id_to(var/atom/target, var/id, var/amount = 1)
Transfers [amount] of [id] to [target]. Returns amount transferred.
+4 -3
View File
@@ -24,13 +24,14 @@
/datum/reagent/proc/remove_self(var/amount) // Shortcut
holder.remove_reagent(id, amount)
/datum/reagent/proc/touch_mob(var/mob/M) // This doesn't apply to being splashed - this is for, e.g. extinguishers and sprays. The difference is that reagent is not on the mob - it's in another object.
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
/datum/reagent/proc/touch_mob(var/mob/M, var/amount)
return
/datum/reagent/proc/touch_obj(var/obj/O) // Acid melting, cleaner cleaning, etc
/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc
return
/datum/reagent/proc/touch_turf(var/turf/T) // Cleaner cleaning, lube lubbing, etc, all go here
/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here
return
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
@@ -155,6 +155,17 @@
if(!cube.wrapped)
cube.Expand()
/datum/reagent/water/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
var/needed = L.fire_stacks * 10
if(amount > needed)
L.fire_stacks = 0
L.ExtinguishMob()
remove_self(needed)
else
L.adjust_fire_stacks(-(amount / 10))
remove_self(amount)
/datum/reagent/water/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(istype(M, /mob/living/carbon/slime))
var/mob/living/carbon/slime/S = M
@@ -165,15 +176,6 @@
++S.Discipline
if(dose == removed)
S.visible_message("<span class='warning'>[S]'s flesh sizzles where the water touches it!</span>", "<span class='danger'>Your flesh burns in the water!</span>")
var/needed = M.fire_stacks * 10
if(volume > needed)
M.fire_stacks = 0
M.ExtinguishMob()
remove_self(needed)
else
M.adjust_fire_stacks(-(volume / 10))
remove_self(volume)
return
/datum/reagent/fuel
name = "Welding fuel"
@@ -194,5 +196,7 @@
/datum/reagent/fuel/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustToxLoss(2 * removed)
/datum/reagent/fuel/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) // Splashing people with welding fuel to make them easy to ignite!
M.adjust_fire_stacks(0.1 * removed)
/datum/reagent/fuel/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
L.adjust_fire_stacks(amount / 10) // Splashing people with welding fuel to make them easy to ignite!
@@ -70,9 +70,9 @@
glass_name = "glass of ethanol"
glass_desc = "A well-known alcohol with a variety of applications."
/datum/reagent/ethanol/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.adjust_fire_stacks(removed / 15)
return
/datum/reagent/ethanol/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
L.adjust_fire_stacks(amount / 15)
/datum/reagent/ethanol/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustToxLoss(removed * 2 * toxicity)
@@ -318,7 +318,7 @@
return
if(volume < meltdose) // Not enough to melt anything
M.take_organ_damage(removed * power * 0.2)
M.take_organ_damage(0, removed * power * 0.2) //burn damage, since it causes chemical burns. Acid doesn't make bones shatter, like brute trauma would.
return
if(!M.unacidable && removed > 0)
if(istype(M, /mob/living/carbon/human) && volume >= meltdose)
@@ -67,10 +67,7 @@
/datum/reagent/paint/touch_mob(var/mob/M)
if(istype(M) && !istype(M, /mob/dead)) //painting ghosts: not allowed
M.color = color
/datum/reagent/paint/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.color = color
M.color = color //maybe someday change this to paint only clothes and exposed body parts for human mobs.
/datum/reagent/paint/get_data()
return color
@@ -265,9 +262,9 @@
remove_self(5)
return
/datum/reagent/thermite/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
M.adjust_fire_stacks(removed * 0.2)
return
/datum/reagent/thermite/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
L.adjust_fire_stacks(amount / 5)
/datum/reagent/thermite/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.adjustFireLoss(3 * removed)
@@ -45,9 +45,12 @@
color = "#9D14DB"
strength = 30
/datum/reagent/toxin/phoron/touch_mob(var/mob/living/L, var/amount)
if(istype(L))
L.adjust_fire_stacks(amount / 5)
/datum/reagent/toxin/phoron/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
..()
M.adjust_fire_stacks(removed / 5)
M.take_organ_damage(0, removed * 0.1) //being splashed directly with phoron causes minor chemical burns
/datum/reagent/toxin/phoron/touch_turf(var/turf/simulated/T)
if(!istype(T))
@@ -494,7 +497,7 @@
/datum/reagent/nanites/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
if(prob(10))
M.contract_disease(new /datum/disease/robotic_transformation(0), 1)
M.contract_disease(new /datum/disease/robotic_transformation(0), 1) //What
/datum/reagent/nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
M.contract_disease(new /datum/disease/robotic_transformation(0), 1)