/decl/chem (#10538)

This commit is contained in:
MarinaGryphon
2021-01-17 00:11:28 +02:00
committed by GitHub
parent 2ced864e12
commit c720e947ed
237 changed files with 5745 additions and 7000 deletions
+80 -120
View File
@@ -14,23 +14,14 @@
if(species && species.flags & NO_BLOOD) //We want the var for safety but we can do without the actual blood.
return
vessel.add_reagent(/datum/reagent/blood, species.blood_volume)
fixblood()
vessel.add_reagent(/decl/reagent/blood, species.blood_volume, temperature = species?.body_temperature)
//Resets blood data
/mob/living/carbon/human/proc/fixblood()
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.type == /datum/reagent/blood)
B.data = list(
"donor" = WEAKREF(src),
"species" = species.bodytype,
"blood_DNA" = dna.unique_enzymes,
"blood_colour" = species.blood_color,
"blood_type" = dna.b_type,
"resistances" = null,
"trace_chem" = null
)
B.color = B.data["blood_colour"]
if(!REAGENT_VOLUME(vessel, /decl/reagent/blood))
return
LAZYINITLIST(vessel.reagent_data)
LAZYSET(vessel.reagent_data, /decl/reagent/blood, get_blood_data())
//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/human/proc/drip(var/amt as num, var/tar = src, var/spraydir)
@@ -41,7 +32,7 @@
if(!amt)
return
vessel.remove_reagent(/datum/reagent/blood,amt)
vessel.remove_reagent(/decl/reagent/blood,amt)
blood_splatter(tar, src, spray_dir = spraydir)
#define BLOOD_SPRAY_DISTANCE 2
@@ -93,7 +84,7 @@
#undef BLOOD_SPRAY_DISTANCE
/mob/living/carbon/human/proc/get_blood_volume()
return round((vessel.get_reagent_amount(/datum/reagent/blood)/species.blood_volume)*100)
return round((REAGENT_VOLUME(vessel, /decl/reagent/blood)/species.blood_volume)*100)
/mob/living/carbon/human/proc/get_blood_circulation()
var/obj/item/organ/internal/heart/heart = internal_organs_by_name[BP_HEART]
@@ -149,91 +140,41 @@
//Gets blood from mob to the container, preserving all data in it.
/mob/living/carbon/proc/take_blood(obj/item/reagent_containers/container, var/amount)
var/datum/reagent/B = get_blood(container.reagents)
if(!B) B = new /datum/reagent/blood
B.holder = container
B.volume += amount
//set reagent data
B.data["donor"] = WEAKREF(src)
B.data["blood_DNA"] = copytext(src.dna.unique_enzymes,1,0)
if(src.resistances && src.resistances.len)
if(B.data["resistances"])
B.data["resistances"] |= src.resistances.Copy()
else
B.data["resistances"] = src.resistances.Copy()
B.data["blood_type"] = copytext(src.dna.b_type,1,0)
// Putting this here due to return shenanigans.
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/H = src
B.data["blood_colour"] = H.species.blood_color
B.color = B.data["blood_colour"]
B.data["species"] = H.species.bodytype
var/list/temp_chem = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
temp_chem += R.type
temp_chem[R.type] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
return B
container.reagents.add_reagent(/decl/reagent/blood, amount, get_blood_data(), temperature = species?.body_temperature)
return TRUE
//For humans, blood does not appear from blue, it comes from vessels.
/mob/living/carbon/human/take_blood(obj/item/reagent_containers/container, var/amount)
if(!should_have_organ(BP_HEART))
reagents.trans_to_obj(container, amount)
return TRUE
if(species && species.flags & NO_BLOOD)
return null
if(vessel.total_volume < amount)
return FALSE
if(vessel.get_reagent_amount(/datum/reagent/blood) < amount)
return null
vessel.trans_to_holder(container.reagents, amount)
. = ..()
vessel.remove_reagent(/datum/reagent/blood,amount) // Removes blood if human
if(vessel.has_reagent(/decl/reagent/blood))
LAZYSET(vessel.reagent_data, /decl/reagent/blood, get_blood_data())
vessel.trans_to_holder(container.reagents, amount)
return TRUE
//Transfers blood from container ot vessels
/mob/living/carbon/proc/inject_blood(var/datum/reagent/blood/injected, var/amount)
if (!injected || !istype(injected))
return
var/list/chems = list()
chems = params2list(injected.data["trace_chem"])
//Transfers blood from container to vessels
/mob/living/carbon/proc/inject_blood(var/amount, var/datum/reagents/donor)
var/list/injected_data = REAGENT_DATA(donor, /decl/reagent/blood)
var/chems = LAZYACCESS(injected_data, "trace_chem")
for(var/C in chems)
src.reagents.add_reagent(C, (text2num(chems[C]) / species.blood_volume) * amount)//adds trace chemicals to owner's blood
reagents.update_total()
reagents.add_reagent(C, (text2num(chems[C]) / species.blood_volume) * amount)//adds trace chemicals to owner's blood
//Transfers blood from reagents to vessel, respecting blood types compatability.
/mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount)
// In case of mobs without blood, put it in their chem storage.
if(species.flags & NO_BLOOD)
reagents.add_reagent(/datum/reagent/blood, amount, injected.data)
reagents.update_total()
/mob/living/carbon/human/inject_blood(var/amount, var/datum/reagents/donor)
if(!should_have_organ(BP_HEART))
reagents.add_reagent(/decl/reagent/blood, amount, REAGENT_DATA(donor, /decl/reagent/blood), temperature = species?.body_temperature)
return
var/datum/reagent/blood/our = get_blood(vessel)
if (!injected || !our)
return
var/datum/vampire/vampire
if(mind)
vampire = mind.antag_datums[MODE_VAMPIRE]
if(!vampire && blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]))
reagents.add_reagent(/datum/reagent/toxin,amount * 0.5)
reagents.update_total()
else
vessel.add_reagent(/datum/reagent/blood, amount, injected.data)
vessel.update_total()
// Incompatibility is handled in mix_data now.
vessel.add_reagent(/decl/reagent/blood, amount, REAGENT_DATA(donor, /decl/reagent/blood), temperature = species?.body_temperature)
..()
//Gets human's own blood.
/mob/living/carbon/proc/get_blood(datum/reagents/container)
var/datum/reagent/blood/res = locate() in container.reagent_list //Grab some blood
if(res) // Make sure there's some blood at all
if(weakref && res.data["donor"] != weakref) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in container.reagent_list)
if(D.data["donor"] == weakref)
return D
return res
proc/blood_incompatible(donor,receiver,donor_species,receiver_species)
if(!donor || !receiver) return 0
@@ -257,19 +198,31 @@ proc/blood_incompatible(donor,receiver,donor_species,receiver_species)
//AB is a universal receiver.
return 0
proc/blood_splatter(var/target, var/datum/reagent/blood/source, var/large, var/spray_dir)
/mob/living/carbon/proc/get_blood_data()
var/data = list()
data["donor"] = WEAKREF(src)
if(dna)
data["blood_DNA"] = dna.unique_enzymes
data["blood_type"] = dna.b_type
else
data["blood_DNA"] = md5(ref(src))
data["blood_type"] = "O+"
if(species)
data["species"] = species.bodytype
data["blood_colour"] = species.blood_color
var/list/temp_chem = list()
for(var/R in reagents.reagent_volumes)
temp_chem[R] = REAGENT_VOLUME(reagents, R)
data["trace_chem"] = temp_chem
data["dose_chem"] = chem_doses.Copy()
return data
var/obj/effect/decal/cleanable/blood/B
proc/blood_splatter(var/target, var/source, var/large, var/spray_dir)
var/obj/effect/decal/cleanable/blood/splatter
var/decal_type = /obj/effect/decal/cleanable/blood/splatter
var/turf/T = get_turf(target)
if(istype(source,/mob/living/carbon/human))
var/mob/living/carbon/human/M = source
source = M.get_blood(M.vessel)
if(!istype(source))
source = null
// Are we dripping or splattering?
var/list/drips = list()
// Only a certain number of drips (or one large splatter) can be on a given turf.
@@ -280,40 +233,47 @@ proc/blood_splatter(var/target, var/datum/reagent/blood/source, var/large, var/s
decal_type = /obj/effect/decal/cleanable/blood/drip
// Find a blood decal or create a new one.
B = locate(decal_type) in T
if(T)
var/list/existing = filter_list(T.contents, decal_type)
if(length(existing) > 3)
B = pick(existing)
if(!B)
B = new decal_type(T)
splatter = pick(existing)
if(!splatter)
splatter = new decal_type(T)
var/obj/effect/decal/cleanable/blood/drip/drop = B
if(istype(drop) && LAZYLEN(drips) && !large)
drop.add_overlay(drips)
var/obj/effect/decal/cleanable/blood/drip/drop = splatter
if(istype(drop) && drips && drips.len && !large)
drop.overlays |= drips
drop.drips |= drips
// If there's no data to copy, call it quits here.
if(!source)
return B
var/list/blood_data
if(islist(source))
blood_data = source
if(ishuman(source))
var/mob/living/carbon/human/donor = source
blood_data = donor.get_blood_data()
else if(isatom(source))
var/atom/donor = source
blood_data = REAGENT_DATA(donor.reagents, /decl/reagent/blood)
if(!islist(blood_data))
return splatter
// Update appearance.
if(source.data["blood_colour"])
B.basecolor = source.data["blood_colour"]
B.update_icon()
if(blood_data["blood_colour"])
splatter.basecolor = blood_data["blood_colour"]
splatter.update_icon()
if(spray_dir)
B.icon_state = "squirt"
B.dir = spray_dir
splatter.icon_state = "squirt"
splatter.set_dir(spray_dir)
// Update blood information.
if(source.data["blood_DNA"])
B.blood_DNA = list()
if(source.data["blood_type"])
B.blood_DNA[source.data["blood_DNA"]] = source.data["blood_type"]
if(blood_data["blood_DNA"])
splatter.blood_DNA = list()
if(blood_data["blood_type"])
splatter.blood_DNA[blood_data["blood_DNA"]] = blood_data["blood_type"]
else
B.blood_DNA[source.data["blood_DNA"]] = "O+"
splatter.blood_DNA[blood_data["blood_DNA"]] = "O+"
B.fluorescent = 0
B.invisibility = 0
return B
splatter.fluorescent = 0
splatter.invisibility = 0
return splatter
+1 -1
View File
@@ -124,7 +124,7 @@
tick_surge_damage() //Yes, this is intentional.
/obj/item/organ/internal/proc/handle_regeneration()
if(!damage || BP_IS_ROBOTIC(src) || !owner || owner.chem_effects[CE_TOXIN] || owner.is_asystole())
if(!damage || BP_IS_ROBOTIC(src) || !istype(owner) || owner.chem_effects[CE_TOXIN] || (toxin_type in owner.chem_effects) || owner.is_asystole())
return
if(damage < 0.1*max_damage)
heal_damage(0.1)
+5 -14
View File
@@ -116,24 +116,15 @@
return
if(pulse != PULSE_NONE || BP_IS_ROBOTIC(src))
var/blood_volume = round(owner.vessel.get_reagent_amount(/datum/reagent/blood))
var/blood_volume = round(REAGENT_VOLUME(owner.vessel, /decl/reagent/blood))
//Blood regeneration if there is some space
if(blood_volume < species.blood_volume && blood_volume)
var/datum/reagent/blood/B = locate() in owner.vessel.reagent_list //Grab some blood
if(B) // Make sure there's some blood at all
if(weakref && B.data["donor"] != weakref) //If it's not theirs, then we look for theirs - donor is a weakref here, but it should be safe to just directly compare it.
for(var/datum/reagent/blood/D in owner.vessel.reagent_list)
if(weakref && D.data["donor"] == weakref)
B = D
break
B.volume += 0.1 // regenerate blood VERY slowly
if(blood_volume <= BLOOD_VOLUME_SAFE) //We loose nutrition and hydration very slowly if our blood is too low
if(REAGENT_DATA(owner.vessel, /decl/reagent/blood)) // Make sure there's blood at all
owner.vessel.add_reagent(/decl/reagent/blood, 0.1 + LAZYACCESS(owner.chem_effects, CE_BLOODRESTORE), temperature = species?.body_temperature)
if(blood_volume <= BLOOD_VOLUME_SAFE) //We lose nutrition and hydration very slowly if our blood is too low
owner.adjustNutritionLoss(2)
owner.adjustHydrationLoss(1)
if(CE_BLOODRESTORE in owner.chem_effects)
B.volume += owner.chem_effects[CE_BLOODRESTORE]
//Bleeding out
var/blood_max = 0
@@ -162,7 +153,7 @@
blood_max += bleed_amount
do_spray += "[temp.name]"
else
owner.vessel.remove_reagent(/datum/reagent/blood, bleed_amount)
owner.vessel.remove_reagent(/decl/reagent/blood, bleed_amount)
switch(pulse)
if(PULSE_SLOW)
+6 -6
View File
@@ -22,7 +22,7 @@
// Coffee is really bad for you with busted kidneys.
// This should probably be expanded in some way, but fucked if I know
// what else kidneys can process in our reagent list.
var/datum/reagent/drink/coffee = locate(/datum/reagent/drink/coffee) in owner.reagents.reagent_list
var/decl/reagent/drink/coffee = REAGENT_VOLUME(owner.reagents, /decl/reagent/drink/coffee)
if(coffee)
if(is_bruised())
owner.adjustToxLoss(0.1 * PROCESS_ACCURACY)
@@ -30,11 +30,11 @@
owner.adjustToxLoss(0.3 * PROCESS_ACCURACY)
if(is_bruised())
if(prob(5) && reagents.get_reagent_amount(/datum/reagent/potassium) < 5)
reagents.add_reagent(/datum/reagent/potassium, REM*5)
if(prob(5) && REAGENT_VOLUME(reagents, /decl/reagent/potassium) < 5)
reagents.add_reagent(/decl/reagent/potassium, REM*5)
if(is_broken())
if(owner.reagents.get_reagent_amount(/datum/reagent/potassium) < 15)
owner.reagents.add_reagent(/datum/reagent/potassium, REM*2)
if(REAGENT_VOLUME(owner.reagents, /decl/reagent/potassium) < 15)
owner.reagents.add_reagent(/decl/reagent/potassium, REM*2)
//If your kidneys aren't working, your body's going to have a hard time cleaning your blood.
if(!owner.chem_effects[CE_ANTITOXIN])
@@ -42,4 +42,4 @@
if(is_broken())
owner.adjustToxLoss(0.5)
if(status & ORGAN_DEAD)
owner.adjustToxLoss(1)
owner.adjustToxLoss(1)
+2 -2
View File
@@ -234,7 +234,7 @@
if(toxins_pp > safe_toxins_max)
var/ratio = (poison/safe_toxins_max) * 10
if(reagents)
reagents.add_reagent(/datum/reagent/toxin, Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE))
reagents.add_reagent(/decl/reagent/toxin, Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE))
breath.adjust_gas(poison_type, -poison/6, update = 0) //update after
owner.phoron_alert = max(owner.phoron_alert, 1)
else
@@ -377,4 +377,4 @@
rescued = FALSE
#undef HUMAN_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
#undef HUMAN_CRIT_MAX_OXYLOSS
+1 -1
View File
@@ -126,7 +126,7 @@
if(should_process_alcohol)
var/alcohol_volume = ingested.get_reagent_amount(/datum/reagent/alcohol/ethanol)
var/alcohol_volume = REAGENT_VOLUME(ingested, /decl/reagent/alcohol)
// Alcohol counts as double volume for the purposes of vomit probability
var/effective_volume = ingested.total_volume + alcohol_volume
+8 -9
View File
@@ -174,11 +174,10 @@
log_debug("Organ [DEBUG_REF(src)] had QDELETED reagents! Regenerating.")
create_reagents(5)
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in reagents.reagent_list
if(B && !(status & ORGAN_ROBOT) && prob(40))
reagents.remove_reagent(/datum/reagent/blood,0.1)
if(REAGENT_VOLUME(reagents, /decl/reagent/blood) && !(status & ORGAN_ROBOT) && prob(40))
reagents.remove_reagent(/decl/reagent/blood,0.1)
if (isturf(loc))
blood_splatter(src,B,1)
blood_splatter(src,src,TRUE)
if(config.organs_decay) damage += rand(1,3)
if(damage >= max_damage)
damage = max_damage
@@ -267,7 +266,7 @@
germ_level += rand(2,3)
if(501 to INFINITY)
germ_level += rand(3,5)
owner.reagents.add_reagent(/datum/reagent/toxin, rand(1,2))
owner.reagents.add_reagent(/decl/reagent/toxin, rand(1,2))
/obj/item/organ/proc/receive_chem(chemical as obj)
return 0
@@ -287,10 +286,10 @@
//Germs
/obj/item/organ/proc/handle_antibiotics()
if(!owner)
if(!owner || !(CE_ANTIBIOTIC in owner.chem_effects))
return
var/antibiotics = owner.reagents?.get_reagent_amount(/datum/reagent/thetamycin)
var/antibiotics = owner.chem_effects[CE_ANTIBIOTIC]
if (!germ_level || antibiotics < 5)
return
@@ -391,8 +390,8 @@
if (!reagents)
create_reagents(5)
var/datum/reagent/blood/organ_blood = locate(/datum/reagent/blood) in reagents.reagent_list
if(!organ_blood || !organ_blood.data["blood_DNA"])
var/blood_data = LAZYACCESS(reagents.reagent_data, /decl/reagent/blood)
if(!("blood_DNA" in blood_data))
owner.vessel.trans_to(src, 5, 1, 1)
if(owner && vital)
+4 -4
View File
@@ -137,7 +137,7 @@
to_chat(owner, "<span class='notice'>\The [src] activates, releasing a stream of chemicals into your veins!</span>")
owner.reagents.add_reagent(/datum/reagent/adrenaline, 15)
owner.reagents.add_reagent(/decl/reagent/adrenaline, 15)
/obj/item/organ/internal/augment/venomous_rest
name = "venomous rest implant"
@@ -156,9 +156,9 @@
return FALSE
if(owner.reagents)
owner.reagents.add_reagent(/datum/reagent/inaprovaline, 10)
owner.reagents.add_reagent(/datum/reagent/tricordrazine, 10)
owner.reagents.add_reagent(/datum/reagent/soporific, 15)
owner.reagents.add_reagent(/decl/reagent/inaprovaline, 10)
owner.reagents.add_reagent(/decl/reagent/tricordrazine, 10)
owner.reagents.add_reagent(/decl/reagent/soporific, 15)
take_damage(15)
to_chat(owner, "<span class='notice'>\The [src] activates, releasing a stream of chemicals into your veins!</span>")
+8 -8
View File
@@ -90,8 +90,8 @@
set_light(1, l_color = "#E6E600")
if(prob(10))
to_chat(owner, "<span class='warning'>You feel something squirming inside of you!</span>")
owner.reagents.add_reagent(/datum/reagent/toxin/phoron, 8)
owner.reagents.add_reagent(/datum/reagent/kois, 5)
owner.reagents.add_reagent(/decl/reagent/toxin/phoron, 8)
owner.reagents.add_reagent(/decl/reagent/kois, 5)
if(stage >= 4)
if(prob(10))
@@ -101,8 +101,8 @@
var/turf/T = get_turf(owner)
var/datum/reagents/R = new/datum/reagents(100)
R.add_reagent(/datum/reagent/kois,10)
R.add_reagent(/datum/reagent/toxin/phoron,10)
R.add_reagent(/decl/reagent/kois,10)
R.add_reagent(/decl/reagent/toxin/phoron,10)
var/datum/effect/effect/system/smoke_spread/chem/spores/S = new("koisspore")
S.attach(T)
@@ -157,7 +157,7 @@
if(prob(5))
to_chat(owner, "<span class='warning'>You feel something squirming inside of you!</span>")
owner.reagents.add_reagent(/datum/reagent/kois/black, 4)
owner.reagents.add_reagent(/decl/reagent/kois/black, 4)
else if(prob(10))
to_chat(owner, "<span class='warning'>You feel disorientated!</span>")
@@ -199,8 +199,8 @@
var/turf/T = get_turf(owner)
var/datum/reagents/R = new/datum/reagents(100)
R.add_reagent(/datum/reagent/kois/black,10)
R.add_reagent(/datum/reagent/toxin/phoron,5)
R.add_reagent(/decl/reagent/kois/black,10)
R.add_reagent(/decl/reagent/toxin/phoron,5)
var/datum/effect/effect/system/smoke_spread/chem/spores/S = new("blackkois")
S.attach(T)
@@ -318,4 +318,4 @@
owner.change_skin_color(r, g, b)
owner.update_dna()
else
owner.adjustToxLoss(50)
owner.adjustToxLoss(50)