mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 21:48:39 +01:00
Merge pull request #17881 from coiax/time-of-death
Polymorph bugs, time since death, groundwork laid
This commit is contained in:
@@ -433,3 +433,6 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
// Evil narsie colour
|
||||
#define NARSIE_WINDOW_COLOUR "#7D1919"
|
||||
|
||||
// Defib stats
|
||||
#define DEFIB_TIME_LIMIT 120
|
||||
#define DEFIB_TIME_LOSS 60
|
||||
|
||||
+5
-1
@@ -1726,7 +1726,11 @@
|
||||
return G
|
||||
break
|
||||
|
||||
|
||||
/datum/mind/proc/grab_ghost(force)
|
||||
var/mob/dead/observer/G = get_ghost(even_if_they_cant_reenter = force)
|
||||
. = G
|
||||
if(G)
|
||||
G.reenter_corpse()
|
||||
|
||||
/mob/proc/sync_mind()
|
||||
mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist)
|
||||
|
||||
@@ -212,13 +212,17 @@
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
see_in_dark = 8
|
||||
var/independent = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/New()
|
||||
..()
|
||||
verbs -= /mob/living/verb/pulled //no pulling people deep into the blob
|
||||
if(!independent) //no pulling people deep into the blob
|
||||
verbs -= /mob/living/verb/pulled
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/Life()
|
||||
if(..())
|
||||
if(independent)
|
||||
return // strong independent blobbernaut that don't need no blob
|
||||
var/damagesources = 0
|
||||
if(!(locate(/obj/effect/blob) in range(2, src)))
|
||||
damagesources++
|
||||
@@ -271,3 +275,7 @@
|
||||
factory.naut = null //remove this naut from its factory
|
||||
factory.maxhealth = initial(factory.maxhealth)
|
||||
flick("blobbernaut_death", src)
|
||||
|
||||
/mob/living/simple_animal/hostile/blob/blobbernaut/independent
|
||||
independent = TRUE
|
||||
gold_core_spawnable = 1
|
||||
|
||||
@@ -144,14 +144,18 @@
|
||||
visible_message("<span class='warning'>[src] twists and dissolves into a pile of green flesh!</span>", \
|
||||
"<span class='userdanger'>Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--</span>")
|
||||
restore()
|
||||
barf_contents()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/Destroy()
|
||||
/mob/living/simple_animal/hostile/morph/proc/barf_contents()
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.loc = loc
|
||||
if(prob(90))
|
||||
step(AM, pick(alldirs))
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/wabbajack_act(mob/living/new_mob)
|
||||
barf_contents()
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/Aggro() // automated only
|
||||
..()
|
||||
|
||||
@@ -137,27 +137,24 @@
|
||||
// HOT. PINK.
|
||||
//color = "#FF69B4"
|
||||
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/New()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/death()
|
||||
release_friends()
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/wabbajack_act()
|
||||
release_friends()
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/proc/release_friends()
|
||||
if(!consumed_mobs)
|
||||
return ..()
|
||||
return
|
||||
|
||||
for(var/mob/living/M in consumed_mobs)
|
||||
M.loc = get_turf(src)
|
||||
if(M.revive(full_heal = 1))
|
||||
// Feel there should be a better way of FORCING a mob's ghost
|
||||
// back into the body
|
||||
if(!M.ckey)
|
||||
for(var/mob/dead/observer/ghost in player_list)
|
||||
if(M.real_name == ghost.real_name)
|
||||
ghost.reenter_corpse()
|
||||
break
|
||||
M << "<span class='clown'>You leave the [src]'s warm embrace, and feel ready to take on the world.</span>"
|
||||
|
||||
return ..()
|
||||
M.grab_ghost(force = FALSE)
|
||||
M << "<span class='clown'>You leave the [src]'s warm embrace, \
|
||||
and feel ready to take on the world.</span>"
|
||||
|
||||
/mob/living/simple_animal/slaughter/laughter/bloodcrawl_swallow(var/mob/living/victim)
|
||||
if(consumed_mobs)
|
||||
|
||||
@@ -173,6 +173,10 @@ MASS SPECTROMETER
|
||||
// Time of death
|
||||
if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH)))
|
||||
user << "<span class='info'>Time of Death:</span> [M.tod]"
|
||||
var/tdelta = world.time - M.timeofdeath
|
||||
if(tdelta < (DEFIB_TIME_LIMIT * 10))
|
||||
user << "<span class='danger'>Subject died [tdelta / 10] seconds \
|
||||
ago, defibrillation may be possible!</span>"
|
||||
|
||||
for(var/datum/disease/D in M.viruses)
|
||||
if(!(D.visibility_flags & HIDDEN_SCANNER))
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
//backpack item
|
||||
|
||||
/obj/item/weapon/defibrillator
|
||||
name = "defibrillator"
|
||||
desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients."
|
||||
@@ -19,6 +18,7 @@
|
||||
var/obj/item/weapon/twohanded/shockpaddles/paddles
|
||||
var/obj/item/weapon/stock_parts/cell/high/bcell = null
|
||||
var/combat = 0 //can we revive through space suits?
|
||||
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
|
||||
|
||||
/obj/item/weapon/defibrillator/New() //starts without a cell for rnd
|
||||
..()
|
||||
@@ -297,6 +297,7 @@
|
||||
var/obj/item/weapon/defibrillator/defib
|
||||
var/req_defib = 1
|
||||
var/combat = 0 //If it penetrates armor and gives additional functionality
|
||||
var/grab_ghost = FALSE
|
||||
|
||||
/obj/item/weapon/twohanded/shockpaddles/proc/recharge(var/time)
|
||||
if(req_defib || !time)
|
||||
@@ -382,178 +383,186 @@
|
||||
else
|
||||
user << "<span class='warning'>You aren't sure how to revive that...</span>"
|
||||
return
|
||||
else
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(user.a_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)
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(user.a_intent == "disarm")
|
||||
if(req_defib && defib.safety)
|
||||
return
|
||||
if(user.zone_selected == "chest")
|
||||
if(user.a_intent == "harm")
|
||||
if(req_defib && defib.safety)
|
||||
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 == "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(!req_defib && !combat)
|
||||
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='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
|
||||
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()
|
||||
return
|
||||
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)
|
||||
if(!req_defib)
|
||||
recharge(60)
|
||||
if(req_defib && (defib.cooldowncheck(user)))
|
||||
return
|
||||
busy = 0
|
||||
update_icon()
|
||||
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>")
|
||||
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>")
|
||||
playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0)
|
||||
var/tplus = world.time - H.timeofdeath
|
||||
var/tlimit = 1200 //past this much time the patient is unrecoverable (in deciseconds)
|
||||
var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting
|
||||
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
|
||||
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))
|
||||
user.audible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient's chest is obscured. Operation aborted.</span>")
|
||||
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
|
||||
busy = 0
|
||||
update_icon()
|
||||
return
|
||||
if(H.stat == DEAD)
|
||||
M.visible_message("<span class='warning'>[M]'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()
|
||||
total_burn = H.getFireLoss()
|
||||
|
||||
var/failed = null
|
||||
|
||||
if (H.suiciding || (H.disabilities & NOCLONE))
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.</span>"
|
||||
else if (H.hellbound)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existance. Further attempts futile.</span>"
|
||||
else if (tplus > tlimit)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile.</span>"
|
||||
else if (!H.getorgan(/obj/item/organ/heart))
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing.</span>"
|
||||
else if(total_burn >= 180 || total_brute >= 180)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile.</span>"
|
||||
else if(H.get_ghost())
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful.</span>"
|
||||
else
|
||||
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
|
||||
if(!BR || BR.damaged_brain)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile.</span>"
|
||||
|
||||
if(failed)
|
||||
user.visible_message(failed)
|
||||
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)
|
||||
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)
|
||||
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.revive()
|
||||
H.emote("gasp")
|
||||
if(tplus > tloss)
|
||||
H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
|
||||
add_logs(user, M, "revived", defib)
|
||||
if(req_defib)
|
||||
defib.deductcharge(revivecost)
|
||||
cooldown = 1
|
||||
update_icon()
|
||||
if(req_defib)
|
||||
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
|
||||
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.</span>")
|
||||
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>")
|
||||
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>")
|
||||
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
|
||||
// (in deciseconds)
|
||||
var/tlimit = DEFIB_TIME_LIMIT * 10
|
||||
// brain damage starts setting in on the patient after
|
||||
// some time left rotting
|
||||
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
|
||||
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))
|
||||
user.audible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient's chest is obscured. Operation aborted.</span>")
|
||||
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
|
||||
busy = 0
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='warning'>You need to target your patient's chest with [src]!</span>"
|
||||
return
|
||||
busy = 0
|
||||
update_icon()
|
||||
return
|
||||
if(H.stat == DEAD)
|
||||
M.visible_message("<span class='warning'>[M]'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()
|
||||
total_burn = H.getFireLoss()
|
||||
|
||||
var/failed = null
|
||||
|
||||
if (H.suiciding || (H.disabilities & NOCLONE))
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile.</span>"
|
||||
else if (H.hellbound)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existance. Further attempts futile.</span>"
|
||||
else if (tplus > tlimit)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile.</span>"
|
||||
else if (!H.getorgan(/obj/item/organ/heart))
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing.</span>"
|
||||
else if(total_burn >= 180 || total_brute >= 180)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile.</span>"
|
||||
else if(H.get_ghost())
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful.</span>"
|
||||
else
|
||||
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
|
||||
if(!BR || BR.damaged_brain)
|
||||
failed = "<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile.</span>"
|
||||
|
||||
if(failed)
|
||||
user.visible_message(failed)
|
||||
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)
|
||||
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)
|
||||
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.revive()
|
||||
H.emote("gasp")
|
||||
if(tplus > tloss)
|
||||
H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))))
|
||||
add_logs(user, M, "revived", defib)
|
||||
if(req_defib)
|
||||
defib.deductcharge(revivecost)
|
||||
cooldown = 1
|
||||
update_icon()
|
||||
if(req_defib)
|
||||
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
|
||||
user.visible_message("<span class='warning'>[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.</span>")
|
||||
playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0)
|
||||
busy = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/twohanded/shockpaddles/syndicate
|
||||
name = "syndicate defibrillator paddles"
|
||||
|
||||
@@ -1024,3 +1024,18 @@ Sorry Giacom. Please don't be mad :(
|
||||
for(var/datum/objective/sintouched/acedia/A in src.mind.objectives)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Called when we are hit by a bolt of polymorph and changed
|
||||
// Generally the mob we are currently in, is about to be deleted
|
||||
/mob/living/proc/wabbajack_act(mob/living/new_mob)
|
||||
if(mind)
|
||||
mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = key
|
||||
|
||||
for(var/para in hasparasites())
|
||||
var/mob/living/simple_animal/hostile/guardian/G = para
|
||||
G.summoner = new_mob
|
||||
G.Recall()
|
||||
G << "<span class='holoparasite'>Your summoner has changed \
|
||||
form to [new_mob]!</span>"
|
||||
|
||||
@@ -156,6 +156,13 @@
|
||||
update_drone_icon()
|
||||
updateSeeStaticMobs()
|
||||
|
||||
/mob/living/simple_animal/drone/proc/liberate()
|
||||
// F R E E D R O N E
|
||||
laws = "1. You are a Free Drone."
|
||||
src << laws
|
||||
seeStatic = FALSE
|
||||
updateSeeStaticMobs()
|
||||
|
||||
/mob/living/simple_animal/drone/proc/update_drone_icon()
|
||||
//Different icons for different hack states
|
||||
if(!hacked)
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
var/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
|
||||
"blue", "dark blue", "dark purple", "yellow", "silver", "pink", "red",
|
||||
"gold", "green", "adamantine", "oil", "light pink", "bluespace",
|
||||
"cerulean", "sepia", "black", "pyrite")
|
||||
|
||||
/mob/living/simple_animal/slime
|
||||
name = "baby slime"
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
@@ -16,7 +21,7 @@
|
||||
response_disarm = "shoos"
|
||||
response_harm = "stomps on"
|
||||
emote_see = list("jiggles", "bounces in place")
|
||||
speak_emote = list("chirps")
|
||||
speak_emote = list("telepathically chirps")
|
||||
bubble_icon = "slime"
|
||||
|
||||
layer = 5
|
||||
@@ -83,19 +88,26 @@
|
||||
var/datum/action/innate/slime/evolve/E = new
|
||||
E.Grant(src)
|
||||
create_reagents(100)
|
||||
spawn (0)
|
||||
number = rand(1, 1000)
|
||||
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
|
||||
icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
|
||||
icon_dead = "[icon_state] dead"
|
||||
real_name = name
|
||||
slime_mutation = mutation_table(colour)
|
||||
var/sanitizedcolour = replacetext(colour, " ", "")
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
spawn(0)
|
||||
set_colour(colour)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/slime/proc/set_colour(new_colour)
|
||||
colour = new_colour
|
||||
|
||||
number = rand(1, 1000)
|
||||
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
|
||||
real_name = name
|
||||
slime_mutation = mutation_table(colour)
|
||||
var/sanitizedcolour = replacetext(colour, " ", "")
|
||||
coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]")
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/slime/proc/random_colour()
|
||||
set_colour(pick(slime_colours))
|
||||
|
||||
/mob/living/simple_animal/slime/regenerate_icons()
|
||||
overlays.len = 0
|
||||
overlays.Cut()
|
||||
var/icon_text = "[colour] [is_adult ? "adult" : "baby"] slime"
|
||||
icon_dead = "[icon_text] dead"
|
||||
if(stat != DEAD)
|
||||
@@ -107,7 +119,7 @@
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/slime/movement_delay()
|
||||
if(bodytemperature >= 330.23) // 135 F
|
||||
if(bodytemperature >= 330.23) // 135 F or 57.08 C
|
||||
return -1 // slimes become supercharged at high temperatures
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -764,6 +764,10 @@ var/next_mob_id = 0
|
||||
if(mind)
|
||||
return mind.get_ghost(even_if_they_cant_reenter)
|
||||
|
||||
/mob/proc/grab_ghost(force)
|
||||
if(mind)
|
||||
return mind.grab_ghost(force = force)
|
||||
|
||||
/mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null)
|
||||
var/mob/dead/observer/ghost = get_ghost()
|
||||
if(ghost)
|
||||
|
||||
@@ -61,12 +61,9 @@
|
||||
var/mob/living/carbon/C = target
|
||||
C.regenerate_limbs()
|
||||
if(target.revive(full_heal = 1))
|
||||
if(!target.ckey)
|
||||
for(var/mob/dead/observer/ghost in player_list)
|
||||
if(target.real_name == ghost.real_name)
|
||||
ghost.reenter_corpse()
|
||||
break
|
||||
target << "<span class='notice'>You rise with a start, you're alive!!!</span>"
|
||||
target.grab_ghost(force = TRUE) // even suicides
|
||||
target << "<span class='notice'>You rise with a start, \
|
||||
you're alive!!!</span>"
|
||||
else if(target.stat != DEAD)
|
||||
target << "<span class='notice'>You feel great!</span>"
|
||||
|
||||
@@ -175,7 +172,7 @@
|
||||
if("drone")
|
||||
new_mob = new /mob/living/simple_animal/drone(M.loc)
|
||||
var/mob/living/simple_animal/drone/D = new_mob
|
||||
D.update_drone_hack()
|
||||
D.liberate() // F R E E D R O N E
|
||||
if(issilicon(new_mob))
|
||||
new_mob.gender = M.gender
|
||||
new_mob.invisibility = 0
|
||||
@@ -186,9 +183,10 @@
|
||||
new_mob.languages |= HUMAN
|
||||
if("slime")
|
||||
new_mob = new /mob/living/simple_animal/slime(M.loc)
|
||||
var/mob/living/simple_animal/slime/slimey = new_mob
|
||||
if(prob(50))
|
||||
var/mob/living/simple_animal/slime/Slime = new_mob
|
||||
Slime.is_adult = 1
|
||||
slimey.is_adult = 1
|
||||
slimey.random_colour()
|
||||
new_mob.languages |= HUMAN
|
||||
if("xeno")
|
||||
if(prob(50))
|
||||
@@ -220,7 +218,7 @@
|
||||
if("spiderhunter")
|
||||
new_mob = new /mob/living/simple_animal/hostile/poison/giant_spider/hunter(M.loc)
|
||||
if("blobbernaut")
|
||||
new_mob = new /mob/living/simple_animal/hostile/blob/blobbernaut(M.loc)
|
||||
new_mob = new /mob/living/simple_animal/hostile/blob/blobbernaut/independent(M.loc)
|
||||
if("magicarp")
|
||||
new_mob = new /mob/living/simple_animal/hostile/carp/ranged(M.loc)
|
||||
if("chaosmagicarp")
|
||||
@@ -279,10 +277,8 @@
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>[M.real_name] ([M.ckey]) became [new_mob.real_name].</font>")
|
||||
|
||||
new_mob.a_intent = "harm"
|
||||
if(M.mind)
|
||||
M.mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = M.key
|
||||
|
||||
M.wabbajack_act(new_mob)
|
||||
|
||||
new_mob << "<B>Your form morphs into that of a [randomize].</B>"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user