mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user