diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm
index 1baa779b492..f6942031dbf 100644
--- a/code/__DEFINES/genetics.dm
+++ b/code/__DEFINES/genetics.dm
@@ -124,6 +124,13 @@
#define NUTRITION_LEVEL_HUNGRY 250
#define NUTRITION_LEVEL_STARVING 150
+//Blood levels
+#define BLOOD_VOLUME_NORMAL 560
+#define BLOOD_VOLUME_SAFE 501
+#define BLOOD_VOLUME_OKAY 336
+#define BLOOD_VOLUME_BAD 224
+#define BLOOD_VOLUME_SURVIVE 122
+
//Used for calculations for negative effects of having genetics powers
#define DEFAULT_GENE_STABILITY 100
#define GENE_INSTABILITY_MINOR 5
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 3cf3cb9b198..609274fbc17 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -172,11 +172,12 @@
// I'm not sure WHY you'd want to put a simple_animal in a sleeper, but precedent is precedent
// Runtime is aptly named, isn't she?
if(ishuman(occupant) && occupant.vessel && !(occupant.species && occupant.species.flags & NO_BLOOD))
+ var/blood_type = occupant.get_blood_name()
occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL)
occupantData["hasBlood"] = 1
- occupantData["bloodLevel"] = round(occupant.vessel.get_reagent_amount("blood"))
+ occupantData["bloodLevel"] = round(occupant.vessel.get_reagent_amount(blood_type))
occupantData["bloodMax"] = occupant.max_blood
- occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount("blood")/occupant.max_blood), 0.01)
+ occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount(blood_type)/occupant.max_blood), 0.01)
data["occupant"] = occupantData
data["maxchem"] = connected.max_chem
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index 157ffaf5cac..decb7fc5922 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -357,12 +357,13 @@
var/bloodData[0]
bloodData["hasBlood"] = 0
if(ishuman(H) && H.vessel && !(H.species && H.species.flags & NO_BLOOD))
- var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
+ var/blood_type = H.get_blood_name()
+ var/blood_volume = round(H.vessel.get_reagent_amount(blood_type))
bloodData["hasBlood"] = 1
bloodData["volume"] = blood_volume
- bloodData["percent"] = round(((blood_volume / 560)*100))
+ bloodData["percent"] = round(((blood_volume / BLOOD_VOLUME_NORMAL)*100))
bloodData["pulse"] = H.get_pulse(GETPULSE_TOOL)
- bloodData["bloodLevel"] = round(H.vessel.get_reagent_amount("blood"))
+ bloodData["bloodLevel"] = blood_volume
bloodData["bloodMax"] = H.max_blood
occupantData["blood"] = bloodData
@@ -530,8 +531,9 @@
dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
"
if(occupant.vessel)
- var/blood_volume = round(occupant.vessel.get_reagent_amount("blood"))
- var/blood_percent = blood_volume / 560
+ var/blood_type = occupant.get_blood_name()
+ var/blood_volume = round(occupant.vessel.get_reagent_amount(blood_type))
+ var/blood_percent = blood_volume / BLOOD_VOLUME_NORMAL
blood_percent *= 100
extra_font = (blood_volume > 448 ? "" : "")
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index 10ae5692ba2..81753797b57 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -132,11 +132,12 @@
occupantData["btFaren"] = ((occupant.bodytemperature - T0C) * (9.0/5.0))+ 32
if(ishuman(occupant) && occupant.vessel && !(occupant.species && occupant.species.flags & NO_BLOOD))
+ var/blood_type = occupant.get_blood_name()
occupantData["pulse"] = occupant.get_pulse(GETPULSE_TOOL)
occupantData["hasBlood"] = 1
- occupantData["bloodLevel"] = round(occupant.vessel.get_reagent_amount("blood"))
+ occupantData["bloodLevel"] = round(occupant.vessel.get_reagent_amount(blood_type))
occupantData["bloodMax"] = occupant.max_blood
- occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount("blood")/occupant.max_blood), 0.01) //copy pasta ends here
+ occupantData["bloodPercent"] = round(100*(occupant.vessel.get_reagent_amount(blood_type)/occupant.max_blood), 0.01) //copy pasta ends here
occupantData["bloodType"]=occupant.b_type
if(occupant.surgeries.len)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 6b472f95b80..45438785015 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -227,8 +227,9 @@ REAGENT SCANNER
user.show_message(text("\red Internal bleeding detected. Advanced scanner required for location."), 1)
break
if(H.vessel)
- var/blood_volume = round(M:vessel.get_reagent_amount("blood"))
- var/blood_percent = blood_volume / 560
+ var/blood_type = H.get_blood_name()
+ var/blood_volume = round(H.vessel.get_reagent_amount(blood_type))
+ var/blood_percent = blood_volume / BLOOD_VOLUME_NORMAL
blood_percent *= 100
if(blood_volume <= 500)
user.show_message("\red Warning: Blood Level LOW: [blood_percent]% [blood_volume]cl")
@@ -236,6 +237,9 @@ REAGENT SCANNER
user.show_message("\red Warning: Blood Level CRITICAL: [blood_percent]% [blood_volume]cl")
else
user.show_message("\blue Blood Level Normal: [blood_percent]% [blood_volume]cl")
+ if(H.species.exotic_blood)
+ user.show_message("Subject possesses exotic blood.")
+ user.show_message("Exotic blood type: [blood_type].")
if(H.heart_attack && H.stat != DEAD)
user.show_message("Subject suffering from heart attack: Apply defibrillator immediately.")
user.show_message("\blue Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 54cceec0635..0e2e95bc778 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -317,8 +317,9 @@ This function restores the subjects blood to max.
*/
/mob/living/carbon/human/proc/restore_blood()
if(!(species.flags & NO_BLOOD))
- var/blood_volume = vessel.get_reagent_amount("blood")
- vessel.add_reagent("blood", 560.0 - blood_volume)
+ var/blood_type = get_blood_name()
+ var/blood_volume = vessel.get_reagent_amount(blood_type)
+ vessel.add_reagent(blood_type, BLOOD_VOLUME_NORMAL - blood_volume)
/*
This function restores all organs.
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 3af93392326..d4f000ad8fe 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -70,7 +70,7 @@ var/global/default_martial_art = new/datum/martial_art
var/mob/remoteview_target = null
var/meatleft = 3 //For chef item
var/decaylevel = 0 // For rotting bodies
- var/max_blood = 560 // For stuff in the vessel
+ var/max_blood = BLOOD_VOLUME_NORMAL // For stuff in the vessel
var/slime_color = "blue" //For slime people this defines their color, it's blue by default to pay tribute to the old icons
var/check_mutations=0 // Check mutations on next life tick
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index d877c983e1e..28e39b53f6e 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -176,7 +176,7 @@
if(gene.is_active(src))
speech_problem_flag = 1
gene.OnMobLife(src)
- if(gene_stability < 85)
+ if(gene_stability < 85)
var/instability = DEFAULT_GENE_STABILITY - gene_stability
if(prob(instability / 10))
adjustFireLoss(min(6, instability / 12))
@@ -1067,7 +1067,8 @@
var/temp = PULSE_NORM
- if(round(vessel.get_reagent_amount("blood")) <= BLOOD_VOLUME_BAD) //how much blood do we have
+ var/blood_type = get_blood_name()
+ if(round(vessel.get_reagent_amount(blood_type)) <= BLOOD_VOLUME_BAD) //how much blood do we have
temp = PULSE_THREADY //not enough :(
if(status_flags & FAKEDEATH)
diff --git a/code/modules/reagents/newchem/medicine.dm b/code/modules/reagents/newchem/medicine.dm
index 3094f590d3f..9357fc62899 100644
--- a/code/modules/reagents/newchem/medicine.dm
+++ b/code/modules/reagents/newchem/medicine.dm
@@ -59,7 +59,7 @@ datum/reagent/styptic_powder/on_mob_life(var/mob/living/M as mob)
..()
return
-datum/reagent/salglu_solution
+/datum/reagent/salglu_solution
name = "Saline-Glucose Solution"
id = "salglu_solution"
description = "This saline and glucose solution can help stabilize critically injured patients and cleanse wounds."
@@ -68,13 +68,17 @@ datum/reagent/salglu_solution
penetrates_skin = 1
metabolization_rate = 0.15
-datum/reagent/salglu_solution/on_mob_life(var/mob/living/M as mob)
- if(!M) M = holder.my_atom
+/datum/reagent/salglu_solution/on_mob_life(mob/living/M)
+ if(!M)
+ M = holder.my_atom
if(prob(33))
M.adjustBruteLoss(-2*REM)
M.adjustFireLoss(-2*REM)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(!H.species.exotic_blood && !(H.species.flags & NO_BLOOD) && prob(33))
+ H.vessel.add_reagent("blood", 1)
..()
- return
datum/reagent/synthflesh
name = "Synthflesh"
diff --git a/code/modules/reagents/oldchem/reagents/reagents_food.dm b/code/modules/reagents/oldchem/reagents/reagents_food.dm
index c2711aac2f4..90c65bbf4eb 100644
--- a/code/modules/reagents/oldchem/reagents/reagents_food.dm
+++ b/code/modules/reagents/oldchem/reagents/reagents_food.dm
@@ -9,19 +9,25 @@
nutriment_factor = 12 * REAGENTS_METABOLISM
color = "#664330" // rgb: 102, 67, 48
-/datum/reagent/nutriment/on_mob_life(var/mob/living/M as mob)
- if(!M) M = holder.my_atom
+/datum/reagent/nutriment/on_mob_life(mob/living/M)
+ if(!M)
+ M = holder.my_atom
if(!(M.mind in ticker.mode.vampires))
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.can_eat()) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients
H.nutrition += nutriment_factor // For hunger and fatness
- if(prob(50)) M.adjustBruteLoss(-1)
+ if(prob(50))
+ M.adjustBruteLoss(-1)
+ if(H.species.exotic_blood)
+ H.vessel.add_reagent(H.species.exotic_blood, 0.4)
+ else
+ if(!(H.species.flags & NO_BLOOD))
+ H.vessel.add_reagent("blood", 0.4)
if(istype(M,/mob/living/simple_animal)) //Any nutrients can heal simple animals
- if(prob(50)) M.heal_organ_damage(1,0)
+ if(prob(50))
+ M.heal_organ_damage(1,0)
..()
- return
-
/datum/reagent/protein // Meat-based protein, digestable by carnivores and omnivores, worthless to herbivores
name = "Protein"
diff --git a/code/modules/reagents/oldchem/reagents/reagents_misc.dm b/code/modules/reagents/oldchem/reagents/reagents_misc.dm
index 889a2011d48..e6064e54347 100644
--- a/code/modules/reagents/oldchem/reagents/reagents_misc.dm
+++ b/code/modules/reagents/oldchem/reagents/reagents_misc.dm
@@ -150,20 +150,15 @@
description = "Pure iron is a metal."
reagent_state = SOLID
color = "#C8A5DC" // rgb: 200, 165, 220
-/*
-/datum/reagent/iron/on_mob_life(var/mob/living/M as mob)
- if(!M) M = holder.my_atom
- if((M.virus) && (prob(8) && (M.virus.name=="Magnitis")))
- if(M.virus.spread == "Airborne")
- M.virus.spread = "Remissive"
- M.virus.stage--
- if(M.virus.stage <= 0)
- M.resistances += M.virus.type
- M.virus = null
- holder.remove_reagent(src.id, 0.2)
- return
-*/
+/datum/reagent/iron/on_mob_life(mob/living/M)
+ if(!M)
+ M = holder.my_atom
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(!H.species.exotic_blood && !(H.species.flags & NO_BLOOD))
+ H.vessel.add_reagent("blood", 0.8)
+ ..()
//foam
diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm
index 77c12cd78a8..d549b2ec997 100644
--- a/code/modules/surgery/organs/blood.dm
+++ b/code/modules/surgery/organs/blood.dm
@@ -1,14 +1,8 @@
/****************************************************
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()
@@ -60,12 +54,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
blood_volume = round(vessel.get_reagent_amount(blood_reagent))
if(blood_volume < max_blood && blood_volume)
vessel.add_reagent(blood_reagent, 0.1) // regenerate blood VERY slowly
- if(reagents.has_reagent("nutriment")) //Getting food speeds it up
+ if(reagents.has_reagent(blood_reagent))
vessel.add_reagent(blood_reagent, 0.4)
- reagents.remove_reagent("nutriment", 0.1)
- else if(reagents.has_reagent(blood_reagent))
- vessel.add_reagent(blood_reagent, 0.4)
- reagents.remove_reagent(blood_reagent, 0.4)
else
blood_volume = round(vessel.get_reagent_amount("blood"))
@@ -73,14 +63,13 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if(blood_volume < max_blood && 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(src.mind) //Handles vampires "eating" blood that isn't their own.
- if(src.mind in ticker.mode.vampires)
+ if(mind) //Handles vampires "eating" blood that isn't their own.
+ if(mind in ticker.mode.vampires)
for(var/datum/reagent/blood/BL in vessel.reagent_list)
- if(src.nutrition >= 450)
+ if(nutrition >= 450)
break //We don't want blood tranfusions making vampires fat.
if(BL.data["donor"] != src)
- src.nutrition += (15 * REAGENTS_METABOLISM)
+ nutrition += (15 * REAGENTS_METABOLISM)
BL.volume -= REAGENTS_METABOLISM
if(BL.volume <= 0)
qdel(BL)
@@ -93,85 +82,48 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
break
vessel.add_reagent("blood", 0.1) // regenerate blood VERY slowly
- if(reagents.has_reagent("nutriment")) //Getting food speeds it up
- vessel.add_reagent("blood", 0.4)
- reagents.remove_reagent("nutriment", 0.1)
- if(reagents.has_reagent("iron")) //Hematogen candy anyone?
- vessel.add_reagent("blood", 0.8)
- reagents.remove_reagent("iron", 0.1)
- if(reagents.has_reagent("salglu_solution")) //saline is good for blood regeneration
- if(prob(33))
- vessel.add_reagent("blood", 1.0)
- // Damaged heart virtually reduces the blood volume, as the blood isn't
- // being pumped properly anymore.
- var/obj/item/organ/internal/heart/heart = get_int_organ(/obj/item/organ/internal/heart)
-
- if(heart)
- 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
+ var/oxy_immune = species.flags & NO_BREATHE //Some species have blood, but don't breathe; they should still suffer the 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")
- to_chat(src, "\red You feel [word]")
- if(prob(1))
- var/word = pick("dizzy","woosey","faint")
- to_chat(src, "\red You feel [word]")
- if(oxyloss < 20)
- oxyloss += 3
+ if(prob(5))
+ to_chat(src, "You feel [pick("dizzy","woozy","faint")].")
+ if(oxy_immune)
+ adjustToxLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
+ else
+ adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
- if(!pale)
- pale = 1
- update_body()
- eye_blurry += 6
- if(oxyloss < 50)
- oxyloss += 10
- oxyloss += 1
- if(prob(15))
- Paralyse(rand(1,3))
- var/word = pick("dizzy","woosey","faint")
- to_chat(src, "\red You feel very [word]")
+ if(oxy_immune)
+ adjustToxLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
+ else
+ adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
+ if(prob(5))
+ eye_blurry = max(eye_blurry, 6)
+ var/word = pick("dizzy","woozy","faint")
+ to_chat(src, "You feel very [word].")
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
- if(!pale)
- pale = 1
- update_body()
- if(oxyloss > 20)
- eye_blurry += 6
- oxyloss += 12
+ if(oxy_immune)
+ adjustToxLoss(5)
+ else
+ adjustOxyLoss(5)
if(prob(15))
Paralyse(rand(1,3))
- var/word = pick("dizzy","woosey","faint")
- to_chat(src, "\red You feel extremely [word]")
+ var/word = pick("dizzy","woozy","faint")
+ to_chat(src, "You feel extremely [word].")
if(0 to BLOOD_VOLUME_SURVIVE)
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 / 4
+ for(var/datum/wound/W in temp.wounds)
+ if(W.bleeding())
+ blood_max += W.damage / 4
if(temp.open)
blood_max += 2 //Yer stomach is cut open
drip(blood_max)
@@ -188,7 +140,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
var/amm = 0.1 * amt
var/turf/T = get_turf(src)
- if(src.species.exotic_blood)
+ if(species.exotic_blood)
vessel.remove_reagent(species.exotic_blood,amm)
if(vessel.total_volume)
var/fraction = amm / vessel.total_volume
@@ -197,7 +149,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
else
vessel.remove_reagent("blood",amm)
- blood_splatter(src,src)
+ blood_splatter(src, src)
/****************************************************
@@ -269,7 +221,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
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
+ src.reagents.add_reagent(C, (text2num(chems[C]) / BLOOD_VOLUME_NORMAL) * amount)//adds trace chemicals to owner's blood
reagents.update_total()
container.reagents.remove_reagent("blood", amount)