diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 3316894b169..d8d80a8b1c5 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -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))
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index b7b05526a13..91e4bcda519 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -435,7 +435,7 @@ Congratulations! You are now trained for xenobiology research!"}
species = "[H.dna.species.name]"
if(L.mind && L.mind.changeling)
species = "Changeling lifeform"
- 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 = "Experimental gland detected!"
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 << "You need one sheet of silver to do \
+ this!"
+ return
+ user << "You start adding [P] to [src]..."
+ 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 << "You feel a series of tiny pricks!"
+
+/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"
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
index def0cd77e2f..e888e2884c5 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_surgery.dm
@@ -33,15 +33,15 @@
if(IC)
user.visible_message("[user] pulls [IC] out of [target]'s [target_zone]!", "You pull [IC] out of [target]'s [target_zone].")
user.put_in_hands(IC)
- IC.Remove(target, special = 1)
+ IC.Remove(target)
return 1
else
user << "You don't find anything in [target]'s [target_zone]!"
- 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].", "You insert [tool] into [target].")
user.drop_item()
- var/obj/item/organ/gland/gland = tool
+ var/obj/item/organ/heart/gland/gland = tool
gland.Insert(target, 2)
- return 1
\ No newline at end of file
+ return 1
diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm
index ead066e8ccd..15560a450ee 100644
--- a/code/game/gamemodes/miniantags/abduction/gland.dm
+++ b/code/game/gamemodes/miniantags/abduction/gland.dm
@@ -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 << "You feel curiously revitalized."
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 << "You feel nauseous!"
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 << "You get a headache."
var/turf/T = get_turf(owner)
@@ -97,38 +99,37 @@
H << "You hear a buzz in your head."
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 << "You feel unlike yourself."
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 << "You feel very stretchy."
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 << "You feel sick."
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 << "You feel a spike of pain in your head."
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 << "You feel something crawling in your skin."
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 << "You lay an egg!"
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("[owner]'s skin erupts with blood!",\
"Blood pours from your skin!")
@@ -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 << "You feel something moving around inside you..."
//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 << "You feel bloated."
sleep(150)
if(!owner) return
@@ -258,4 +257,3 @@
if(istype(T))
T.atmos_spawn_air("plasma=50;TEMP=[T20C]")
owner.vomit()
- return
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
index f4c07f98343..5894c4d98b5 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm
@@ -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
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
index 265838d15a3..c82a72631ec 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm
@@ -160,7 +160,7 @@
if(H.stat == DEAD)
say("Specimen deceased - please provide fresh sample.")
return "Specimen deceased."
- 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 "No glands detected!"
@@ -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)
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 5441fc9c481..81de98c0aa2 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -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 [occupant.real_name] 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 [occupant] 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 << "-% Cannot link machines across power zones. Buffer cleared %-"
@@ -278,28 +287,27 @@
P.buffer = src
user << "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-"
return
-
- if (W.GetID())
- if (!check_access(W))
+
+ if(W.GetID())
+ if(!check_access(W))
user << "Access Denied."
return
- if (!locked || !occupant)
- return
- if (occupant.health < -20 && occupant.stat != DEAD)
- user << "Access Refused. Patient status still unstable."
+ if(!(occupant || mess))
+ user << "Error: Pod has no occupant."
return
else
- locked = FALSE
- user << "System unlocked."
+ connected_message("Authorized Ejection")
+ SPEAK("An authorized ejection of [occupant.real_name] has occurred.")
+ user << "You force an emergency ejection. "
+ go_out()
else
return ..()
/obj/machinery/clonepod/emag_act(mob/user)
- if (isnull(occupant))
+ if(!occupant)
return
- user << "You force an emergency ejection."
- locked = FALSE
- go_out()
+ user << "You corrupt the genetic compiler."
+ 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("You hear a splat.")
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
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 02706abf4d4..d8ec9e29218 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -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
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 9da0d31aac7..f5ee27cc0e3 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -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 << "Subject suffering from heart attack: Apply defibrillator immediately!"
if(iscarbon(M))
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index 965c9fe1463..47bc2d5835c 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -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 << "[src] are recharging!"
return
+
+ if(user.a_intent == INTENT_DISARM)
+ do_disarm(M, user)
+ return
+
if(!ishuman(M))
if(req_defib)
user << "The instructions on [defib] don't mention how to revive that..."
@@ -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("[user] has touched [H.name] with [src]!", \
- "[user] has touched [H.name] with [src]!")
- 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 << "You need to target your patient's \
chest with [src]!"
return
+
if(user.a_intent == INTENT_HARM)
- if(req_defib && defib.safety)
- return
- if(!req_defib && !combat)
- return
- user.visible_message("[user] begins to place [src] on [M.name]'s chest.",
- "You overcharge the paddles and begin to place them onto [M]'s chest...")
- busy = 1
- update_icon()
- if(do_after(user, 30, target = M))
- user.visible_message("[user] places [src] on [M.name]'s chest.",
- "You place [src] on [M.name]'s chest and begin to charge them.")
- var/turf/T = get_turf(defib)
- playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
- if(req_defib)
- T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...")
- else
- user.audible_message("[src] let out an urgent beep.")
- 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 << "[M] is dead."
- playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
- busy = 0
- update_icon()
- return
- user.visible_message("[user] shocks [M] with \the [src]!", "You shock [M] with \the [src]!")
- 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("[M] thrashes wildly, clutching at their chest!",
- "You feel a horrible agony in your chest!")
- 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("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest...")
+ 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("[user] has touched [M] with [src]!", \
+ "[user] has touched [M] with [src]!")
+ 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("[user] begins to place [src] on [H]'s chest.",
+ "You overcharge the paddles and begin to place them onto [H]'s chest...")
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("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.")
+ if(do_after(user, 30, target = H))
+ user.visible_message("[user] places [src] on [H]'s chest.",
+ "You place [src] on [H]'s chest and begin to charge them.")
+ var/turf/T = get_turf(defib)
+ playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
+ if(req_defib)
+ T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...")
+ else
+ user.audible_message("[src] let out an urgent beep.")
+ 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 << "[H] is dead."
+ playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
+ busy = 0
+ update_icon()
+ return
+ user.visible_message("[user] shocks [H] with \the [src]!", "You shock [H] with \the [src]!")
+ 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("[H] thrashes wildly, clutching at their chest!",
+ "You feel a horrible agony in your chest!")
+ 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("[user] begins to place [src] on [H]'s chest.", "You begin to place [src] on [H]'s chest...")
+ 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("[user] places [src] on [H]'s chest.", "You place [src] on [H]'s chest.")
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("[M]'s body convulses a bit.")
+ H.visible_message("[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("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.")
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("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.")
- playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
-
else if (!H.getorgan(/obj/item/organ/heart))
user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient's heart is missing. Operation aborted.")
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
+ else if(H.undergoing_cardiac_arrest())
+ H.set_heartattack(FALSE)
+ user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.")
+ playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1)
+
else
user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.")
@@ -579,3 +592,5 @@
icon_state = "defibpaddles0"
item_state = "defibpaddles0"
req_defib = FALSE
+
+#undef HALFWAYCRITDEATH
diff --git a/code/modules/cargo/exports/organs.dm b/code/modules/cargo/exports/organs.dm
index ebf34e8763c..39c0051a4ee 100644
--- a/code/modules/cargo/exports/organs.dm
+++ b/code/modules/cargo/exports/organs.dm
@@ -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.
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index 73ae98b59db..4a0e072a06f 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -6,11 +6,13 @@
if(bleedsuppress)
return
else
- bleedsuppress = 1
- spawn(amount)
- bleedsuppress = 0
- if(stat != DEAD && bleed_rate)
- src << "The blood soaks through your bandage."
+ bleedsuppress = TRUE
+ addtimer(CALLBACK(src, .proc/resume_bleeding), amount)
+
+/mob/living/carbon/human/proc/resume_bleeding()
+ bleedsuppress = 0
+ if(stat != DEAD && bleed_rate)
+ src << "The blood soaks through your bandage."
/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)
\ No newline at end of file
+ B = new(T)
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index cd3c9a533ac..6464d1ab70e 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -21,7 +21,6 @@
dizziness = 0
jitteriness = 0
- heart_attack = 0
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index b0eac013cd8..9ebefb9dc9b 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -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)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 16c2ae46bc4..9fefbb3ab6e 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -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 << "You feel your heart beating again!"
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index d712ce9b6a9..796897c5bcf 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -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
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 239f657ba03..2651a150cd0 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -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
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 0c6a3e4302b..67fc0608607 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -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"
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index fc79232e8f5..24ca24a3d3f 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -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("[H] clutches at [H.p_their()] chest as if [H.p_their()] heart stopped!")
else
@@ -833,4 +833,4 @@
if(prob(10))
M.Weaken(1, 0)
. = 1
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index e446ab9736b..187b42f035f 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -212,4 +212,10 @@
name = "Tricordrazine"
id = "tricordrazine"
results = list("tricordrazine" = 3)
- required_reagents = list("bicaridine" = 1, "kelotane" = 1, "antitoxin" = 1)
\ No newline at end of file
+ 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)
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index 850335c717a..e352273a13e 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -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 << "You feel a horrible agony in your chest!"
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 << "You feel your heart beating again!"
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 086395d0b64..da4ab4725f7 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -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("[user] squeezes [src] to \
- make it beat again!")
+ make it beat again!", "You squeeze \
+ [src] to make it beat again!")
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
\ No newline at end of file
+ return