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