Allows clone backups from destroyed bodies (but for real) (#34460)

* fix destroyed bodies being uncloneable

* fixes slimes cloning when gibbed or dusted
This commit is contained in:
nervere
2023-06-27 14:45:42 -04:00
committed by GitHub
parent 3d18355fd9
commit 232b8b96e0
4 changed files with 49 additions and 29 deletions

View File

@@ -193,7 +193,7 @@
if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body
return FALSE return FALSE
if(clonemind.active) //somebody is using that mind if(clonemind.active) //somebody is using that mind
if( ckey(clonemind.key)!=R.ckey ) if(ckey(clonemind.key)!=R.ckey )
return FALSE return FALSE
else else
for(var/mob/G in player_list) for(var/mob/G in player_list)
@@ -201,6 +201,10 @@
if(isobserver(G)) if(isobserver(G))
if(G:can_reenter_corpse) if(G:can_reenter_corpse)
break break
if((!G.mind.current) && G.mind.body_archive) //If the mind's body was destroyed and that mind has a body archive
var/datum/dna2/record/D = G.mind.body_archive.data["dna_records"] //Retrieve the DNA records from the mind's body archive
if((D.id == R.id) || D.ckey == R.ckey) //If the MD5 hash of the mind's real_name matches the record's real_name (stored as the id variable), or if the ckeys match
break //Proceed with cloning. This set of checks is to allow cloning players with completely destroyed bodies, that nevertheless had cloning data stored
else else
return FALSE return FALSE
else if(G) else if(G)

View File

@@ -338,35 +338,31 @@
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if(!pod1 || !canLink(pod1)) //If the pod exists BUT it's too far away from the console if(!pod1 || !canLink(pod1)) //If the pod exists BUT it's too far away from the console
temp = "Error: No Clonepod detected." temp = "Error: No Clonepod detected."
return
else if(pod1.occupant) else if(pod1.occupant)
temp = "Error: Clonepod is currently occupied." temp = "Error: Clonepod is currently occupied."
return
else if(pod1.biomass < CLONE_BIOMASS) else if(pod1.biomass < CLONE_BIOMASS)
temp = "Error: Not enough biomass." temp = "Error: Not enough biomass."
return
else if(pod1.mess) else if(pod1.mess)
temp = "Error: Clonepod malfunction." temp = "Error: Clonepod malfunction."
return
else if(!config.revival_cloning) else if(!config.revival_cloning)
temp = "Error: Unable to initiate cloning cycle." temp = "Error: Unable to initiate cloning cycle."
return
if(pod1.growclone(C))
temp = "Initiating cloning cycle..."
records.Remove(C)
QDEL_NULL(C)
menu = 1
else else
if(pod1.growclone(C)) temp = "Initiating cloning cycle...<br>Error: Post-initialisation failed. Cloning cycle aborted."
temp = "Initiating cloning cycle..." src.updateUsrDialog()
records.Remove(C) return
QDEL_NULL(C)
menu = 1
else
//if growclone() failed, we can't clone the guy, so what is this even DOING here?
var/mob/selected = find_dead_player("[C.ckey]")
if(!selected)
temp = "Initiating cloning cycle...<br>Error: Post-initialisation failed. Cloning cycle aborted."
src.updateUsrDialog()
return
selected << 'sound/effects/adminhelp.ogg'
if(alert(selected,"Your DNA has been selected for cloning. Do you want to return to life?","Cloning","Yes","No") == "Yes" && pod1.growclone(C))
temp = "Initiating cloning cycle..."
records.Remove(C)
QDEL_NULL(C)
menu = 1
else
temp = "Initiating cloning cycle...<br>Error: Post-initialisation failed. Cloning cycle aborted."
else else
temp = "Error: Data corruption." temp = "Error: Data corruption."

View File

@@ -131,7 +131,7 @@
dorfpod.scan_body(src) dorfpod.scan_body(src)
if(ticker && ticker.mode) if(ticker && ticker.mode)
sql_report_death(src) sql_report_death(src)
species.handle_death(src) species.handle_death(src, gibbed)
if(become_zombie) if(become_zombie)
spawn(20 SECONDS) spawn(20 SECONDS)
if(!gcDestroyed) if(!gcDestroyed)

View File

@@ -282,7 +282,7 @@ var/global/list/playable_species = list("Human")
else else
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). /datum/species/proc/handle_death(var/mob/living/carbon/human/H, var/gibbed = 0) //Handles any species-specific death events (such as dionaea nymph spawns).
return return
/datum/species/proc/can_artifact_revive() /datum/species/proc/can_artifact_revive()
@@ -1111,11 +1111,35 @@ var/list/has_died_as_golem = list()
"brain" = /datum/organ/internal/brain/slime_core, "brain" = /datum/organ/internal/brain/slime_core,
) )
/datum/species/slime/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). /datum/species/slime/handle_death(var/mob/living/carbon/human/H, gibbed) //Handles any species-specific death events (such as dionaea nymph spawns).
H.dropBorers() H.dropBorers(gibbed)
for(var/atom/movable/I in H.contents) for(var/atom/movable/I in H.contents)
I.forceMove(H.loc) I.forceMove(H.loc)
anim(target = H, a_icon = 'icons/mob/mob.dmi', flick_anim = "liquify", sleeptime = 15) anim(target = H, a_icon = 'icons/mob/mob.dmi', flick_anim = "liquify", sleeptime = 15)
if(!gibbed)
handle_slime_puddle(H)
/datum/species/slime/gib(mob/living/carbon/human/H)
handle_slime_puddle(H)
..()
H.monkeyizing = TRUE
for(var/datum/organ/external/E in H.organs)
if(istype(E, /datum/organ/external/chest) || istype(E, /datum/organ/external/groin) || istype(E, /datum/organ/external/head))
continue
//Only make the limb drop if it's not too damaged
if(prob(100 - E.get_damage()))
//Override the current limb status and don't cause an explosion
E.droplimb(1, 1)
var/gib_radius = 0
if(H.reagents.has_reagent(LUBE))
gib_radius = 6
anim(target = H, a_icon = 'icons/mob/mob.dmi', flick_anim = "gibbed-h", sleeptime = 15)
hgibs(H.loc, H.virus2, H.dna, flesh_color, blood_color, gib_radius)
/datum/species/slime/proc/handle_slime_puddle(var/mob/living/carbon/human/H)
if(!H)
return
var/mob/living/slime_pile/S = new(H.loc) var/mob/living/slime_pile/S = new(H.loc)
if(H.real_name) if(H.real_name)
S.real_name = H.real_name S.real_name = H.real_name
@@ -1127,10 +1151,6 @@ var/list/has_died_as_golem = list()
S.dna=H.dna S.dna=H.dna
S.mind=H.mind S.mind=H.mind
/datum/species/slime/gib(mob/living/carbon/human/H)
..()
H.default_gib()
/mob/living/slime_pile //serves as the corpse of slime people /mob/living/slime_pile //serves as the corpse of slime people
name = "puddle of slime" name = "puddle of slime"
desc = "The remains of a slime person." desc = "The remains of a slime person."