Partially grown clones are horribly disfigured + cardiac arrest refactor (#24106)

add: Refactors heart attack code, a cardiac arrest will knock someone unconscious and kill them very quickly.
add: Adds corazone, an anti-heart attack drug, made by mixing 2 parts Phenol, 1 part Lithium. A person with corazone in their system will not suffer any negative effects from missing a heart. Use it during surgery.
add: Abductor glands are now hearts, the abductor operation table now automatically injects corazone to prevent deaths during surgery. The gland will restart if it stops beating.
fix: Cloning pods always know the name of the person they are cloning.
add: You can swipe a medical ID card to eject someone from the cloning pod early. The cloning pod will announce this over the radio.
del: Fresh clones have no organs or limbs, they gain them during the cloning process. Ejecting a clone too early is not recommended. Power loss will also eject a clone as before.
del: An ejected clone will take damage from being at critical health very quickly upon ejection, rather than before, where a clone could be stable in critical for up to two minutes.
add: Occupants of cloning pods do not interact with the air outside the pod.


After @Cyberboss 's multi-pod cloning got merged, I scrapped the multi-pod stuff from my own work, and brought back the maiming.

Early ejected clones being partially disfigured is a cool feature.

This penalises (but does not completely remove) speed cloning, as there is a window where the clone can be ejected without missing any limbs or organs. Otherwise the clones will probably die due to lack of lungs or heart.

Heart attacks are more lethal, there's an easy medicine for treating them, if chemistry have it on hand.

Clones not reacting to the air around them is a buff to plasmamen (although they'll still burn to death once they're ejected in an oxygen atmosphere).
This commit is contained in:
coiax
2017-02-21 11:13:54 +13:00
committed by oranges
parent 62da82fcd9
commit de0b29dea6
22 changed files with 392 additions and 274 deletions
+2
View File
@@ -128,6 +128,8 @@ var/list/static/global/pointed_types = typecacheof(list(
#define is_pointed(W) (is_type_in_typecache(W, pointed_types))
#define isbodypart(A) (istype(A, /obj/item/bodypart))
//Assemblies
#define isassembly(O) (istype(O, /obj/item/device/assembly))
@@ -435,7 +435,7 @@ Congratulations! You are now trained for xenobiology research!"}
species = "<span clas=='notice'>[H.dna.species.name]</span>"
if(L.mind && L.mind.changeling)
species = "<span class='warning'>Changeling lifeform</span>"
var/obj/item/organ/gland/temp = locate() in H.internal_organs
var/obj/item/organ/heart/gland/temp = locate() in H.internal_organs
if(temp)
helptext = "<span class='warning'>Experimental gland detected!</span>"
else
@@ -531,15 +531,6 @@ Congratulations! You are now trained for xenobiology research!"}
// Operating Table / Beds / Lockers
/obj/structure/table/optable/abductor
icon = 'icons/obj/abductor.dmi'
icon_state = "bed"
can_buckle = 1
buckle_lying = 1
flags = NODECONSTRUCT
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/structure/bed/abductor
name = "resting contraption"
desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
@@ -576,6 +567,17 @@ Congratulations! You are now trained for xenobiology research!"}
new /obj/structure/table/abductor(src.loc)
qdel(src)
return
if(istype(I, /obj/item/stack/sheet/mineral/silver))
var/obj/item/stack/sheet/P = I
if(P.get_amount() < 1)
user << "<span class='warning'>You need one sheet of silver to do \
this!</span>"
return
user << "<span class='notice'>You start adding [P] to [src]...</span>"
if(do_after(user, 50, target = src))
P.use(1)
new /obj/structure/table/optable/abductor(src.loc)
qdel(src)
/obj/structure/table/abductor
name = "alien table"
@@ -589,6 +591,38 @@ Congratulations! You are now trained for xenobiology research!"}
canSmoothWith = null
frame = /obj/structure/table_frame/abductor
/obj/structure/table/optable/abductor
name = "alien operating table"
desc = "Used for alien medical procedures. The surface is covered in tiny spines."
frame = /obj/structure/table_frame/abductor
buildstack = /obj/item/stack/sheet/mineral/silver
framestack = /obj/item/stack/sheet/mineral/abductor
buildstackamount = 1
framestackamount = 1
icon = 'icons/obj/abductor.dmi'
icon_state = "bed"
can_buckle = 1
buckle_lying = 1
var/static/list/injected_reagents = list("corazone")
/obj/structure/table/optable/abductor/Crossed(atom/movable/AM)
. = ..()
if(iscarbon(AM))
START_PROCESSING(SSobj, src)
AM << "<span class='danger'>You feel a series of tiny pricks!</span>"
/obj/structure/table/optable/abductor/process()
. = PROCESS_KILL
for(var/mob/living/carbon/C in get_turf(src))
. = TRUE
for(var/chemical in injected_reagents)
if(C.reagents.get_reagent_amount(chemical) < 1)
C.reagents.add_reagent(chemical, 1)
/obj/structure/table/optable/abductor/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/structure/closet/abductor
name = "alien locker"
@@ -33,15 +33,15 @@
if(IC)
user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "<span class='notice'>You pull [IC] out of [target]'s [target_zone].</span>")
user.put_in_hands(IC)
IC.Remove(target, special = 1)
IC.Remove(target)
return 1
else
user << "<span class='warning'>You don't find anything in [target]'s [target_zone]!</span>"
return 0
return 1
/datum/surgery_step/gland_insert
name = "insert gland"
implements = list(/obj/item/organ/gland = 100)
implements = list(/obj/item/organ/heart/gland = 100)
time = 32
/datum/surgery_step/gland_insert/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -50,6 +50,6 @@
/datum/surgery_step/gland_insert/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] inserts [tool] into [target].", "<span class ='notice'>You insert [tool] into [target].</span>")
user.drop_item()
var/obj/item/organ/gland/gland = tool
var/obj/item/organ/heart/gland/gland = tool
gland.Insert(target, 2)
return 1
return 1
@@ -1,12 +1,11 @@
/obj/item/organ/gland
/obj/item/organ/heart/gland
name = "fleshy mass"
desc = "A nausea-inducing hunk of twisting flesh and metal."
icon = 'icons/obj/abductor.dmi'
zone = "chest"
slot = "gland"
icon_state = "gland"
status = ORGAN_ROBOTIC
origin_tech = "materials=4;biotech=7;abductor=3"
beating = TRUE
var/cooldown_low = 300
var/cooldown_high = 300
var/next_activation = 0
@@ -14,30 +13,33 @@
var/human_only = 0
var/active = 0
/obj/item/organ/gland/proc/ownerCheck()
/obj/item/organ/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return 1
if(!human_only && iscarbon(owner))
return 1
return 0
/obj/item/organ/gland/proc/Start()
/obj/item/organ/heart/gland/proc/Start()
active = 1
next_activation = world.time + rand(cooldown_low,cooldown_high)
/obj/item/organ/gland/Remove(var/mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/Remove(var/mob/living/carbon/M, special = 0)
active = 0
if(initial(uses) == 1)
uses = initial(uses)
..()
/obj/item/organ/gland/Insert(var/mob/living/carbon/M, special = 0)
/obj/item/organ/heart/gland/Insert(var/mob/living/carbon/M, special = 0)
..()
if(special != 2 && uses) // Special 2 means abductor surgery
Start()
/obj/item/organ/gland/on_life()
/obj/item/organ/heart/gland/on_life()
if(!beating)
// alien glands are immune to stopping.
beating = TRUE
if(!active)
return
if(!ownerCheck())
@@ -50,28 +52,28 @@
if(!uses)
active = 0
/obj/item/organ/gland/proc/activate()
/obj/item/organ/heart/gland/proc/activate()
return
/obj/item/organ/gland/heals
/obj/item/organ/heart/gland/heals
cooldown_low = 200
cooldown_high = 400
uses = -1
icon_state = "health"
/obj/item/organ/gland/heals/activate()
/obj/item/organ/heart/gland/heals/activate()
owner << "<span class='notice'>You feel curiously revitalized.</span>"
owner.adjustBruteLoss(-20)
owner.adjustOxyLoss(-20)
owner.adjustFireLoss(-20)
/obj/item/organ/gland/slime
/obj/item/organ/heart/gland/slime
cooldown_low = 600
cooldown_high = 1200
uses = -1
icon_state = "slime"
/obj/item/organ/gland/slime/activate()
/obj/item/organ/heart/gland/slime/activate()
owner << "<span class='warning'>You feel nauseous!</span>"
owner.vomit(20)
@@ -80,14 +82,14 @@
Slime.Friends = list(owner)
Slime.Leader = owner
/obj/item/organ/gland/mindshock
/obj/item/organ/heart/gland/mindshock
origin_tech = "materials=4;biotech=4;magnets=6;abductor=3"
cooldown_low = 300
cooldown_high = 300
uses = -1
icon_state = "mindshock"
/obj/item/organ/gland/mindshock/activate()
/obj/item/organ/heart/gland/mindshock/activate()
owner << "<span class='notice'>You get a headache.</span>"
var/turf/T = get_turf(owner)
@@ -97,38 +99,37 @@
H << "<span class='alien'>You hear a buzz in your head.</span>"
H.confused += 20
/obj/item/organ/gland/pop
/obj/item/organ/heart/gland/pop
cooldown_low = 900
cooldown_high = 1800
uses = -1
human_only = 1
icon_state = "species"
/obj/item/organ/gland/pop/activate()
/obj/item/organ/heart/gland/pop/activate()
owner << "<span class='notice'>You feel unlike yourself.</span>"
var/species = pick(list(/datum/species/lizard,/datum/species/jelly/slime,/datum/species/pod,/datum/species/fly,/datum/species/jelly))
owner.set_species(species)
/obj/item/organ/gland/ventcrawling
/obj/item/organ/heart/gland/ventcrawling
origin_tech = "materials=4;biotech=5;bluespace=4;abductor=3"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
icon_state = "vent"
/obj/item/organ/gland/ventcrawling/activate()
/obj/item/organ/heart/gland/ventcrawling/activate()
owner << "<span class='notice'>You feel very stretchy.</span>"
owner.ventcrawler = VENTCRAWLER_ALWAYS
return
/obj/item/organ/gland/viral
/obj/item/organ/heart/gland/viral
cooldown_low = 1800
cooldown_high = 2400
uses = 1
icon_state = "viral"
/obj/item/organ/gland/viral/activate()
/obj/item/organ/heart/gland/viral/activate()
owner << "<span class='warning'>You feel sick.</span>"
var/virus_type = pick(/datum/disease/beesease, /datum/disease/brainrot, /datum/disease/magnitis)
var/datum/disease/D = new virus_type()
@@ -139,48 +140,47 @@
owner.med_hud_set_status()
/obj/item/organ/gland/emp //TODO : Replace with something more interesting
/obj/item/organ/heart/gland/emp //TODO : Replace with something more interesting
origin_tech = "materials=4;biotech=4;magnets=6;abductor=3"
cooldown_low = 900
cooldown_high = 1600
uses = 10
icon_state = "emp"
/obj/item/organ/gland/emp/activate()
/obj/item/organ/heart/gland/emp/activate()
owner << "<span class='warning'>You feel a spike of pain in your head.</span>"
empulse(get_turf(owner), 2, 5, 1)
/obj/item/organ/gland/spiderman
/obj/item/organ/heart/gland/spiderman
cooldown_low = 450
cooldown_high = 900
uses = 10
icon_state = "spider"
/obj/item/organ/gland/spiderman/activate()
/obj/item/organ/heart/gland/spiderman/activate()
owner << "<span class='warning'>You feel something crawling in your skin.</span>"
owner.faction |= "spiders"
new /obj/structure/spider/spiderling(owner.loc)
/obj/item/organ/gland/egg
/obj/item/organ/heart/gland/egg
cooldown_low = 300
cooldown_high = 400
uses = -1
icon_state = "egg"
/obj/item/organ/gland/egg/activate()
/obj/item/organ/heart/gland/egg/activate()
owner << "<span class='boldannounce'>You lay an egg!</span>"
var/obj/item/weapon/reagent_containers/food/snacks/egg/egg = new(owner.loc)
egg.reagents.add_reagent("sacid",20)
egg.desc += " It smells bad."
/obj/item/organ/gland/bloody
/obj/item/organ/heart/gland/bloody
cooldown_low = 200
cooldown_high = 400
uses = -1
/obj/item/organ/gland/bloody/activate()
owner.adjustBruteLoss(15)
/obj/item/organ/heart/gland/bloody/activate()
owner.blood_volume -= 20
owner.visible_message("<span class='danger'>[owner]'s skin erupts with blood!</span>",\
"<span class='userdanger'>Blood pours from your skin!</span>")
@@ -189,13 +189,13 @@
for(var/mob/living/carbon/human/H in oview(3,owner)) //Blood decals for simple animals would be neat. aka Carp with blood on it.
H.add_mob_blood(owner)
/obj/item/organ/gland/bodysnatch
/obj/item/organ/heart/gland/bodysnatch
cooldown_low = 600
cooldown_high = 600
human_only = 1
uses = 1
/obj/item/organ/gland/bodysnatch/activate()
/obj/item/organ/heart/gland/bodysnatch/activate()
owner << "<span class='warning'>You feel something moving around inside you...</span>"
//spawn cocoon with clone greytide snpc inside
if(ishuman(owner))
@@ -203,7 +203,6 @@
C.Copy(owner)
C.Start()
owner.gib()
return
/obj/structure/spider/cocoon/abductor
name = "slimy cocoon"
@@ -240,13 +239,13 @@
M.loc = src.loc
qdel(src)
/obj/item/organ/gland/plasma
/obj/item/organ/heart/gland/plasma
cooldown_low = 1200
cooldown_high = 1800
origin_tech = "materials=4;biotech=4;plasmatech=6;abductor=3"
uses = -1
/obj/item/organ/gland/plasma/activate()
/obj/item/organ/heart/gland/plasma/activate()
owner << "<span class='warning'>You feel bloated.</span>"
sleep(150)
if(!owner) return
@@ -258,4 +257,3 @@
if(istype(T))
T.atmos_spawn_air("plasma=50;TEMP=[T20C]")
owner.vomit()
return
@@ -15,7 +15,7 @@
/obj/machinery/abductor/gland_dispenser/New()
..()
gland_types = subtypesof(/obj/item/organ/gland)
gland_types = subtypesof(/obj/item/organ/heart/gland)
gland_types = shuffle(gland_types)
gland_colors = new/list(gland_types.len)
amounts = new/list(gland_types.len)
@@ -60,7 +60,7 @@
return
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/organ/gland))
if(istype(W, /obj/item/organ/heart/gland))
if(!user.drop_item())
return
W.loc = src
@@ -160,7 +160,7 @@
if(H.stat == DEAD)
say("Specimen deceased - please provide fresh sample.")
return "<span class='bad'>Specimen deceased.</span>"
var/obj/item/organ/gland/GlandTest = locate() in H.internal_organs
var/obj/item/organ/heart/gland/GlandTest = locate() in H.internal_organs
if(!GlandTest)
say("Experimental dissection not detected!")
return "<span class='bad'>No glands detected!</span>"
@@ -185,7 +185,7 @@
H.mind.announce_objectives()
ticker.mode.update_abductor_icons_added(H.mind)
for(var/obj/item/organ/gland/G in H.internal_organs)
for(var/obj/item/organ/heart/gland/G in H.internal_organs)
G.Start()
point_reward++
if(point_reward > 0)
+91 -64
View File
@@ -4,6 +4,7 @@
//Potential replacement for genetics revives or something I dunno (?)
#define CLONE_INITIAL_DAMAGE 190 //Clones in clonepods start with 190 cloneloss damage and 190 brainloss damage, thats just logical
#define MINIMUM_HEAL_LEVEL 40
#define SPEAK(message) radio.talk_into(src, message, radio_channel, get_spans())
@@ -16,12 +17,10 @@
icon_state = "pod_0"
req_access = list(access_cloning) //For premature unlocking.
verb_say = "states"
var/heal_level = 90 //The clone is released once its health reaches this level.
var/locked = FALSE
var/heal_level //The clone is released once its health reaches this level.
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
var/mess = FALSE //Need to clean out it if it's full of exploded clone.
var/attempting = FALSE //One clone attempt at a time thanks
var/eject_wait = FALSE //Don't eject them as soon as they are created fuckkk
var/speed_coeff
var/efficiency
@@ -34,6 +33,13 @@
var/obj/effect/countdown/clonepod/countdown
var/list/unattached_flesh
var/flesh_number = 0
// The "brine" is the reagents that are automatically added in small
// amounts to the occupant.
var/static/list/brine_types = list("salbutamol", "bicaridine", "corazone")
/obj/machinery/clonepod/New()
..()
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/clonepod(null)
@@ -55,6 +61,10 @@
countdown = null
if(connected)
connected.DetachCloner(src)
for(var/i in unattached_flesh)
qdel(i)
LAZYCLEARLIST(unattached_flesh)
unattached_flesh = null
. = ..()
/obj/machinery/clonepod/RefreshParts()
@@ -65,6 +75,8 @@
for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts)
speed_coeff += P.rating
heal_level = (efficiency * 15) + 10
if(heal_level < MINIMUM_HEAL_LEVEL)
heal_level = MINIMUM_HEAL_LEVEL
if(heal_level > 100)
heal_level = 100
@@ -137,18 +149,14 @@
return FALSE
if(clonemind.damnation_type) //Can't clone the damned.
INVOKE_ASYNC(src, .proc/horrifyingsound)
mess = 1
mess = TRUE
icon_state = "pod_g"
update_icon()
return FALSE
attempting = TRUE //One at a time!!
locked = TRUE
countdown.start()
eject_wait = TRUE
addtimer(CALLBACK(src, .proc/wait_complete), 30)
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
@@ -172,8 +180,8 @@
icon_state = "pod_1"
//Get the clone body ready
H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
H.setBrainLoss(CLONE_INITIAL_DAMAGE)
maim_clone(H)
check_brine() // put in chemicals NOW to stop death via cardiac arrest
H.Paralyse(4)
if(grab_ghost_when == CLONER_FRESH_CLONE)
@@ -196,24 +204,19 @@
attempting = FALSE
return TRUE
/obj/machinery/clonepod/proc/wait_complete()
eject_wait = FALSE
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
if(!is_operational()) //Autoeject if power is lost
if (occupant)
locked = FALSE
go_out()
connected_message("Clone Ejected: Loss of power.")
else if((occupant) && (occupant.loc == src))
if((occupant.stat == DEAD) || (occupant.suiciding) || occupant.hellbound) //Autoeject corpses and suiciding dudes.
connected_message("Clone Rejected: Deceased.")
SPEAK("The cloning of <b>[occupant.real_name]</b> has been \
SPEAK("The cloning of [occupant.real_name] has been \
aborted due to unrecoverable tissue failure.")
locked = FALSE
go_out()
else if(occupant.cloneloss > (100 - heal_level))
@@ -221,37 +224,43 @@
//Slowly get that clone healed and finished.
occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier))
var/progress = CLONE_INITIAL_DAMAGE - occupant.getCloneLoss()
// To avoid the default cloner making incomplete clones
progress += (100 - MINIMUM_HEAL_LEVEL)
var/milestone = CLONE_INITIAL_DAMAGE / flesh_number
var/installed = flesh_number - unattached_flesh.len
if((progress / milestone) >= installed)
// attach some flesh
var/obj/item/I = pick_n_take(unattached_flesh)
if(isorgan(I))
var/obj/item/organ/O = I
O.Insert(occupant)
else if(isbodypart(I))
var/obj/item/bodypart/BP = I
BP.attach_limb(occupant)
//Premature clones may have brain damage.
occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier))
//So clones don't die of oxyloss in a running pod.
if (occupant.reagents.get_reagent_amount("salbutamol") < 30)
occupant.reagents.add_reagent("salbutamol", 60)
// NOBREATH species will take brute damage in crit instead
// so heal that as well
if(occupant.reagents.get_reagent_amount("bicaridine") < 5)
occupant.reagents.add_reagent("bicaridine", 10)
check_brine()
use_power(7500) //This might need tweaking.
else if((occupant.cloneloss <= (100 - heal_level)) && (!eject_wait))
else if((occupant.cloneloss <= (100 - heal_level)))
connected_message("Cloning Process Complete.")
SPEAK("The cloning cycle of <b>[occupant]</b> is complete.")
locked = FALSE
SPEAK("The cloning cycle of [occupant.real_name] is complete.")
go_out()
else if ((!occupant) || (occupant.loc != src))
occupant = null
if (locked)
locked = FALSE
if (!mess && !panel_open)
icon_state = "pod_0"
use_power(200)
//Let's unlock this early I guess. Might be too early, needs tweaking.
/obj/machinery/clonepod/attackby(obj/item/weapon/W, mob/user, params)
if(!(occupant || mess || locked))
if(!(occupant || mess))
if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]",W))
return
@@ -263,7 +272,7 @@
if(istype(W,/obj/item/device/multitool))
var/obj/item/device/multitool/P = W
if(istype(P.buffer, /obj/machinery/computer/cloning))
if(get_area(P.buffer) != get_area(src))
user << "<font color = #666633>-% Cannot link machines across power zones. Buffer cleared %-</font color>"
@@ -278,28 +287,27 @@
P.buffer = src
user << "<font color = #666633>-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-</font color>"
return
if (W.GetID())
if (!check_access(W))
if(W.GetID())
if(!check_access(W))
user << "<span class='danger'>Access Denied.</span>"
return
if (!locked || !occupant)
return
if (occupant.health < -20 && occupant.stat != DEAD)
user << "<span class='danger'>Access Refused. Patient status still unstable.</span>"
if(!(occupant || mess))
user << "<span class='danger'>Error: Pod has no occupant.</span>"
return
else
locked = FALSE
user << "System unlocked."
connected_message("Authorized Ejection")
SPEAK("An authorized ejection of [occupant.real_name] has occurred.")
user << "<span class='notice'>You force an emergency ejection. </span>"
go_out()
else
return ..()
/obj/machinery/clonepod/emag_act(mob/user)
if (isnull(occupant))
if(!occupant)
return
user << "<span class='notice'>You force an emergency ejection.</span>"
locked = FALSE
go_out()
user << "<span class='warning'>You corrupt the genetic compiler.</span>"
malfunction()
//Put messages in the connected computer's temp var for display.
/obj/machinery/clonepod/proc/connected_message(message)
@@ -312,31 +320,17 @@
connected.updateUsrDialog()
return TRUE
/obj/machinery/clonepod/verb/eject()
set name = "Eject Cloner"
set category = "Object"
set src in oview(1)
if(!usr)
return
if(usr.stat || !usr.canmove || usr.restrained())
return
go_out()
add_fingerprint(usr)
/obj/machinery/clonepod/proc/go_out()
if (locked)
return
countdown.stop()
if (mess) //Clean that mess and dump those gibs!
if(mess) //Clean that mess and dump those gibs!
mess = FALSE
new /obj/effect/gibspawner/generic(loc)
audible_message("<span class='italics'>You hear a splat.</span>")
icon_state = "pod_0"
return
if (!occupant)
if(!occupant)
return
if(grab_ghost_when == CLONER_MATURE_CLONE)
@@ -349,7 +343,6 @@
var/turf/T = get_turf(src)
occupant.forceMove(T)
icon_state = "pod_0"
eject_wait = FALSE //If it's still set somehow.
occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest.
occupant = null
@@ -383,14 +376,12 @@
/obj/machinery/clonepod/ex_act(severity, target)
..()
if(!QDELETED(src))
locked = FALSE
go_out()
/obj/machinery/clonepod/handle_atom_del(atom/A)
if(A == occupant)
occupant = null
locked = FALSE
go_out()
countdown.stop()
/obj/machinery/clonepod/proc/horrifyingsound()
for(var/i in 1 to 5)
@@ -401,10 +392,45 @@
/obj/machinery/clonepod/deconstruct(disassembled = TRUE)
if(occupant)
locked = FALSE
go_out()
..()
/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H)
if(!unattached_flesh)
unattached_flesh = list()
else
for(var/fl in unattached_flesh)
qdel(fl)
unattached_flesh.Cut()
H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health
H.setBrainLoss(CLONE_INITIAL_DAMAGE)
// In addition to being cellularly damaged and having barely any
// brain function, they also have no limbs or internal organs.
var/static/list/zones = list("r_arm", "l_arm", "r_leg", "l_leg")
for(var/zone in zones)
var/obj/item/bodypart/BP = H.get_bodypart(zone)
BP.drop_limb()
BP.forceMove(src)
unattached_flesh += BP
for(var/o in H.internal_organs)
var/obj/item/organ/organ = o
if(!istype(organ) || organ.vital)
continue
organ.Remove(H, special=TRUE)
organ.forceMove(src)
unattached_flesh += organ
flesh_number = unattached_flesh.len
/obj/machinery/clonepod/proc/check_brine()
// Clones are in a pickled bath of mild chemicals, keeping
// them alive, despite their lack of internal organs
for(var/bt in brine_types)
if(occupant.reagents.get_reagent_amount(bt) < 1)
occupant.reagents.add_reagent(bt, 1)
/*
* Diskette Box
@@ -449,3 +475,4 @@
#undef CLONE_INITIAL_DAMAGE
#undef SPEAK
#undef MINIMUM_HEAL_LEVEL
@@ -169,3 +169,20 @@
/obj/structure/closet/crate/secure/loot = 20,
"" = 80
)
/obj/effect/spawner/lootdrop/organ_spawner
name = "organ spawner"
loot = list(
/obj/item/organ/heart/gland/bloody = 7,
/obj/item/organ/heart/gland/bodysnatch = 4,
/obj/item/organ/heart/gland/egg = 7,
/obj/item/organ/heart/gland/emp = 3,
/obj/item/organ/heart/gland/mindshock = 5,
/obj/item/organ/heart/gland/plasma = 7,
/obj/item/organ/heart/gland/pop = 5,
/obj/item/organ/heart/gland/slime = 4,
/obj/item/organ/heart/gland/spiderman = 5,
/obj/item/organ/heart/gland/ventcrawling = 1,
/obj/item/organ/body_egg/alien_embryo = 1,
/obj/item/organ/hivelord_core = 2)
lootcount = 3
+1 -1
View File
@@ -125,7 +125,7 @@ MASS SPECTROMETER
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.heart_attack && H.stat != DEAD)
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
user << "<span class='danger'>Subject suffering from heart attack: Apply defibrillator immediately!</span>"
if(iscarbon(M))
+112 -97
View File
@@ -1,4 +1,6 @@
//backpack item
#define HALFWAYCRITDEATH ((HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) * 0.5)
/obj/item/weapon/defibrillator
name = "defibrillator"
desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
@@ -240,7 +242,6 @@
paddles = make_paddles()
bcell = new(src)
update_icon()
return
/obj/item/weapon/defibrillator/compact/combat
name = "combat defibrillator"
@@ -253,7 +254,6 @@
paddles = make_paddles()
bcell = new /obj/item/weapon/stock_parts/cell/infinite(src)
update_icon()
return
/obj/item/weapon/defibrillator/compact/combat/loaded/attackby(obj/item/weapon/W, mob/user, params)
if(W == paddles)
@@ -339,7 +339,6 @@
return 1
/obj/item/weapon/twohanded/shockpaddles/attack(mob/M, mob/user)
var/halfwaycritdeath = (HEALTH_THRESHOLD_CRIT + HEALTH_THRESHOLD_DEAD) / 2
if(busy)
return
@@ -359,6 +358,11 @@
else
user << "<span class='warning'>[src] are recharging!</span>"
return
if(user.a_intent == INTENT_DISARM)
do_disarm(M, user)
return
if(!ishuman(M))
if(req_defib)
user << "<span class='warning'>The instructions on [defib] don't mention how to revive that...</span>"
@@ -367,101 +371,109 @@
return
var/mob/living/carbon/human/H = M
if(user.a_intent == INTENT_DISARM)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
busy = 1
H.visible_message("<span class='danger'>[user] has touched [H.name] with [src]!</span>", \
"<span class='userdanger'>[user] has touched [H.name] with [src]!</span>")
H.adjustStaminaLoss(50)
H.Weaken(5)
H.updatehealth() //forces health update before next life tick
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
H.emote("gasp")
add_logs(user, M, "stunned", src)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(req_defib)
defib.cooldowncheck(user)
else
recharge(60)
return
if(user.zone_selected != "chest")
user << "<span class='warning'>You need to target your patient's \
chest with [src]!</span>"
return
if(user.a_intent == INTENT_HARM)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
user.visible_message("<span class='warning'>[user] begins to place [src] on [M.name]'s chest.</span>",
"<span class='warning'>You overcharge the paddles and begin to place them onto [M]'s chest...</span>")
busy = 1
update_icon()
if(do_after(user, 30, target = M))
user.visible_message("<span class='notice'>[user] places [src] on [M.name]'s chest.</span>",
"<span class='warning'>You place [src] on [M.name]'s chest and begin to charge them.</span>")
var/turf/T = get_turf(defib)
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
if(req_defib)
T.audible_message("<span class='warning'>\The [defib] lets out an urgent beep and lets out a steadily rising hum...</span>")
else
user.audible_message("<span class='warning'>[src] let out an urgent beep.</span>")
if(do_after(user, 30, target = M)) //Takes longer due to overcharging
if(!M)
busy = 0
update_icon()
return
if(M && M.stat == DEAD)
user << "<span class='warning'>[M] is dead.</span>"
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
busy = 0
update_icon()
return
user.visible_message("<span class='boldannounce'><i>[user] shocks [M] with \the [src]!</span>", "<span class='warning'>You shock [M] with \the [src]!</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1)
playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
var/mob/living/carbon/human/HU = M
M.emote("scream")
if(!HU.heart_attack)
HU.heart_attack = 1
if(!HU.stat)
HU.visible_message("<span class='warning'>[M] thrashes wildly, clutching at their chest!</span>",
"<span class='userdanger'>You feel a horrible agony in your chest!</span>")
HU.apply_damage(50, BURN, "chest")
add_logs(user, M, "overloaded the heart of", defib)
M.Weaken(5)
M.Jitter(100)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(!req_defib)
recharge(60)
if(req_defib && (defib.cooldowncheck(user)))
return
busy = 0
update_icon()
do_harm(H, user)
return
if((!req_defib && grab_ghost) || (req_defib && defib.grab_ghost))
H.notify_ghost_cloning("Your heart is being defibrillated!")
H.grab_ghost() // Shove them back in their body.
else if(!H.suiciding && !(H.disabilities & NOCLONE)&& !H.hellbound)
H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src)
user.visible_message("<span class='warning'>[user] begins to place [src] on [M.name]'s chest.</span>", "<span class='warning'>You begin to place [src] on [M.name]'s chest...</span>")
do_help(H, user)
/obj/item/weapon/twohanded/shockpaddles/proc/do_disarm(mob/living/M, mob/living/user)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
busy = 1
M.visible_message("<span class='danger'>[user] has touched [M] with [src]!</span>", \
"<span class='userdanger'>[user] has touched [M] with [src]!</span>")
M.adjustStaminaLoss(50)
M.Weaken(5)
M.updatehealth() //forces health update before next life tick
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
M.emote("gasp")
add_logs(user, M, "stunned", src)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(req_defib)
defib.cooldowncheck(user)
else
recharge(60)
/obj/item/weapon/twohanded/shockpaddles/proc/do_harm(mob/living/carbon/human/H, mob/living/user)
if(req_defib && defib.safety)
return
if(!req_defib && !combat)
return
user.visible_message("<span class='warning'>[user] begins to place [src] on [H]'s chest.</span>",
"<span class='warning'>You overcharge the paddles and begin to place them onto [H]'s chest...</span>")
busy = 1
update_icon()
if(do_after(user, 30, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("<span class='notice'>[user] places [src] on [M.name]'s chest.</span>", "<span class='warning'>You place [src] on [M.name]'s chest.</span>")
if(do_after(user, 30, target = H))
user.visible_message("<span class='notice'>[user] places [src] on [H]'s chest.</span>",
"<span class='warning'>You place [src] on [H]'s chest and begin to charge them.</span>")
var/turf/T = get_turf(defib)
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
if(req_defib)
T.audible_message("<span class='warning'>\The [defib] lets out an urgent beep and lets out a steadily rising hum...</span>")
else
user.audible_message("<span class='warning'>[src] let out an urgent beep.</span>")
if(do_after(user, 30, target = H)) //Takes longer due to overcharging
if(!H)
busy = 0
update_icon()
return
if(H && H.stat == DEAD)
user << "<span class='warning'>[H] is dead.</span>"
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
busy = 0
update_icon()
return
user.visible_message("<span class='boldannounce'><i>[user] shocks [H] with \the [src]!</span>", "<span class='warning'>You shock [H] with \the [src]!</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1)
playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1)
H.emote("scream")
if(H.can_heartattack() && !H.undergoing_cardiac_arrest())
if(!H.stat)
H.visible_message("<span class='warning'>[H] thrashes wildly, clutching at their chest!</span>",
"<span class='userdanger'>You feel a horrible agony in your chest!</span>")
H.set_heartattack(TRUE)
H.apply_damage(50, BURN, "chest")
add_logs(user, H, "overloaded the heart of", defib)
H.Weaken(5)
H.Jitter(100)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
busy = 0
update_icon()
if(!req_defib)
recharge(60)
if(req_defib && (defib.cooldowncheck(user)))
return
busy = 0
update_icon()
/obj/item/weapon/twohanded/shockpaddles/proc/do_help(mob/living/carbon/human/H, mob/living/user)
user.visible_message("<span class='warning'>[user] begins to place [src] on [H]'s chest.</span>", "<span class='warning'>You begin to place [src] on [H]'s chest...</span>")
busy = 1
update_icon()
if(do_after(user, 30, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("<span class='notice'>[user] places [src] on [H]'s chest.</span>", "<span class='warning'>You place [src] on [H]'s chest.</span>")
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
var/tplus = world.time - H.timeofdeath
// past this much time the patient is unrecoverable
@@ -472,7 +484,7 @@
var/tloss = DEFIB_TIME_LOSS * 10
var/total_burn = 0
var/total_brute = 0
if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
if(do_after(user, 20, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
for(var/obj/item/carried_item in H.contents)
if(istype(carried_item, /obj/item/clothing/suit/space))
if((!src.combat && !req_defib) || (req_defib && !defib.combat))
@@ -482,7 +494,7 @@
update_icon()
return
if(H.stat == DEAD)
M.visible_message("<span class='warning'>[M]'s body convulses a bit.")
H.visible_message("<span class='warning'>[H]'s body convulses a bit.")
playsound(get_turf(src), "bodyfall", 50, 1)
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
total_brute = H.getBruteLoss()
@@ -512,23 +524,24 @@
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
else
//If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit
if (H.health > halfwaycritdeath)
H.adjustOxyLoss(H.health - halfwaycritdeath, 0)
if (H.health > HALFWAYCRITDEATH)
H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0)
else
var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss()
var/mobhealth = H.health
H.adjustOxyLoss((mobhealth - halfwaycritdeath) * (H.getOxyLoss() / overall_damage), 0)
H.adjustToxLoss((mobhealth - halfwaycritdeath) * (H.getToxLoss() / overall_damage), 0)
H.adjustFireLoss((mobhealth - halfwaycritdeath) * (total_burn / overall_damage), 0)
H.adjustBruteLoss((mobhealth - halfwaycritdeath) * (total_brute / overall_damage), 0)
H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0)
H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0)
H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0)
H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0)
H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually.
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.</span>")
playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0)
H.set_heartattack(FALSE)
H.revive()
H.emote("gasp")
if(tplus > tloss)
H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
add_logs(user, M, "revived", defib)
add_logs(user, H, "revived", defib)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
@@ -537,14 +550,14 @@
defib.cooldowncheck(user)
else
recharge(60)
else if(H.heart_attack)
H.heart_attack = 0
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
else if (!H.getorgan(/obj/item/organ/heart))
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient's heart is missing. Operation aborted.</span>")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
else if(H.undergoing_cardiac_arrest())
H.set_heartattack(FALSE)
user.visible_message("<span class='notice'>[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.</span>")
playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
else
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.</span>")
@@ -579,3 +592,5 @@
icon_state = "defibpaddles0"
item_state = "defibpaddles0"
req_defib = FALSE
#undef HALFWAYCRITDEATH
+1 -1
View File
@@ -56,7 +56,7 @@
/datum/export/organ/alien/abductor
cost = 2500
unit_name = "abductor gland"
export_types = list(/obj/item/organ/gland)
export_types = list(/obj/item/organ/heart/gland)
/datum/export/organ/alien/changeling_egg
cost = 50000 // Holy. Fuck.
+8 -6
View File
@@ -6,11 +6,13 @@
if(bleedsuppress)
return
else
bleedsuppress = 1
spawn(amount)
bleedsuppress = 0
if(stat != DEAD && bleed_rate)
src << "<span class='warning'>The blood soaks through your bandage.</span>"
bleedsuppress = TRUE
addtimer(CALLBACK(src, .proc/resume_bleeding), amount)
/mob/living/carbon/human/proc/resume_bleeding()
bleedsuppress = 0
if(stat != DEAD && bleed_rate)
src << "<span class='warning'>The blood soaks through your bandage.</span>"
/mob/living/carbon/monkey/handle_blood()
@@ -273,4 +275,4 @@
T = get_turf(src)
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
if(!B)
B = new(T)
B = new(T)
@@ -21,7 +21,6 @@
dizziness = 0
jitteriness = 0
heart_attack = 0
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
@@ -820,6 +820,7 @@
regenerate_limbs()
regenerate_organs()
remove_all_embedded_objects()
set_heartattack(FALSE)
drunkenness = 0
for(var/datum/mutation/human/HM in dna.mutations)
if(HM.quality != POSITIVE)
@@ -461,9 +461,10 @@
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
if(heart_attack && !illusion)
if(undergoing_cardiac_arrest() && !illusion)
if(shock_damage * siemens_coeff >= 1 && prob(25))
heart_attack = 0
var/obj/item/organ/heart/heart = getorganslot("heart")
heart.beating = TRUE
if(stat == CONSCIOUS)
src << "<span class='notice'>You feel your heart beating again!</span>"
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
@@ -46,8 +46,6 @@ var/global/default_martial_art = new/datum/martial_art
var/name_override //For temporary visible name changes
var/heart_attack = 0
var/drunkenness = 0 //Overall drunkenness - check handle_alcohol() in life.dm for effects
var/datum/personal_crafting/handcrafting
can_buckle = TRUE
+40 -17
View File
@@ -325,27 +325,50 @@
if(!has_embedded_objects())
clear_alert("embeddedobject")
/mob/living/carbon/human/proc/can_heartattack()
CHECK_DNA_AND_SPECIES(src)
if(NOBLOOD in dna.species.species_traits)
return FALSE
return TRUE
/mob/living/carbon/human/proc/undergoing_cardiac_arrest()
if(!can_heartattack())
return FALSE
var/obj/item/organ/heart/heart = getorganslot("heart")
if(istype(heart) && heart.beating)
return FALSE
return TRUE
/mob/living/carbon/human/proc/set_heartattack(status)
if(!can_heartattack())
return FALSE
var/obj/item/organ/heart/heart = getorganslot("heart")
if(!istype(heart))
return
heart.beating = !status
/mob/living/carbon/human/proc/handle_heart()
CHECK_DNA_AND_SPECIES(src)
var/needs_heart = (!(NOBLOOD in dna.species.species_traits))
if(!can_heartattack())
return
var/we_breath = (!(NOBREATH in dna.species.species_traits))
if(heart_attack)
if(!needs_heart)
heart_attack = FALSE
else if(we_breath)
if(losebreath < 3)
losebreath += 2
adjustOxyLoss(5)
adjustBruteLoss(1)
else
// even though we don't require oxygen, our blood still needs
// circulation, and without it, our tissues die and start
// gaining toxins
adjustBruteLoss(3)
if(src.reagents)
src.reagents.add_reagent("toxin", 2)
if(!undergoing_cardiac_arrest())
return
// Cardiac arrest, unless corazone
if(reagents.get_reagent_amount("corazone"))
return
if(we_breath)
adjustOxyLoss(8)
Paralyse(4)
// Tissues die without blood circulation
adjustBruteLoss(2)
/*
Alcohol Poisoning Chart
@@ -1116,3 +1116,11 @@
M.adjustToxLoss(2, 0)
. = 1
..()
/datum/reagent/medicine/corazone
// Heart attack code will not do as damage if corazone is present
// because it's SPACE MAGIC ASPIRIN
name = "Corazone"
id = "corazone"
description = "A medication used to treat pain, fever, and inflammation, along with heart attacks."
color = "#F5F5F5"
@@ -522,8 +522,8 @@
if(3)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(!H.heart_attack)
H.heart_attack = 1 // rip in pepperoni
if(!H.undergoing_cardiac_arrest() && H.can_heartattack())
H.set_heartattack(TRUE)
if(H.stat == CONSCIOUS)
H.visible_message("<span class='userdanger'>[H] clutches at [H.p_their()] chest as if [H.p_their()] heart stopped!</span>")
else
@@ -833,4 +833,4 @@
if(prob(10))
M.Weaken(1, 0)
. = 1
..()
..()
@@ -212,4 +212,10 @@
name = "Tricordrazine"
id = "tricordrazine"
results = list("tricordrazine" = 3)
required_reagents = list("bicaridine" = 1, "kelotane" = 1, "antitoxin" = 1)
required_reagents = list("bicaridine" = 1, "kelotane" = 1, "antitoxin" = 1)
/datum/chemical_reaction/corazone
name = "Corazone"
id = "corazone"
results = list("corazone" = 3)
required_reagents = list("phenol" = 2, "lithium" = 1)
@@ -100,8 +100,8 @@
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.stat != DEAD && prob(50 / severity))
H.heart_attack = TRUE
if(H.stat != DEAD && prob(50 / severity) && H.can_heartattack())
H.set_heartattack(TRUE)
H << "<span class='userdanger'>You feel a horrible agony in your chest!</span>"
addtimer(CALLBACK(src, .proc/undo_heart_attack), 600 / severity)
@@ -109,7 +109,7 @@
var/mob/living/carbon/human/H = owner
if(!istype(H))
return
H.heart_attack = FALSE
H.set_heartattack(FALSE)
if(H.stat == CONSCIOUS)
H << "<span class='notice'>You feel your heart beating again!</span>"
+6 -19
View File
@@ -104,6 +104,7 @@
zone = "chest"
slot = "heart"
origin_tech = "biotech=5"
// Heart attack code is in code/modules/mob/living/carbon/human/life.dm
var/beating = 1
var/icon_base = "heart"
attack_verb = list("beat", "thumped")
@@ -116,15 +117,8 @@
/obj/item/organ/heart/Remove(mob/living/carbon/M, special = 0)
..()
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.stat == DEAD || H.heart_attack)
Stop()
return
if(!special)
H.heart_attack = 1
addtimer(CALLBACK(src, .proc/stop_if_unowned), 120)
if(!special)
addtimer(CALLBACK(src, .proc/stop_if_unowned), 120)
/obj/item/organ/heart/proc/stop_if_unowned()
if(!owner)
@@ -134,18 +128,11 @@
..()
if(!beating)
visible_message("<span class='notice'>[user] squeezes [src] to \
make it beat again!</span>")
make it beat again!</span>", "<span class='notice'>You squeeze \
[src] to make it beat again!</span>")
Restart()
addtimer(CALLBACK(src, .proc/stop_if_unowned), 80)
/obj/item/organ/heart/Insert(mob/living/carbon/M, special = 0)
..()
if(ishuman(M) && beating)
var/mob/living/carbon/human/H = M
if(H.heart_attack)
H.heart_attack = 0
return
/obj/item/organ/heart/proc/Stop()
beating = 0
update_icon()
@@ -866,4 +853,4 @@
flash_protect = 2
/obj/item/organ/eyes/robotic/shield/emp_act(severity)
return
return