mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-28 18:21:51 +00:00
Silly little addition, does not affect gameplay at all. Liver, lungs, kidneys, heart, and eyes now have flavor text that shows up when you examine them.
227 lines
7.7 KiB
Plaintext
227 lines
7.7 KiB
Plaintext
/obj/item/organ/internal/heart
|
|
name = "heart"
|
|
desc = "When it's calling to you, you'd better listen."
|
|
icon_state = "heart-on"
|
|
organ_tag = BP_HEART
|
|
parent_organ = BP_CHEST
|
|
dead_icon = "heart-off"
|
|
robotic_name = "circulatory pump"
|
|
toxin_type = CE_CARDIOTOXIC
|
|
|
|
max_damage = 60
|
|
min_broken_damage = 45
|
|
relative_size = 5
|
|
damage_reduction = 0.7
|
|
|
|
var/pulse = PULSE_NORM //current pulse level
|
|
var/heartbeat = 0
|
|
var/next_blood_squirt = 0
|
|
var/list/external_pump
|
|
|
|
/obj/item/organ/internal/heart/process()
|
|
if(owner)
|
|
handle_pulse()
|
|
if(pulse)
|
|
if(pulse == PULSE_2FAST && prob(1))
|
|
take_internal_damage(0.5)
|
|
if(pulse == PULSE_THREADY && prob(5))
|
|
take_internal_damage(0.5)
|
|
handle_heartbeat()
|
|
handle_blood()
|
|
..()
|
|
|
|
/obj/item/organ/internal/heart/proc/handle_pulse()
|
|
if(owner.stat == DEAD || (species && species.flags & NO_BLOOD) || BP_IS_ROBOTIC(src)) //No heart, no pulse, buddy. Or if the heart is robotic. Or you're dead.
|
|
pulse = PULSE_NONE
|
|
return
|
|
|
|
// pulse mod starts out as just the chemical effect amount
|
|
var/pulse_mod = owner.chem_effects[CE_PULSE]
|
|
var/is_stable = owner.chem_effects[CE_STABLE]
|
|
|
|
// If you have enough heart chemicals to be over 2, you're likely to take extra damage.
|
|
if(pulse_mod > 2 && !is_stable)
|
|
var/damage_chance = (pulse_mod - 2) ** 2
|
|
if(prob(damage_chance))
|
|
take_internal_damage(0.5)
|
|
|
|
// Now pulse mod is impacted by shock stage and other things too
|
|
if(owner.shock_stage > 30)
|
|
pulse_mod++
|
|
if(owner.shock_stage > 80)
|
|
pulse_mod++
|
|
|
|
var/oxy = owner.get_blood_oxygenation()
|
|
if(oxy < BLOOD_VOLUME_OKAY) //brain wants us to get moar oxygen
|
|
pulse_mod++
|
|
if(oxy < BLOOD_VOLUME_BAD) //MOAR
|
|
pulse_mod++
|
|
|
|
if(owner.status_flags & FAKEDEATH)
|
|
pulse = clamp(PULSE_NONE + pulse_mod, PULSE_NONE, PULSE_2FAST) //pretend that we're dead. unlike actual death, can be inflienced by meds
|
|
return
|
|
|
|
//If heart is stopped, it isn't going to restart itself randomly.
|
|
if(pulse == PULSE_NONE)
|
|
return
|
|
else //and if it's beating, let's see if it should
|
|
var/should_stop = prob(80) && owner.get_blood_circulation() < BLOOD_VOLUME_SURVIVE //cardiovascular shock, not enough liquid to pump
|
|
should_stop = should_stop || prob(max(0, owner.getBrainLoss() - owner.maxHealth * 0.75)) //brain failing to work heart properly
|
|
should_stop = should_stop || (prob(5) && pulse == PULSE_THREADY) //erratic heart patterns, usually caused by oxyloss
|
|
should_stop = should_stop || owner.chem_effects[CE_NOPULSE]
|
|
if(should_stop) // The heart has stopped due to going into traumatic or cardiovascular shock.
|
|
to_chat(owner, SPAN_DANGER("Your heart has stopped!"))
|
|
pulse = PULSE_NONE
|
|
return
|
|
|
|
// Pulse normally shouldn't go above PULSE_2FAST
|
|
pulse = clamp(PULSE_NORM + pulse_mod, PULSE_SLOW, PULSE_2FAST)
|
|
|
|
// If fibrillation, then it can be PULSE_THREADY
|
|
var/fibrillation = oxy <= BLOOD_VOLUME_SURVIVE || (prob(30) && owner.shock_stage > 120)
|
|
if(pulse && fibrillation) //I SAID MOAR OXYGEN
|
|
pulse = PULSE_THREADY
|
|
|
|
// Stablising chemicals pull the heartbeat towards the center
|
|
if(pulse != PULSE_NORM && is_stable)
|
|
if(pulse > PULSE_NORM)
|
|
pulse--
|
|
else
|
|
pulse++
|
|
|
|
/obj/item/organ/internal/heart/proc/handle_heartbeat()
|
|
if(pulse >= PULSE_2FAST || owner.shock_stage >= 10)
|
|
//PULSE_THREADY - maximum value for pulse, currently it is 5.
|
|
//High pulse value corresponds to a fast rate of heartbeat.
|
|
//Divided by 2, otherwise it is too slow.
|
|
var/rate = (PULSE_THREADY - pulse)/2
|
|
switch(owner.chem_effects[CE_PULSE])
|
|
if(2 to INFINITY)
|
|
heartbeat++
|
|
if(-INFINITY to -2)
|
|
heartbeat--
|
|
|
|
if(heartbeat >= rate)
|
|
heartbeat = 0
|
|
sound_to(owner, sound('sound/effects/singlebeat.ogg', 0, 0, 0, 50))
|
|
else
|
|
heartbeat++
|
|
|
|
/obj/item/organ/internal/heart/proc/handle_blood()
|
|
if(!owner)
|
|
return
|
|
|
|
if(owner.species && owner.species.flags & NO_BLOOD)
|
|
return
|
|
|
|
if(!owner || owner.stat == DEAD || owner.bodytemperature < 170 || owner.InStasis()) //Dead or cryosleep people do not pump the blood.
|
|
return
|
|
|
|
if(pulse != PULSE_NONE || BP_IS_ROBOTIC(src))
|
|
var/blood_volume = round(REAGENT_VOLUME(owner.vessel, /singleton/reagent/blood))
|
|
|
|
//Blood regeneration if there is some space
|
|
if(blood_volume < species.blood_volume && blood_volume)
|
|
if(REAGENT_DATA(owner.vessel, /singleton/reagent/blood)) // Make sure there's blood at all
|
|
owner.vessel.add_reagent(/singleton/reagent/blood, BLOOD_REGEN_RATE + 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)
|
|
|
|
//Bleeding out
|
|
var/blood_max = 0
|
|
var/open_wound
|
|
var/list/do_spray = list()
|
|
for(var/obj/item/organ/external/temp in owner.bad_external_organs)
|
|
if((temp.status & ORGAN_BLEEDING) && !BP_IS_ROBOTIC(temp))
|
|
for(var/datum/wound/W in temp.wounds)
|
|
if(W.bleeding())
|
|
open_wound = TRUE
|
|
if(temp.applied_pressure)
|
|
if(ishuman(temp.applied_pressure))
|
|
var/mob/living/carbon/human/H = temp.applied_pressure
|
|
H.bloody_hands(src, 0)
|
|
var/min_eff_damage = max(0, W.damage - 10) / 6
|
|
blood_max += max(min_eff_damage, W.damage - 30) / 40
|
|
else
|
|
blood_max += ((W.damage / 40) * species.bleed_mod)
|
|
|
|
if(temp.status & ORGAN_ARTERY_CUT)
|
|
var/bleed_amount = FLOOR((owner.vessel.total_volume / (temp.applied_pressure || !open_wound ? 450 : 250)) * temp.arterial_bleed_severity, 0.1)
|
|
if(bleed_amount)
|
|
if((CE_BLOODCLOT in owner.chem_effects) && !(owner.chem_effects[CE_BLOODTHIN]))
|
|
bleed_amount *= 0.8 // won't do much, but it'll help
|
|
if(CE_BLOODTHIN in owner.chem_effects)
|
|
bleed_amount *= 1+(owner.chem_effects[CE_BLOODTHIN]/100)
|
|
if(open_wound)
|
|
blood_max += bleed_amount
|
|
do_spray += "[temp.name]"
|
|
else
|
|
owner.vessel.remove_reagent(/singleton/reagent/blood, bleed_amount)
|
|
|
|
switch(pulse)
|
|
if(PULSE_SLOW)
|
|
blood_max *= 0.8
|
|
if(PULSE_FAST)
|
|
blood_max *= 1.25
|
|
if(PULSE_2FAST, PULSE_THREADY)
|
|
blood_max *= 1.5
|
|
|
|
if(CE_BLOODCLOT in owner.chem_effects)
|
|
blood_max *= 0.7
|
|
else if(CE_STABLE in owner.chem_effects)
|
|
blood_max *= 0.8
|
|
|
|
if(world.time >= next_blood_squirt && istype(owner.loc, /turf) && do_spray.len)
|
|
owner.visible_message(SPAN_DANGER("Blood squirts from \the [owner]'s [pick(do_spray)]!"), \
|
|
SPAN_DANGER("<font size=3>Blood sprays out of your [pick(do_spray)]!</font>"))
|
|
owner.eye_blurry = 2
|
|
owner.Stun(1)
|
|
next_blood_squirt = world.time + 100
|
|
var/turf/sprayloc = get_turf(owner)
|
|
blood_max -= owner.drip(Ceiling(blood_max/3), sprayloc)
|
|
if(blood_max > 0)
|
|
blood_max -= owner.blood_squirt(blood_max, sprayloc)
|
|
if(blood_max > 0)
|
|
owner.drip(blood_max, get_turf(owner))
|
|
else
|
|
owner.drip(blood_max)
|
|
|
|
/obj/item/organ/internal/heart/proc/is_working()
|
|
if(!is_usable())
|
|
return FALSE
|
|
|
|
return pulse > PULSE_NONE || BP_IS_ROBOTIC(src) || (owner.status_flags & FAKEDEATH)
|
|
|
|
/obj/item/organ/internal/heart/do_surge_effects()
|
|
var/obj/item/organ/external/E = owner.organs_by_name[parent_organ]
|
|
if(prob(surge_damage))
|
|
owner.custom_pain(SPAN_DANGER("Your [E.name] stings horribly!"), 15, FALSE, E)
|
|
sound_to(owner, sound('sound/effects/singlebeat.ogg', 0, 0, 0, 100))
|
|
|
|
/obj/item/organ/internal/heart/listen()
|
|
if(BP_IS_ROBOTIC(src) && is_working())
|
|
if(is_bruised())
|
|
return "sputtering pump"
|
|
else
|
|
return "steady whirr of the pump"
|
|
|
|
if(!pulse || (owner.status_flags & FAKEDEATH))
|
|
return "no pulse"
|
|
|
|
var/pulsesound = "normal"
|
|
if(is_bruised())
|
|
pulsesound = "irregular"
|
|
|
|
switch(pulse)
|
|
if(PULSE_SLOW)
|
|
pulsesound = "slow"
|
|
if(PULSE_FAST)
|
|
pulsesound = "fast"
|
|
if(PULSE_2FAST)
|
|
pulsesound = "very fast"
|
|
if(PULSE_THREADY)
|
|
pulsesound = "extremely fast and faint"
|
|
|
|
. = "[pulsesound] pulse"
|