Files
CHOMPStation2/code/modules/organs/blood.dm
Kelenius 317abc6b79 Merge branch 'dev' into ofChemistryAndStuff
Conflicts:
	code/datums/recipe.dm
	code/game/machinery/bots/farmbot.dm
	code/game/machinery/bots/medbot.dm
	code/game/mecha/equipment/tools/tools.dm
	code/game/objects/effects/chem/chemsmoke.dm
	code/game/objects/effects/effect_system.dm
	code/game/objects/items/toys.dm
	code/game/objects/items/weapons/extinguisher.dm
	code/game/objects/items/weapons/mop.dm
	code/modules/mob/living/carbon/human/human.dm
	code/modules/organs/organ_internal.dm
	code/modules/reagents/Chemistry-Holder.dm
	code/modules/reagents/Chemistry-Reagents.dm
	code/modules/reagents/Chemistry-Recipes.dm
	code/modules/reagents/reagent_containers/food/snacks.dm
	code/modules/reagents/reagent_containers/pill.dm
	code/modules/reagents/reagent_containers/spray.dm
	maps/exodus-1.dmm
2015-04-28 10:49:26 +03:00

318 lines
10 KiB
Plaintext

/****************************************************
BLOOD SYSTEM
****************************************************/
//Blood levels
var/const/BLOOD_VOLUME_SAFE = 501
var/const/BLOOD_VOLUME_OKAY = 336
var/const/BLOOD_VOLUME_BAD = 224
var/const/BLOOD_VOLUME_SURVIVE = 122
/mob/living/carbon/human/var/datum/reagents/vessel //Container for blood and BLOOD ONLY. Do not transfer other chems here.
/mob/living/carbon/human/var/var/pale = 0 //Should affect how mob sprite is drawn, but currently doesn't.
//Initializes blood vessels
/mob/living/carbon/human/proc/make_blood()
if(vessel)
return
vessel = new/datum/reagents(600)
vessel.my_atom = src
if(species && species.flags & NO_BLOOD) //We want the var for safety but we can do without the actual blood.
return
vessel.add_reagent("blood",560)
spawn(1)
fixblood()
//Resets blood data
/mob/living/carbon/human/proc/fixblood()
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.id == "blood")
B.data = list( "donor"=src,"viruses"=null,"species"=species.name,"blood_DNA"=dna.unique_enzymes,"blood_colour"= species.blood_color,"blood_type"=dna.b_type, \
"resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = list())
B.color = B.data["blood_colour"]
// Takes care blood loss and regeneration
/mob/living/carbon/human/proc/handle_blood()
if(species && species.flags & NO_BLOOD)
return
if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood.
var/blood_volume = round(vessel.get_reagent_amount("blood"))
//Blood regeneration if there is some space
if(blood_volume < 560 && blood_volume)
var/datum/reagent/blood/B = locate() in vessel.reagent_list //Grab some blood
if(B) // Make sure there's some blood at all
if(B.data["donor"] != src) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in vessel.reagent_list)
if(D.data["donor"] == src)
B = D
break
B.volume += 0.1 // regenerate blood VERY slowly
if(CE_BLOODRESTORE in chem_effects)
B.volume += chem_effects[CE_BLOODRESTORE]
// Damaged heart virtually reduces the blood volume, as the blood isn't
// being pumped properly anymore.
if(species && species.has_organ["heart"])
var/obj/item/organ/heart/heart = internal_organs_by_name["heart"]
if(!heart)
blood_volume = 0
else if(heart.damage > 1 && heart.damage < heart.min_bruised_damage)
blood_volume *= 0.8
else if(heart.damage >= heart.min_bruised_damage && heart.damage < heart.min_broken_damage)
blood_volume *= 0.6
else if(heart.damage >= heart.min_broken_damage && heart.damage < INFINITY)
blood_volume *= 0.3
//Effects of bloodloss
switch(blood_volume)
if(BLOOD_VOLUME_SAFE to 10000)
if(pale)
pale = 0
update_body()
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(!pale)
pale = 1
update_body()
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(prob(1))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel [word]"
if(oxyloss < 20)
oxyloss += 3
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
if(!pale)
pale = 1
update_body()
eye_blurry = max(eye_blurry,6)
if(oxyloss < 50)
oxyloss += 10
oxyloss += 1
if(prob(15))
Paralyse(rand(1,3))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
oxyloss += 5
toxloss += 3
if(prob(15))
var/word = pick("dizzy","woosey","faint")
src << "\red You feel extremely [word]"
if(0 to BLOOD_VOLUME_SURVIVE)
// There currently is a strange bug here. If the mob is not below -100 health
// when death() is called, apparently they will be just fine, and this way it'll
// spam deathgasp. Adjusting toxloss ensures the mob will stay dead.
toxloss += 300 // just to be safe!
death()
// Without enough blood you slowly go hungry.
if(blood_volume < BLOOD_VOLUME_SAFE)
if(nutrition >= 300)
nutrition -= 10
else if(nutrition >= 200)
nutrition -= 3
//Bleeding out
var/blood_max = 0
for(var/obj/item/organ/external/temp in organs)
if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
continue
for(var/datum/wound/W in temp.wounds) if(W.bleeding())
blood_max += W.damage / 40
if (temp.open)
blood_max += 2 //Yer stomach is cut open
drip(blood_max)
//Makes a blood drop, leaking amt units of blood from the mob
/mob/living/carbon/human/proc/drip(var/amt as num)
if(species && species.flags & NO_BLOOD) //TODO: Make drips come from the reagents instead.
return
if(!amt)
return
vessel.remove_reagent("blood",amt)
blood_splatter(src,src)
/****************************************************
BLOOD TRANSFERS
****************************************************/
//Gets blood from mob to the container, preserving all data in it.
/mob/living/carbon/proc/take_blood(obj/item/weapon/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"] = src
if (!B.data["virus2"])
B.data["virus2"] = list()
B.data["virus2"] |= virus_copylist(src.virus2)
B.data["antibodies"] = src.antibodies
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"]
var/list/temp_chem = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
temp_chem += R.id
temp_chem[R.id] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
return B
//For humans, blood does not appear from blue, it comes from vessels.
/mob/living/carbon/human/take_blood(obj/item/weapon/reagent_containers/container, var/amount)
if(species && species.flags & NO_BLOOD)
return null
if(vessel.get_reagent_amount("blood") < amount)
return null
. = ..()
vessel.remove_reagent("blood",amount) // Removes blood if human
//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/sniffles = virus_copylist(injected.data["virus2"])
for(var/ID in sniffles)
var/datum/disease2/disease/sniffle = sniffles[ID]
infect_virus2(src,sniffle,1)
if (injected.data["antibodies"] && prob(5))
antibodies |= injected.data["antibodies"]
var/list/chems = list()
chems = params2list(injected.data["trace_chem"])
for(var/C in chems)
src.reagents.add_reagent(C, (text2num(chems[C]) / 560) * amount)//adds trace chemicals to owner's blood
reagents.update_total()
//Transfers blood from reagents to vessel, respecting blood types compatability.
/mob/living/carbon/human/inject_blood(var/datum/reagent/blood/injected, var/amount)
if(species && species.flags & NO_BLOOD)
reagents.add_reagent("blood", amount, injected.data)
reagents.update_total()
return
var/datum/reagent/blood/our = get_blood(vessel)
if (!injected || !our)
return
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]) )
reagents.add_reagent("toxin",amount * 0.5)
reagents.update_total()
else
vessel.add_reagent("blood", amount, injected.data)
vessel.update_total()
..()
//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(res.data["donor"] != src) //If it's not theirs, then we look for theirs
for(var/datum/reagent/blood/D in container.reagent_list)
if(D.data["donor"] == src)
return D
return res
proc/blood_incompatible(donor,receiver,donor_species,receiver_species)
if(!donor || !receiver) return 0
if(donor_species && receiver_species)
if(donor_species != receiver_species)
return 1
var/donor_antigen = copytext(donor,1,lentext(donor))
var/receiver_antigen = copytext(receiver,1,lentext(receiver))
var/donor_rh = (findtext(donor,"+")>0)
var/receiver_rh = (findtext(receiver,"+")>0)
if(donor_rh && !receiver_rh) return 1
switch(receiver_antigen)
if("A")
if(donor_antigen != "A" && donor_antigen != "O") return 1
if("B")
if(donor_antigen != "B" && donor_antigen != "O") return 1
if("O")
if(donor_antigen != "O") return 1
//AB is a universal receiver.
return 0
proc/blood_splatter(var/target,var/datum/reagent/blood/source,var/large)
var/obj/effect/decal/cleanable/blood/B
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)
// 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.
for(var/obj/effect/decal/cleanable/blood/drip/drop in T)
drips |= drop.drips
qdel(drop)
if(!large && drips.len < 3)
decal_type = /obj/effect/decal/cleanable/blood/drip
// Find a blood decal or create a new one.
B = locate(decal_type) in T
if(!B)
B = new decal_type(T)
var/obj/effect/decal/cleanable/blood/drip/drop = B
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
// Update appearance.
if(source.data["blood_colour"])
B.basecolor = source.data["blood_colour"]
B.update_icon()
// 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"]
else
B.blood_DNA[source.data["blood_DNA"]] = "O+"
// Update virus information.
if(source.data["virus2"])
B.virus2 = virus_copylist(source.data["virus2"])
return B