diff --git a/code/game/gamemodes/cult/construct_spells.dm b/code/game/gamemodes/cult/construct_spells.dm index 62cdd5bf48..6273273c98 100644 --- a/code/game/gamemodes/cult/construct_spells.dm +++ b/code/game/gamemodes/cult/construct_spells.dm @@ -472,7 +472,7 @@ var/mob/living/carbon/human/H = owner if(!H.should_have_organ(O_HEART)) return 1 - if(H.vessel.remove_reagent("blood", amount)) + if(H.remove_blood(amount)) return 1 return 0 @@ -673,4 +673,4 @@ else user.visible_message("\The [user] lowers its fist.") return - qdel(src) \ No newline at end of file + qdel(src) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 990b6b4c3f..092185ed88 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1263,7 +1263,7 @@ vessel.maximum_volume = species.blood_volume vessel.add_reagent("blood", species.blood_volume - vessel.total_volume) else if(vessel.total_volume > species.blood_volume) - vessel.remove_reagent("blood", vessel.total_volume - species.blood_volume) + vessel.remove_reagent("blood",vessel.total_volume - species.blood_volume) //This one should stay remove_reagent to work even lack of a O_heart vessel.maximum_volume = species.blood_volume fixblood() species.update_attack_types() //VOREStation Edit - Required for any trait that updates unarmed_types in setup. @@ -1733,7 +1733,7 @@ if(blood_volume < species?.blood_volume*species?.blood_level_fatal) bloodtrail = 0 //Most of it's gone already, just leave it be else - vessel.remove_reagent("blood", 1) + remove_blood(1) if(bloodtrail) if(istype(loc, /turf/simulated)) var/turf/T = loc diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm index d206cb5820..0b1c99d64b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm @@ -183,7 +183,7 @@ if(!docile && ishuman(host) && chemicals < max_chemicals) var/mob/living/carbon/human/H = host - H.vessel.remove_reagent("blood", 1) + H.remove_blood(1) if(!H.reagents.has_reagent("inaprovaline")) H.reagents.add_reagent("inaprovaline", 1) chemicals += 2 diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index 071bb05e91..9d36c005d0 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -1,3 +1,4 @@ +#define BLOOD_MINIMUM_STOP_PROCESS 2.1 // Define to avoid hitting 0 blood. /**************************************************** BLOOD SYSTEM ****************************************************/ @@ -14,8 +15,12 @@ var/const/CE_STABLE_THRESHOLD = 0.5 /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() +/***Initializes blood vessels + * Called code/modules/mob/living/carbon/human/human.dm#L1259 set_species procedure with 0 args + * Also called by inject_blood as fallback with amt = injected_amount + * MUST be followed by calling fixblood() allways. +***/ +/mob/living/carbon/human/proc/make_blood(var/amt = 0) if(vessel) return @@ -29,7 +34,11 @@ var/const/CE_STABLE_THRESHOLD = 0.5 if(!should_have_organ(O_HEART)) //We want the var for safety but we can do without the actual blood. return - vessel.add_reagent("blood",species.blood_volume) + if(!amt) + vessel.add_reagent("blood",species.blood_volume) + else + vessel.add_reagent("blood", clamp(amt, 1, species.blood_volume)) + //Resets blood data /mob/living/carbon/human/proc/fixblood() @@ -210,10 +219,14 @@ var/const/CE_STABLE_THRESHOLD = 0.5 if(!amt) return 0 - if(amt > vessel.get_reagent_amount("blood")) - amt = vessel.get_reagent_amount("blood") - 1 // Bit of a safety net; it's impossible to add blood if there's not blood already in the vessel. + var/current_blood = vessel.get_reagent_amount("blood") + if(current_blood < BLOOD_MINIMUM_STOP_PROCESS) + return 0 //We stop processing under 3 units of blood because apparently weird shit can make it overflowrandomly. - return vessel.remove_reagent("blood",amt * (src.mob_size/MOB_MEDIUM)) + if(amt > current_blood) + amt = current_blood - 2 // Bit of a safety net; it's impossible to add blood if there's not blood already in the vessel. + + return vessel.remove_reagent("blood",amt) /**************************************************** BLOOD TRANSFERS @@ -256,11 +269,11 @@ var/const/CE_STABLE_THRESHOLD = 0.5 if(!should_have_organ(O_HEART)) return null - if(vessel.get_reagent_amount("blood") < amount) + if(vessel.get_reagent_amount("blood") < max(amount, BLOOD_MINIMUM_STOP_PROCESS)) return null . = ..() - vessel.remove_reagent("blood",amount) // Removes blood if human + remove_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) @@ -288,8 +301,28 @@ var/const/CE_STABLE_THRESHOLD = 0.5 var/datum/reagent/blood/our = get_blood(vessel) - if (!injected || !our) + if (!injected) return + if(!our) + log_debug("[src] has no blood reagent, proceeding with fallback reinitialization.") + var/vessel_old = vessel + vessel = null + qdel(vessel_old) + make_blood(amount) + if(!vessel) + log_debug("Failed to re-initialize blood datums on [src]!") + return + if(vessel.total_volume < species.blood_volume) + vessel.add_reagent("blood", species.blood_volume - vessel.total_volume) + else if(vessel.total_volume > species.blood_volume) + vessel.maximum_volume = species.blood_volume + fixblood() + our = get_blood(vessel) + if(!our) + log_debug("Failed to re-initialize blood datums on [src]!") + 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() diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 0c85e2aa27..b22ee48e98 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -750,7 +750,7 @@ Note that amputating the affected organ does in fact remove the infection from t if(!(W.can_autoheal() || (bicardose && inaprovaline) || myeldose)) //bicaridine and inaprovaline stop internal wounds from growing bigger with time, unless it is so small that it is already healing W.open_wound(0.1 * wound_update_accuracy) - owner.vessel.remove_reagent("blood", wound_update_accuracy * W.damage/40) //line should possibly be moved to handle_blood, so all the bleeding stuff is in one place. + owner.remove_blood( wound_update_accuracy * W.damage/40) //line should possibly be moved to handle_blood, so all the bleeding stuff is in one place. if(prob(1 * wound_update_accuracy)) owner.custom_pain("You feel a stabbing pain in your [name]!", 50) diff --git a/code/modules/xenoarcheaology/effects/vampire.dm b/code/modules/xenoarcheaology/effects/vampire.dm index 29cabc5b2a..757f02889a 100644 --- a/code/modules/xenoarcheaology/effects/vampire.dm +++ b/code/modules/xenoarcheaology/effects/vampire.dm @@ -27,7 +27,7 @@ B.target_turf = pick(RANGE_TURFS(1, holder)) B.blood_DNA = list() B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type - M.vessel.remove_reagent("blood",rand(10,30)) + M.remove_blood(rand(10,30)) /datum/artifact_effect/vampire/DoEffectTouch(var/mob/user) bloodcall(user) diff --git a/code/modules/xenoarcheaology/finds/special.dm b/code/modules/xenoarcheaology/finds/special.dm index e7c66148d5..af22d90dbf 100644 --- a/code/modules/xenoarcheaology/finds/special.dm +++ b/code/modules/xenoarcheaology/finds/special.dm @@ -134,7 +134,7 @@ B.target_turf = pick(range(1, src)) B.blood_DNA = list() B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type - M.vessel.remove_reagent("blood",rand(25,50)) + M.remove_blood(rand(25,50)) //animated blood 2 SPOOKY /obj/effect/decal/cleanable/blood/splatter/animated