mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-17 01:54:25 +01:00
377 lines
12 KiB
Plaintext
377 lines
12 KiB
Plaintext
/datum/reagent/blood
|
|
data = new/list("donor" = null, "viruses" = null, "species" = SPECIES_HUMAN, "blood_DNA" = null, "blood_type" = null, "blood_colour" = "#A10808", "resistances" = null, "trace_chem" = null, REAGENT_ID_ANTIBODIES = list(), "changeling" = FALSE)
|
|
name = REAGENT_BLOOD
|
|
id = REAGENT_ID_BLOOD
|
|
description = "Blood."
|
|
taste_description = REAGENT_ID_IRON
|
|
taste_mult = 1.3
|
|
reagent_state = LIQUID
|
|
metabolism = REM * 5
|
|
mrate_static = TRUE
|
|
affects_dead = 1 //so you can pump blood into someone before defibbing them
|
|
color = "#C80000"
|
|
var/volume_mod = 1 // So if you add different subtypes of blood, you can affect how much vessel blood each unit of reagent adds
|
|
|
|
glass_name = "tomato juice"
|
|
glass_desc = "Are you sure this is tomato juice?"
|
|
|
|
supply_conversion_value = REFINERYEXPORT_VALUE_COMMON
|
|
industrial_use = REFINERYEXPORT_REASON_BIOHAZARD
|
|
coolant_modifier = 0.25
|
|
|
|
|
|
/datum/reagent/blood/initialize_data(newdata)
|
|
..()
|
|
if(data && data["blood_colour"])
|
|
color = data["blood_colour"]
|
|
|
|
return
|
|
|
|
/datum/reagent/blood/get_data() // Just in case you have a reagent that handles data differently.
|
|
var/t = data.Copy()
|
|
if(t["viruses"])
|
|
var/list/v = t["viruses"]
|
|
t["viruses"] = v.Copy()
|
|
return t
|
|
|
|
/datum/reagent/blood/touch_turf(turf/simulated/T)
|
|
if(!istype(T) || volume < 3)
|
|
return
|
|
|
|
..()
|
|
|
|
if(!data["donor"] || ishuman(data["donor"]))
|
|
blood_splatter(T, src, 1)
|
|
else if(istype(data["donor"], /mob/living/carbon/alien))
|
|
var/mob/living/carbon/alien/A = data["donor"]
|
|
var/obj/effect/decal/cleanable/blood/B = blood_splatter(T, src, 1)
|
|
B.add_blooddna(A.dna,A)
|
|
else
|
|
var/obj/effect/decal/cleanable/blood/B = blood_splatter(T, src, 1)
|
|
B.add_blooddna(null,null)
|
|
|
|
/datum/reagent/blood/affect_ingest(mob/living/carbon/M, alien, removed)
|
|
|
|
var/effective_dose = dose
|
|
if(issmall(M)) effective_dose *= 2
|
|
|
|
var/is_vampire = FALSE //VOREStation Edit START
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
if(H.species.bloodsucker)
|
|
H.adjust_nutrition(removed*30)
|
|
is_vampire = TRUE //VOREStation Edit END
|
|
if(alien == IS_SLIME) // Treat it like nutriment for the jello, but not equivalent.
|
|
if(data["species"] == M.species.name) // Unless it's Promethean goo, then refill this one's goo.
|
|
M.inject_blood(src, volume * volume_mod)
|
|
remove_self(volume)
|
|
return
|
|
|
|
M.heal_organ_damage(0.2 * removed * volume_mod, 0) // More 'effective' blood means more usable material.
|
|
M.adjust_nutrition(20 * removed * volume_mod)
|
|
M.add_chemical_effect(CE_BLOODRESTORE, 4 * removed)
|
|
M.adjustToxLoss(removed / 2) // Still has some water in the form of plasma.
|
|
return
|
|
|
|
if(effective_dose > 5)
|
|
if(!is_vampire) //VOREStation Edit.
|
|
M.adjustToxLoss(removed) //VOREStation Edit.
|
|
if(effective_dose > 15)
|
|
if(!is_vampire) //VOREStation Edit.
|
|
M.adjustToxLoss(removed) //VOREStation Edit.
|
|
if(data && data["viruses"])
|
|
var/list/vlist = data["viruses"]
|
|
if(vlist.len)
|
|
for(var/ID in vlist)
|
|
if(!ID)
|
|
continue
|
|
var/datum/disease/D = ID
|
|
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
|
|
continue
|
|
if(M.HasDisease(D))
|
|
continue
|
|
D.try_infect(M)
|
|
|
|
/datum/reagent/blood/affect_touch(mob/living/carbon/M, alien, removed)
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
if(H.isSynthetic())
|
|
return
|
|
if(alien == IS_SLIME)
|
|
affect_ingest(M, alien, removed)
|
|
return
|
|
if(data && data["viruses"])
|
|
var/list/vlist = data["viruses"]
|
|
if(vlist.len)
|
|
for(var/ID in vlist)
|
|
var/datum/disease/D = ID
|
|
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
|
|
continue
|
|
M.ContractDisease(D)
|
|
if(data && data["resistances"])
|
|
M.AddResistances(data["resistances"])
|
|
|
|
/datum/reagent/blood/mix_data(newdata, newamount)
|
|
if(!data || !newdata)
|
|
return
|
|
|
|
if(newdata["species"] != "synthetic" && (data["changeling"] || newdata["changeling"]))
|
|
data["changeling"] = TRUE // Spread to other samples as an antag tactic
|
|
|
|
if(data["viruses"] || newdata["viruses"])
|
|
var/list/mix1 = data["viruses"]
|
|
var/list/mix2 = newdata["viruses"]
|
|
|
|
var/list/to_mix = list()
|
|
var/list/preserve = list()
|
|
|
|
for(var/datum/disease/advance/AD in mix1)
|
|
to_mix += AD
|
|
for(var/datum/disease/advance/AD in mix2)
|
|
to_mix += AD
|
|
|
|
var/datum/disease/advance/mixed_AD = Advance_Mix(to_mix)
|
|
|
|
if(mixed_AD)
|
|
preserve += mixed_AD
|
|
|
|
for(var/datum/disease/D1 in mix1)
|
|
if(!istype(D1, /datum/disease/advance))
|
|
var/keep = TRUE
|
|
for(var/datum/disease/D2 in preserve)
|
|
if(D1.IsSame(D2))
|
|
keep = FALSE
|
|
break
|
|
if(keep)
|
|
preserve += D1
|
|
|
|
for(var/datum/disease/D1 in mix2)
|
|
if(!istype(D1, /datum/disease/advance))
|
|
var/keep = TRUE
|
|
for(var/datum/disease/D2 in preserve)
|
|
if(D1.IsSame(D2))
|
|
keep = FALSE
|
|
break
|
|
if(keep)
|
|
preserve += D1
|
|
|
|
data["viruses"] = preserve
|
|
|
|
/datum/reagent/blood/affect_blood(mob/living/carbon/M, alien, removed)
|
|
if(alien == IS_SLIME) //They don't have blood, so it seems weird that they would instantly 'process' the chemical like another species does.
|
|
affect_ingest(M, alien, removed)
|
|
return
|
|
|
|
if(M.isSynthetic())
|
|
return
|
|
|
|
if(ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
|
|
var/datum/reagent/blood/recipient = H.get_blood(H.vessel)
|
|
|
|
if(recipient && blood_incompatible(data["blood_type"], recipient.data["blood_type"], data["species"], recipient.data["species"]))
|
|
H.inject_blood(src, removed * volume_mod)
|
|
|
|
if(!H.isSynthetic() && data["species"] == "synthetic") // Remember not to inject oil into your veins, it's bad for you.
|
|
H.reagents.add_reagent(REAGENT_ID_TOXIN, removed * 1.5)
|
|
return
|
|
|
|
M.inject_blood(src, volume * volume_mod)
|
|
remove_self(volume)
|
|
|
|
/datum/reagent/blood/proc/changling_blood_test(datum/reagents/holder)
|
|
if(data["changeling"])
|
|
var/location = get_turf(holder.my_atom)
|
|
holder.my_atom.visible_message(span_danger("The blood in \the [holder.my_atom] screams and leaps out!"))
|
|
if(istype(holder.my_atom,/obj/item/reagent_containers/glass))
|
|
holder.splash(location, holder.total_volume)
|
|
holder.clear_reagents() // lets be sure it's all gone if it was in something weird instead
|
|
playsound(holder.my_atom, 'sound/effects/splat.ogg', 50, 1)
|
|
playsound(holder.my_atom, 'sound/voice/hiss6.ogg', 50, 1)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/datum/reagent/blood/proc/get_diseases()
|
|
. = list()
|
|
if(data && data["viruses"])
|
|
for(var/thing in data["viruses"])
|
|
var/datum/disease/D = thing
|
|
. += D
|
|
|
|
/datum/reagent/blood/synthblood
|
|
name = REAGENT_SYNTHBLOOD
|
|
description = "Synthetic Blood"
|
|
id = REAGENT_ID_SYNTHBLOOD
|
|
color = "#999966"
|
|
volume_mod = 2
|
|
coolant_modifier = 0.25
|
|
|
|
/datum/reagent/blood/synthblood/initialize_data(newdata)
|
|
..()
|
|
if(data && !data["blood_type"])
|
|
data["blood_type"] = "O-"
|
|
if(data && data["species"])
|
|
data["species"] = null
|
|
return
|
|
|
|
/datum/reagent/blood/synthblood/dilute
|
|
name = REAGENT_SYNTHBLOOD_DILUTE
|
|
id = REAGENT_ID_SYNTHBLOOD_DILUTE
|
|
color = "#cacaaf"
|
|
volume_mod = 1.2
|
|
coolant_modifier = 0.5
|
|
|
|
// pure concentrated antibodies
|
|
/datum/reagent/antibodies
|
|
data = list(REAGENT_ID_ANTIBODIES=list())
|
|
name = REAGENT_ANTIBODIES
|
|
description = "Antibodies against some type of virus."
|
|
taste_description = "slime"
|
|
id = REAGENT_ID_ANTIBODIES
|
|
reagent_state = LIQUID
|
|
color = "#0050F0"
|
|
mrate_static = TRUE
|
|
|
|
supply_conversion_value = REFINERYEXPORT_VALUE_RARE
|
|
industrial_use = REFINERYEXPORT_REASON_MEDSCI
|
|
|
|
/datum/reagent/antibodies/affect_blood(mob/living/carbon/M, alien, removed)
|
|
if(src.data)
|
|
M.antibodies |= src.data[REAGENT_ID_ANTIBODIES]
|
|
..()
|
|
|
|
#define WATER_LATENT_HEAT 19000 // How much heat is removed when applied to a hot turf, in J/unit (19000 makes 120 u of water roughly equivalent to 4L)
|
|
|
|
/datum/reagent/water
|
|
name = REAGENT_WATER
|
|
id = REAGENT_ID_WATER
|
|
taste_description = REAGENT_ID_WATER
|
|
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
|
|
reagent_state = LIQUID
|
|
scannable = SCANNABLE_BENEFICIAL
|
|
color = "#0064C877"
|
|
metabolism = REM * 10
|
|
|
|
glass_name = REAGENT_ID_WATER
|
|
glass_desc = "The father of all refreshments."
|
|
|
|
supply_conversion_value = REFINERYEXPORT_VALUE_NO
|
|
industrial_use = REFINERYEXPORT_REASON_RAW
|
|
coolant_modifier = 1 // Water!
|
|
|
|
/datum/reagent/water/touch_turf(turf/simulated/T)
|
|
if(!istype(T))
|
|
return
|
|
|
|
..()
|
|
|
|
var/datum/gas_mixture/environment = T.return_air()
|
|
var/min_temperature = T0C + 100 // 100C, the boiling point of water
|
|
|
|
var/hotspot = (locate(/obj/fire) in T)
|
|
if(hotspot && !istype(T, /turf/space))
|
|
var/datum/gas_mixture/lowertemp = T.remove_air(T:air:total_moles)
|
|
lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0)
|
|
lowertemp.react()
|
|
T.assume_air(lowertemp)
|
|
qdel(hotspot)
|
|
|
|
if (environment && environment.temperature > min_temperature) // Abstracted as steam or something
|
|
var/removed_heat = between(0, volume * WATER_LATENT_HEAT, -environment.get_thermal_energy_change(min_temperature))
|
|
environment.add_thermal_energy(-removed_heat)
|
|
if (prob(5))
|
|
T.visible_message(span_warning("The water sizzles as it lands on \the [T]!"))
|
|
|
|
else if(volume >= 10)
|
|
T.wet_floor(1)
|
|
|
|
/datum/reagent/water/touch_obj(obj/O, amount)
|
|
..()
|
|
if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube))
|
|
var/obj/item/reagent_containers/food/snacks/monkeycube/cube = O
|
|
if(!cube.wrapped)
|
|
cube.Expand()
|
|
else if(istype(O, /obj/item/reagent_containers/food/snacks/cube))
|
|
var/obj/item/reagent_containers/food/snacks/cube/cube = O
|
|
cube.Expand()
|
|
else
|
|
O.water_act(amount / 5)
|
|
|
|
/datum/reagent/water/touch_mob(mob/living/L, amount)
|
|
..()
|
|
if(istype(L))
|
|
// First, kill slimes.
|
|
if(istype(L, /mob/living/simple_mob/slime))
|
|
var/mob/living/simple_mob/slime/S = L
|
|
S.adjustToxLoss(15 * amount)
|
|
S.visible_message(span_warning("[S]'s flesh sizzles where the water touches it!"), span_danger("Your flesh burns in the water!"))
|
|
|
|
// Then extinguish people on fire.
|
|
var/needed = max(0,L.fire_stacks) * 5
|
|
if(amount > needed)
|
|
L.extinguish_mob()
|
|
L.water_act(amount / 25) // Div by 25, as water_act multiplies it by 5 in order to calculate firestack modification.
|
|
remove_self(needed)
|
|
// Put out cigarettes if splashed.
|
|
if(ishuman(L))
|
|
var/mob/living/carbon/human/H = L
|
|
if(H.wear_mask)
|
|
if(istype(H.wear_mask, /obj/item/clothing/mask/smokable))
|
|
var/obj/item/clothing/mask/smokable/S = H.wear_mask
|
|
if(S.lit)
|
|
S.quench()
|
|
H.visible_message(span_notice("[H]\'s [S.name] is put out."))
|
|
|
|
/* //VOREStation Edit Start. Stops slimes from dying from water. Fixes fuel affect_ingest, too.
|
|
/datum/reagent/water/affect_blood(mob/living/carbon/M, alien, removed)
|
|
if(alien == IS_SLIME)
|
|
M.adjustToxLoss(6 * removed)
|
|
else
|
|
..()
|
|
|
|
/datum/reagent/water/affect_ingest(mob/living/carbon/M, alien, removed)
|
|
if(alien == IS_SLIME)
|
|
M.adjustToxLoss(6 * removed)
|
|
else
|
|
..()
|
|
|
|
/datum/reagent/water/affect_touch(mob/living/carbon/M, alien, removed)
|
|
if(alien == IS_SLIME && prob(10))
|
|
M.visible_message(span_warning("[M]'s flesh sizzles where the water touches it!"), span_danger("Your flesh burns in the water!"))
|
|
..()
|
|
*/ //VOREStation Edit End.
|
|
|
|
#undef WATER_LATENT_HEAT
|
|
|
|
/datum/reagent/fuel
|
|
name = REAGENT_FUEL
|
|
id = REAGENT_ID_FUEL
|
|
description = "Required for welders. Flamable."
|
|
taste_description = "gross metal"
|
|
reagent_state = LIQUID
|
|
scannable = SCANNABLE_ADVANCED
|
|
color = "#660000"
|
|
|
|
glass_name = "welder fuel"
|
|
glass_desc = "Unless you are an industrial tool, this is probably not safe for consumption."
|
|
|
|
supply_conversion_value = REFINERYEXPORT_VALUE_PROCESSED
|
|
industrial_use = REFINERYEXPORT_REASON_RAW
|
|
coolant_modifier = 0.15
|
|
|
|
/datum/reagent/fuel/touch_turf(turf/T, amount)
|
|
..()
|
|
new /obj/effect/decal/cleanable/liquid_fuel(T, amount, FALSE)
|
|
remove_self(amount)
|
|
return
|
|
|
|
/datum/reagent/fuel/affect_blood(mob/living/carbon/M, alien, removed)
|
|
if(issmall(M)) removed *= 2
|
|
M.adjustToxLoss(4 * removed)
|
|
|
|
/datum/reagent/fuel/touch_mob(mob/living/L, amount)
|
|
..()
|
|
if(istype(L))
|
|
L.adjust_fire_stacks(amount / 10) // Splashing people with welding fuel to make them easy to ignite!
|