diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 9e8756bb..78953609 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -598,6 +598,14 @@ /atom/proc/multitool_act(mob/living/user, obj/item/I) return +///Check if the multitool has an item in it's data buffer +/atom/proc/multitool_check_buffer(user, obj/item/I, silent = FALSE) + if(!istype(I, /obj/item/multitool)) + if(user && !silent) + to_chat(user, "[I] has no data buffer!") + return FALSE + return TRUE + /atom/proc/screwdriver_act(mob/living/user, obj/item/I) SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 398895d6..83f367c7 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -53,7 +53,10 @@ update_icon() /obj/machinery/clonepod/Destroy() + var/mob/living/mob_occupant = occupant go_out() + if(mob_occupant) + log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to Destroy().") QDEL_NULL(radio) QDEL_NULL(countdown) if(connected) @@ -151,6 +154,7 @@ return FALSE if(mess || attempting) return FALSE + if(!empty) //Doesn't matter if we're just making a copy clonemind = locate(mindref) in SSticker.minds if(!istype(clonemind)) //not a mind @@ -183,8 +187,16 @@ H.hardset_dna(ui, mutation_index, H.real_name, blood_type, mrace, features) - if(prob(50 - efficiency*10)) //Chance to give a bad mutation. - H.easy_randmut(NEGATIVE+MINOR_NEGATIVE) //100% bad mutation. Can be cured with mutadone. + if(!HAS_TRAIT(H, TRAIT_RADIMMUNE))//dont apply mutations if the species is Mutation proof. + if(efficiency > 2) + var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) + H.dna.remove_mutation_group(unclean_mutations) + if(efficiency > 5 && prob(20)) + H.easy_randmut(POSITIVE) + if(efficiency < 3 && prob(50)) + var/mob/M = H.easy_randmut(NEGATIVE+MINOR_NEGATIVE) + if(ismob(M)) + H = M H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment. occupant = H @@ -234,16 +246,20 @@ if(!is_operational()) //Autoeject if power is lost if(mob_occupant) go_out() + log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to power loss.") + mob_occupant.apply_vore_prefs() + connected_message("Clone Ejected: Loss of power.") else if(mob_occupant && (mob_occupant.loc == src)) - if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. + if(mob_occupant && (mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. connected_message("Clone Rejected: Deceased.") if(internal_radio) SPEAK("The cloning has been \ aborted due to unrecoverable tissue failure.") go_out() + log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] after suiciding.") mob_occupant.apply_vore_prefs() else if(mob_occupant.cloneloss > (100 - heal_level)) @@ -291,10 +307,13 @@ BP.attach_limb(mob_occupant) go_out() + log_cloning("[key_name(mob_occupant)] completed cloning cycle in [src] at [AREACOORD(src)].") mob_occupant.apply_vore_prefs() else if (!mob_occupant || mob_occupant.loc != src) occupant = null + if (!mess && !panel_open) + icon_state = "pod_0" use_power(200) update_icon() @@ -309,6 +328,8 @@ return if(istype(W, /obj/item/multitool)) + if(!multitool_check_buffer(user, W)) + return var/obj/item/multitool/P = W if(istype(P.buffer, /obj/machinery/computer/cloning)) @@ -335,10 +356,13 @@ to_chat(user, "Error: Pod has no occupant.") return else + add_fingerprint(user) connected_message("Emergency Ejection") SPEAK("An emergency ejection of the current clone has occurred. Survival not guaranteed.") to_chat(user, "You force an emergency ejection. ") go_out() + log_cloning("[key_name(user)] manually ejected [key_name(mob_occupant)] from [src] at [AREACOORD(src)].") + log_combat(user, mob_occupant, "ejected", W, "from [src]") mob_occupant.apply_vore_prefs() else return ..() @@ -348,6 +372,9 @@ return to_chat(user, "You corrupt the genetic compiler.") malfunction() + add_fingerprint(user) + log_cloning("[key_name(user)] emagged [src] at [AREACOORD(src)], causing it to malfunction.") + log_combat(user, src, "emagged", null, occupant ? "[occupant] inside, killing them via malfunction." : null) //Put messages in the connected computer's temp var for display. /obj/machinery/clonepod/proc/connected_message(message) @@ -418,6 +445,7 @@ to_chat(mob_occupant, "Agony blazes across your consciousness as your body is torn apart.
Is this what dying is like? Yes it is.
") playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0) SEND_SOUND(mob_occupant, sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)) + log_cloning("[key_name(mob_occupant)] destroyed within [src] at [AREACOORD(src)] due to malfunction.") QDEL_IN(mob_occupant, 40) /obj/machinery/clonepod/relaymove(mob/user) @@ -436,11 +464,14 @@ SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of, ERROR: John Doe, prematurely." ,0)) mob_occupant.apply_vore_prefs() go_out() + log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to EMP pulse.") /obj/machinery/clonepod/ex_act(severity, target) ..() - if(!QDELETED(src)) + if(!QDELETED(src) && occupant) + var/mob/living/mob_occupant = occupant go_out() + log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to explosion.") /obj/machinery/clonepod/handle_atom_del(atom/A) if(A == occupant) @@ -456,7 +487,9 @@ /obj/machinery/clonepod/deconstruct(disassembled = TRUE) if(occupant) + var/mob/living/mob_occupant = occupant go_out() + log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to deconstruction.") ..() /obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H)