diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm
index cabc67f6..8548b2be 100644
--- a/code/__DEFINES/logging.dm
+++ b/code/__DEFINES/logging.dm
@@ -35,7 +35,6 @@
#define LOG_GAME (1 << 12)
#define LOG_ADMIN_PRIVATE (1 << 13)
#define LOG_ASAY (1 << 14)
-#define LOG_CLONING (1 << 15)
//Individual logging panel pages
#define INDIVIDUAL_ATTACK_LOG (LOG_ATTACK)
diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm
index 0edb4239..ec719794 100644
--- a/code/__DEFINES/machines.dm
+++ b/code/__DEFINES/machines.dm
@@ -100,10 +100,6 @@
#define NUKE_ON_TIMING 2
#define NUKE_ON_EXPLODING 3
-//cloning defines. These are flags.
-#define CLONING_SUCCESS (1<<0)
-#define CLONING_DELETE_RECORD (1<<1)
-
//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified.
#define PLANT_GENE_REMOVABLE (1<<0)
#define PLANT_GENE_EXTRACTABLE (1<<1)
diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index b6b4efa0..30740956 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -58,10 +58,6 @@
if (CONFIG_GET(flag/log_game))
WRITE_LOG(GLOB.world_game_log, "GAME: [text]")
-/proc/log_cloning(text, mob/initiator)
- if(CONFIG_GET(flag/log_cloning))
- WRITE_LOG(GLOB.world_cloning_log, "CLONING: [text]")
-
/proc/log_access(text)
if (CONFIG_GET(flag/log_access))
WRITE_LOG(GLOB.world_game_log, "ACCESS: [text]")
diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm
index bf4ff55f..deffd25b 100644
--- a/code/_globalvars/logging.dm
+++ b/code/_globalvars/logging.dm
@@ -26,8 +26,6 @@ GLOBAL_VAR(query_debug_log)
GLOBAL_PROTECT(query_debug_log)
GLOBAL_VAR(world_job_debug_log)
GLOBAL_PROTECT(world_job_debug_log)
-GLOBAL_VAR(world_cloning_log)
-GLOBAL_PROTECT(world_cloning_log)
GLOBAL_LIST_EMPTY(bombers)
GLOBAL_PROTECT(bombers)
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index 3f767433..356b86f9 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -39,8 +39,6 @@
/datum/config_entry/flag/log_game // log game events
-/datum/config_entry/flag/log_cloning // log cloning actions.
-
/datum/config_entry/flag/log_vote // log voting
/datum/config_entry/flag/log_whisper // log client whisper
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 466a5406..43ec9e54 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -371,7 +371,7 @@
updateappearance(icon_update=0)
if(LAZYLEN(mutation_index))
- dna.mutation_index = mutation_index.Copy()
+ dna.mutation_index = mutation_index
domutcheck()
if(mrace || newfeatures || ui)
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 5dd0b34d..f633b5cf 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -62,9 +62,6 @@
var/unconvertable = FALSE
var/late_joiner = FALSE
- var/last_death = 0
-
-
var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator
var/list/learned_recipes //List of learned recipe TYPES.
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 78953609..9e8756bb 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -598,14 +598,6 @@
/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 a70c1068..855ede0e 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -19,7 +19,7 @@
circuit = /obj/item/circuitboard/machine/clonepod
var/heal_level //The clone is released once its health reaches this level.
- var/obj/machinery/computer/cloning/connected //So we remember the connected clone machine.
+ 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/speed_coeff
@@ -53,10 +53,7 @@
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)
@@ -77,23 +74,6 @@
if(heal_level > 100)
heal_level = 100
-/obj/machinery/clonepod/attack_hand(mob/user)
- . = ..()
- if(.)
- return
- user.examinate(src)
-
-/obj/machinery/clonepod/attack_ai(mob/user)
- return attack_hand(user)
-
-/obj/machinery/clonepod/examine(mob/user)
- . = ..()
- . += "The linking device can be scanned with a multitool."
- if(in_range(user, src) || isobserver(user))
- . += "The status display reads: Cloning speed at [speed_coeff*50]%.
Predicted amount of cellular damage: [100-heal_level]%."
- if(efficiency > 5)
- . += "Pod has been upgraded to support autoprocessing and apply beneficial mutations."
-
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
/obj/item/disk/data
@@ -122,7 +102,7 @@
//Clonepod
/obj/machinery/clonepod/examine(mob/user)
- . = ..()
+ ..()
var/mob/living/mob_occupant = occupant
if(mess)
to_chat(user, "It's filled with blood and viscera. You swear you can see it moving...")
@@ -149,54 +129,44 @@
return examine(user)
//Start growing a human clone in the pod!
-/obj/machinery/clonepod/proc/growclone(clonename, ui, mutation_index, mindref, last_death, blood_type, datum/species/mrace, list/features, factions, list/quirks, empty)
+/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, mutation_index, mindref, datum/species/mrace, list/features, factions, list/quirks)
if(panel_open)
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
+ clonemind = locate(mindref) in SSticker.minds
+ if(!istype(clonemind)) //not a mind
+ return FALSE
+ if(!QDELETED(clonemind.current))
+ if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body
return FALSE
- if(clonemind.last_death != last_death) //The soul has advanced, the record has not.
+ if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding.
return FALSE
- if(!QDELETED(clonemind.current))
- if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body
- return NONE
- if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding.
- return NONE
- if(!clonemind.active)
- // get_ghost() will fail if they're unable to reenter their body
- var/mob/dead/observer/G = clonemind.get_ghost()
- if(!G)
- return NONE
- if(G.suiciding) // The ghost came from a body that is suiciding.
- return NONE
- if(clonemind.damnation_type) //Can't clone the damned.
- INVOKE_ASYNC(src, .proc/horrifyingsound)
- mess = TRUE
- icon_state = "pod_g"
- update_icon()
+ if(clonemind.active) //somebody is using that mind
+ if( ckey(clonemind.key)!=ckey )
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
+ if(G.suiciding) // The ghost came from a body that is suiciding.
+ return FALSE
+ if(clonemind.damnation_type) //Can't clone the damned.
+ INVOKE_ASYNC(src, .proc/horrifyingsound)
+ mess = TRUE
+ update_icon()
+ return FALSE
attempting = TRUE //One at a time!!
countdown.start()
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
- H.hardset_dna(ui, mutation_index, H.real_name, blood_type, mrace, features)
+ H.hardset_dna(ui, mutation_index, H.real_name, null, mrace, features)
- 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
+ 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.
H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment.
occupant = H
@@ -214,16 +184,15 @@
ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning")
H.Unconscious(80)
- if(!empty)
- clonemind.transfer_to(H)
+ clonemind.transfer_to(H)
- if(grab_ghost_when == CLONER_FRESH_CLONE)
- H.grab_ghost()
- to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?")
+ if(grab_ghost_when == CLONER_FRESH_CLONE)
+ H.grab_ghost()
+ to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?")
- if(grab_ghost_when == CLONER_MATURE_CLONE)
- H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
- to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.")
+ if(grab_ghost_when == CLONER_MATURE_CLONE)
+ H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost
+ to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.")
if(H)
H.faction |= factions
@@ -237,7 +206,7 @@
H.suiciding = FALSE
attempting = FALSE
- return CLONING_SUCCESS
+ return TRUE
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
@@ -246,20 +215,16 @@
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 && (mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes.
+ if((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))
@@ -307,13 +272,10 @@
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()
@@ -328,8 +290,6 @@
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))
@@ -356,13 +316,10 @@
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 ..()
@@ -372,9 +329,6 @@
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)
@@ -427,7 +381,6 @@
unattached_flesh.Cut()
occupant = null
- clonemind = null
/obj/machinery/clonepod/proc/malfunction()
var/mob/living/mob_occupant = occupant
@@ -438,14 +391,13 @@
mess = TRUE
maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet
update_icon()
- if(clonemind && mob_occupant.mind != clonemind)
+ if(mob_occupant.mind != clonemind)
clonemind.transfer_to(mob_occupant)
mob_occupant.grab_ghost() // We really just want to make you suffer.
flash_color(mob_occupant, flash_color="#960000", flash_time=100)
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)
@@ -464,14 +416,11 @@
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) && occupant)
- var/mob/living/mob_occupant = occupant
+ if(!QDELETED(src))
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)
@@ -487,9 +436,7 @@
/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)
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index dede5724..039152f5 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -7,24 +7,25 @@
icon_keyboard = "med_key"
circuit = /obj/item/circuitboard/computer/cloning
req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW.
- var/obj/machinery/dna_scannernew/scanner //Linked scanner. For scanning.
+ var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
var/list/pods //Linked cloning pods
var/temp = "Inactive"
var/scantemp_ckey
var/scantemp = "Ready to Scan"
var/menu = 1 //Which menu screen to display
- var/list/records = list()
var/datum/data/record/active_record = null
var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything.
-
var/loading = 0 // Nice loading text
var/autoprocess = 0
+ var/list/records = list()
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/cloning/Initialize()
. = ..()
updatemodules(TRUE)
+ var/obj/item/circuitboard/computer/cloning/board = circuit
+ records = board.records
/obj/machinery/computer/cloning/Destroy()
@@ -38,7 +39,7 @@
if(pods)
for(var/P in pods)
var/obj/machinery/clonepod/pod = P
- if(pod.occupant && mind && pod.clonemind == mind)
+ if(pod.occupant && pod.clonemind == mind)
return null
if(pod.is_operational() && !(pod.occupant || pod.mess))
return pod
@@ -59,9 +60,6 @@
else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5)
. = pod
-/proc/grow_clone_from_record(obj/machinery/clonepod/pod, datum/data/record/R, empty)
- return pod.growclone(R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mindref"], R.fields["last_death"], R.fields["blood_type"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"], empty)
-
/obj/machinery/computer/cloning/process()
if(!(scanner && LAZYLEN(pods) && autoprocess))
return
@@ -70,19 +68,16 @@
scan_occupant(scanner.occupant)
for(var/datum/data/record/R in records)
- var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mindref"])
+ var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"])
if(!pod)
return
if(pod.occupant)
- continue
+ continue //how though?
- var/result = grow_clone_from_record(pod, R)
- if(result & CLONING_SUCCESS)
+ if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"], R.fields["quirks"]))
temp = "[R.fields["name"]] => Cloning cycle in progress..."
- log_cloning("Cloning of [key_name(R.fields["mindref"])] automatically started via autoprocess - [src] at [AREACOORD(src)]. Pod: [pod] at [AREACOORD(pod)].")
- if(result & CLONING_DELETE_RECORD)
records -= R
/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner)
@@ -137,9 +132,7 @@
to_chat(user, "You insert [W].")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
src.updateUsrDialog()
- else if(W.tool_behaviour == TOOL_MULTITOOL)
- if(!multitool_check_buffer(user, W))
- return
+ else if(istype(W, /obj/item/multitool))
var/obj/item/multitool/P = W
if(istype(P.buffer, /obj/machinery/clonepod))
@@ -208,7 +201,6 @@
if(scanner_occupant)
dat += "Start Scan"
- dat += "Body-Only Scan"
dat += "
[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]"
else
dat += "Start Scan"
@@ -236,11 +228,8 @@
if (!src.active_record)
dat += "Record not found."
else
- var/body_only = active_record.fields["body_only"]
- dat += "