diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 9a09c684389..2da498f8b8d 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -163,6 +163,17 @@ new_character.key = key //now transfer the key to link the client to our new body SEND_SIGNAL(src, COMSIG_MIND_TRANSER_TO, new_character) SEND_SIGNAL(new_character, COMSIG_BODY_TRANSFER_TO) + if(ishuman(new_character)) + var/mob/living/carbon/human/H = new_character + if(H.mind in SSticker.mode.syndicates) + SSticker.mode.update_synd_icons_added() + if(H.mind in SSticker.mode.cult) + SSticker.mode.update_cult_icons_added(H.mind) // Adds the cult antag hud + SSticker.mode.add_cult_actions(H.mind) // And all the actions + if(SSticker.mode.cult_risen) + SSticker.mode.rise(H) + if(SSticker.mode.cult_ascendant) + SSticker.mode.ascend(H) /datum/mind/proc/store_memory(new_text) memory += "[new_text]
" diff --git a/code/datums/uplink_items/uplink_traitor.dm b/code/datums/uplink_items/uplink_traitor.dm index fde738f81a4..41bffc99dfa 100644 --- a/code/datums/uplink_items/uplink_traitor.dm +++ b/code/datums/uplink_items/uplink_traitor.dm @@ -365,6 +365,16 @@ cost = 10 species = list("Human") +//Gr(e)(a)y +/datum/uplink_item/species_restricted/prescan + name = "Technocracy Advanced Cloning System" + desc = "This kit will give you the parts to build an advanced automatic cloning system, to clone whoever has the linked implant installed on death. \ + Power intensive, implant must be recovered for reuse, and implanter must be linked to cloner." + reference = "TACS" + item = /obj/item/storage/box/syndie_kit/prescan + cost = 25 /// A fresh start, but a start with nothing. Hard to use as well + species = list("Grey") + // ------------------------------------- // ITEMS BLACKLISTED FROM NUCLEAR AGENTS // ------------------------------------- diff --git a/code/game/machinery/clonepod.dm b/code/game/machinery/clonepod.dm index 5051daab729..2ae918c6e73 100644 --- a/code/game/machinery/clonepod.dm +++ b/code/game/machinery/clonepod.dm @@ -284,7 +284,6 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ if(grab_ghost_when == CLONER_FRESH_CLONE) clonemind.transfer_to(H) H.ckey = R.ckey - update_clone_antag(H) //Since the body's got the mind, update their antag stuff right now. Otherwise, wait until they get kicked out (as per the CLONER_MATURE_CLONE business) to do it. var/message message += "Consciousness slowly creeps over you as your body regenerates.
" message += "So this is what cloning feels like?" @@ -436,18 +435,6 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ to_chat(user, "A droplet of bananium ooze seeps into the synthmeat storage chamber...") ADD_TRAIT(src, TRAIT_CMAGGED, CLOWN_EMAG) -/obj/machinery/clonepod/proc/update_clone_antag(mob/living/carbon/human/H) - // Check to see if the clone's mind is an antagonist of any kind and handle them accordingly to make sure they get their spells, HUD/whatever else back. - if(H.mind in SSticker.mode.syndicates) - SSticker.mode.update_synd_icons_added() - if(H.mind in SSticker.mode.cult) - SSticker.mode.update_cult_icons_added(H.mind) // Adds the cult antag hud - SSticker.mode.add_cult_actions(H.mind) // And all the actions - if(SSticker.mode.cult_risen) - SSticker.mode.rise(H) - if(SSticker.mode.cult_ascendant) - SSticker.mode.ascend(H) - //Put messages in the connected computer's temp var for display. /obj/machinery/clonepod/proc/connected_message(message) if((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning))) @@ -481,7 +468,6 @@ GLOBAL_LIST_INIT(cloner_biomass_items, list(\ UnregisterSignal(clonemind, COMSIG_MIND_TRANSER_TO) clonemind.transfer_to(occupant) occupant.grab_ghost() - update_clone_antag(occupant) to_chat(occupant, "You remember nothing from the time that you were dead!") to_chat(occupant, "There is a bright flash!
\ You feel like a new being.
") diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index b5ee0089fa4..88c5e23d89c 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -131,6 +131,11 @@ desc = "A label on it reads: Warning: Activating this device will send a high-ordinance EMP explosive to your location." bomb = /obj/machinery/syndicatebomb/emp +/obj/item/radio/beacon/syndicate/bomb/grey_autocloner + desc = "A label on it reads: Warning: Activating this device will send an expensive cloner to your location." + origin_tech = "bluespace=2;syndicate=2" + bomb = /obj/machinery/grey_autocloner + /obj/item/radio/beacon/engine desc = "A label on it reads: Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!." anchored = TRUE //Let's not move these around. Some folk might get the idea to use these for assassinations diff --git a/code/game/objects/items/weapons/implants/implant_prescan.dm b/code/game/objects/items/weapons/implants/implant_prescan.dm new file mode 100644 index 00000000000..0c0eeb714a0 --- /dev/null +++ b/code/game/objects/items/weapons/implants/implant_prescan.dm @@ -0,0 +1,48 @@ +/obj/item/implant/grey_autocloner + name = "technocracy cloning bio-chip" + desc = "Allows for advanced instantanious cloning!" + icon_state = "generic" + origin_tech = "materials=3;combat=5;syndicate=2" + activated = FALSE + trigger_causes = BIOCHIP_TRIGGER_DEATH_ANY + implant_state = "implant-alien" + var/obj/machinery/grey_autocloner/linked + var/datum/dna2/record/our_record + +/obj/item/implant/grey_autocloner/Destroy() + linked = null + our_record = null + return ..() + +/obj/item/implant/grey_autocloner/death_trigger(mob/source, gibbed) + imp_in.ghostize(TRUE) + if(linked) + linked.growclone(our_record) + +/obj/item/implant/grey_autocloner/implant(mob/source, mob/user, force) + if(!linked) + to_chat(user, "Please link the implanter with a Technocracy cloning pod!") + return FALSE + . = ..() + if(!. || !ishuman(imp_in)) + return FALSE + our_record = new /datum/dna2/record() + our_record.ckey = imp_in.ckey + var/obj/item/organ/B = imp_in.get_int_organ(/obj/item/organ/internal/brain) + B.dna.check_integrity() + our_record.dna = B.dna.Clone() + our_record.id = copytext(md5(B.dna.real_name), 2, 6) + our_record.name = B.dna.real_name + our_record.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE + our_record.languages = imp_in.languages + if(imp_in.mind) //Save that mind so traitors can continue traitoring after cloning. + our_record.mind = imp_in.mind.UID() + +/obj/item/implanter/grey_autocloner + name = "bio-chip implanter (Technocracy cloning)" + implant_type = /obj/item/implant/grey_autocloner + +/obj/item/implantcase/grey_autocloner + name = "bio-chip case - 'Technocracy cloning'" + desc = "A glass case containing an Technocracy bio-chip." + implant_type = /obj/item/implant/grey_autocloner diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 5dd3b61997c..d2e8d97fb09 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -433,6 +433,13 @@ for(var/i in 1 to 5) new /obj/item/wall_bug(src, camera) +/obj/item/storage/box/syndie_kit/prescan + name = "\improper Technocracy Advanced Cloning System Kit" + +/obj/item/storage/box/syndie_kit/prescan/populate_contents() + new /obj/item/implanter/grey_autocloner(src) + new /obj/item/radio/beacon/syndicate/bomb/grey_autocloner(src) + /obj/item/storage/box/syndie_kit/pen_bomb name = "\improper Pen bomb" diff --git a/code/game/objects/structures/grey_autocloner.dm b/code/game/objects/structures/grey_autocloner.dm new file mode 100644 index 00000000000..f9d94f3cbf5 --- /dev/null +++ b/code/game/objects/structures/grey_autocloner.dm @@ -0,0 +1,131 @@ +/obj/machinery/grey_autocloner + name = "technocracy cloning pod" + desc = "An advanced Technocracy cloning pod, used for rapid cloning. Very delicate, very power hungry, and very much should not be tampered with." + icon = 'icons/obj/abductor.dmi' + icon_state = "experiment-open" + anchored = TRUE + density = TRUE + var/mob/living/carbon/human/occupant + var/datum/gas_mixture/air_contents + var/list/brine_types = list("corazone", "perfluorodecalin", "epinephrine", "salglu_solution") //Taken from cloner, a bit of extra healing though they should be fully good. + var/datum/mind/clonemind + /// If the clone pod is cloning someone, attempting becomes true, so only one person can clone at a time. False otherwise. + var/attempting = FALSE + +/obj/machinery/grey_autocloner/Initialize(mapload) + . = ..() + air_contents = new() + air_contents.oxygen = MOLES_O2STANDARD * 2 + air_contents.nitrogen = MOLES_N2STANDARD + air_contents.temperature = T20C + +/obj/machinery/grey_autocloner/Destroy() //These will only be not null if deleted with someone in it + occupant = null + clonemind = null + return ..() + +/obj/machinery/grey_autocloner/attackby(obj/item/implanter/implant, mob/user, params) + if(!istype(implant) || !(istype(implant.imp, /obj/item/implant/grey_autocloner))) + return ..() + var/obj/item/implant/grey_autocloner/autoclone = implant.imp + autoclone.linked = src + atom_say("Link confirmed!") + +/obj/machinery/grey_autocloner/proc/growclone(datum/dna2/record/R) + if(attempting || stat & (NOPOWER|BROKEN)) + return FALSE + clonemind = locateUID(R.mind) + if(!istype(clonemind)) //not a mind + return FALSE + if(clonemind.current && clonemind.current.stat != DEAD) //mind is associated with a non-dead body + return FALSE + if(clonemind.active) //somebody is using that mind + if(ckey(clonemind.key) != R.ckey) + return FALSE + if(clonemind.suicided) // Nah, if you are being dragged to the borg factory, that's on you + return FALSE + else + // get_ghost() will fail if they're unable to reenter their body + var/mob/dead/observer/G = clonemind.get_ghost() + if(!G) + return FALSE + + attempting = TRUE //One at a time!! + + if(!R.dna) + R.dna = new /datum/dna() + + var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) + H.set_species(/datum/species/grey) //This is a grey cloner after all. Funnier this way tbh + occupant = H + + if(!R.dna.real_name) //to prevent null names + R.dna.real_name = H.real_name + else + H.real_name = R.dna.real_name + + H.dna = R.dna.Clone() + + for(var/datum/language/L in R.languages) + H.add_language(L.name) + + domutcheck(H, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them + + H.dna.UpdateSE() + H.dna.UpdateUI() + + H.sync_organ_dna(TRUE) // It's literally a fresh body as you can get, so all organs properly belong to it + H.UpdateAppearance() + + H.Paralyse(8 SECONDS) + + clonemind.transfer_to(H) //INSTANTLY INTO THE CLONE + H.ckey = R.ckey + to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
") + + update_icon() + + H.suiciding = FALSE + attempting = FALSE + addtimer(CALLBACK(src, PROC_REF(finish_clone)), 1 MINUTES) + return TRUE + +/obj/machinery/grey_autocloner/process() + if(stat & NOPOWER) //explode if power is lost and cloning + if(occupant) + messy_explode() + return + + else if(occupant?.loc == src) + occupant.Paralyse(8 SECONDS) + if(!use_power(15000)) //Hope the room has power! + return + for(var/bt in brine_types) + if(occupant.reagents.get_reagent_amount(bt) < 1) + occupant.reagents.add_reagent(bt, 1) + +/obj/machinery/grey_autocloner/proc/finish_clone() + playsound(get_turf(src), 'sound/machines/ding.ogg', 50, TRUE) + var/obj/item/organ/internal/storedorgan = new /obj/item/organ/internal/cyberimp/brain/speech_translator + storedorgan.insert(occupant) //insert stored organ into the user + occupant.forceMove(get_turf(src)) + occupant.update_body() + domutcheck(occupant) //Waiting until they're out before possible notransform. + occupant.special_post_clone_handling() + occupant = null + update_icon() + +/obj/machinery/grey_autocloner/emp_act(severity) + messy_explode() + +/obj/machinery/grey_autocloner/proc/messy_explode() + if(occupant) + occupant.forceMove(get_turf(src)) + explosion(get_turf(src), 1, 2, 4, flame_range = 2) + qdel(src) + +/obj/machinery/grey_autocloner/deconstruct(disassembled) + messy_explode() + +/obj/machinery/grey_autocloner/update_icon_state() + icon_state = occupant ? "experiment" : "experiment-open" diff --git a/paradise.dme b/paradise.dme index d4d940bc2e3..4e0a73814d8 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1130,6 +1130,7 @@ #include "code\game\objects\items\weapons\implants\implant_health.dm" #include "code\game\objects\items\weapons\implants\implant_krav_maga.dm" #include "code\game\objects\items\weapons\implants\implant_mindshield.dm" +#include "code\game\objects\items\weapons\implants\implant_prescan.dm" #include "code\game\objects\items\weapons\implants\implant_sad_trombone.dm" #include "code\game\objects\items\weapons\implants\implant_stealth.dm" #include "code\game\objects\items\weapons\implants\implant_storage.dm" @@ -1183,6 +1184,7 @@ #include "code\game\objects\structures\flora.dm" #include "code\game\objects\structures\fluff.dm" #include "code\game\objects\structures\girders.dm" +#include "code\game\objects\structures\grey_autocloner.dm" #include "code\game\objects\structures\grille.dm" #include "code\game\objects\structures\guillotine.dm" #include "code\game\objects\structures\holosigns.dm"