diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index b3957234d01..70c955c2169 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -5,6 +5,9 @@
#define CLONE_BIOMASS 150
#define BIOMASS_MEAT_AMOUNT 50
+#define MINIMUM_HEAL_LEVEL 40
+#define CLONE_INITIAL_DAMAGE 190
+#define BRAIN_INITIAL_DAMAGE 90 // our minds are too feeble for 190
/obj/machinery/clonepod
anchored = 1
@@ -15,12 +18,10 @@
icon_state = "pod_0"
req_access = list(access_genetics) //For premature unlocking.
var/mob/living/carbon/human/occupant
- var/heal_level = 90 //The clone is released once its health reaches this level.
- var/locked = 0
+ var/heal_level //The clone is released once its health reaches this level.
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
var/mess = 0 //Need to clean out it if it's full of exploded clone.
var/attempting = 0 //One clone attempt at a time thanks
- var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
var/biomass = 0
var/speed_coeff
var/efficiency
@@ -33,6 +34,9 @@
var/obj/effect/countdown/clonepod/countdown
+ var/list/missing_organs
+ var/organs_number = 0
+
light_color = LIGHT_COLOR_PURE_GREEN
/obj/machinery/clonepod/power_change()
@@ -82,8 +86,21 @@
/obj/machinery/clonepod/Destroy()
if(connected)
connected.pods -= src
+<<<<<<< HEAD
QDEL_NULL(Radio)
QDEL_NULL(countdown)
+=======
+ if(Radio)
+ qdel(Radio)
+ Radio = null
+ if(countdown)
+ qdel(countdown)
+ countdown = null
+ for(var/i in missing_organs)
+ qdel(i)
+ LAZYCLEARLIST(missing_organs)
+ missing_organs = null
+>>>>>>> Cloning now puts you together bit by bit
return ..()
/obj/machinery/clonepod/RefreshParts()
@@ -93,7 +110,7 @@
efficiency += S.rating
for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts)
speed_coeff += P.rating
- heal_level = min((efficiency * 15) + 10, 100)
+ heal_level = max(min((efficiency * 15) + 10, 100), MINIMUM_HEAL_LEVEL)
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
@@ -217,19 +234,21 @@
if(!G)
return 0
+/*
+ if(clonemind.damnation_type) //Can't clone the damned.
+ playsound('sound/hallucinations/veryfar_noise.ogg', 50, 0)
+ malfunction()
+ return -1 // so that the record gets flushed out
+ */
+
if(biomass >= CLONE_BIOMASS)
biomass -= CLONE_BIOMASS
else
return 0
attempting = 1 //One at a time!!
- locked = 1
countdown.start()
- eject_wait = 1
- spawn(30)
- eject_wait = 0
-
if(!R.dna)
R.dna = new /datum/dna()
@@ -246,9 +265,23 @@
for(var/datum/language/L in R.languages)
H.add_language(L.name)
+ domutcheck(H, null, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them
+
+ if(efficiency > 2 && efficiency < 5 && prob(25))
+ randmutb(H)
+ if(efficiency > 5 && prob(20))
+ randmutg(H)
+ if(efficiency < 3 && prob(50))
+ randmutb(H)
+
+ H.dna.UpdateSE()
+ H.dna.UpdateUI()
+
+ H.sync_organ_dna(1) // It's literally a fresh body as you can get, so all organs properly belong to it
+ H.UpdateAppearance()
+
//Get the clone body ready
- H.adjustCloneLoss(190) //new damage var so you can't eject a clone early then stab them to abuse the current damage system --NeoFite
- H.adjustBrainLoss(90) // The rand(10, 30) will come out as extra brain damage
+ maim_clone(H)
H.Paralyse(4)
//Here let's calculate their health so the pod doesn't immediately eject them!!!
@@ -266,21 +299,6 @@
beginning to regenerate in a cloning pod. You will
become conscious when it is complete."})
- domutcheck(H, null, MUTCHK_FORCED) //Ensures species that get powers by the species proc handle_dna keep them
-
- if(efficiency > 2 && efficiency < 5 && prob(25))
- randmutb(H)
- if(efficiency > 5 && prob(20))
- randmutg(H)
- if(efficiency < 3 && prob(50))
- randmutb(H)
-
- H.dna.UpdateSE()
- H.dna.UpdateUI()
-
- H.sync_organ_dna(1) // It's literally a fresh body as you can get, so all organs properly belong to it
- H.UpdateAppearance()
-
update_icon()
H.suiciding = 0
@@ -299,13 +317,11 @@
if(stat & NOPOWER) //Autoeject if power is lost
if(occupant)
- locked = 0
go_out()
connected_message("Clone Ejected: Loss of power.")
else if((occupant) && (occupant.loc == src))
if((occupant.stat == DEAD) || (occupant.suiciding)) //Autoeject corpses and suiciding dudes.
- locked = 0
announce_radio_message("The cloning of [occupant] has been aborted due to unrecoverable tissue failure.")
go_out()
connected_message("Clone Rejected: Deceased.")
@@ -316,6 +332,15 @@
//Slowly get that clone healed and finished.
occupant.adjustCloneLoss(-((speed_coeff/2)))
+ var/progress = CLONE_INITIAL_DAMAGE - occupant.getCloneLoss()
+ progress += (100 - MINIMUM_HEAL_LEVEL)
+ var/milestone = CLONE_INITIAL_DAMAGE / organs_number
+ var/installed = organs_number - LAZYLEN(missing_organs)
+
+ while((progress / milestone) > installed && LAZYLEN(missing_organs))
+ var/obj/item/organ/I = pick_n_take(missing_organs)
+ I.replaced(occupant)
+
//Premature clones may have brain damage.
occupant.adjustBrainLoss(-((speed_coeff/20)*efficiency))
@@ -328,22 +353,19 @@
use_power(7500) //This might need tweaking.
- else if((occupant.cloneloss <= (100 - heal_level)) && (!eject_wait))
+ else if((occupant.cloneloss <= (100 - heal_level)))
connected_message("Cloning Process Complete.")
announce_radio_message("The cloning cycle of [occupant] is complete.")
- locked = 0
go_out()
else if((!occupant) || (occupant.loc != src))
occupant = null
- if(locked)
- locked = 0
update_icon()
use_power(200)
//Let's unlock this early I guess. Might be too early, needs tweaking.
/obj/machinery/clonepod/attackby(obj/item/weapon/W, mob/user, params)
- if(!(occupant || mess || locked))
+ if(!(occupant || mess))
if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]", W))
return
@@ -357,14 +379,14 @@
if(!check_access(W))
to_chat(user, "Access Denied.")
return
- if (!locked || !occupant)
- return
- if(occupant.health < -20 && occupant.stat != DEAD)
- to_chat(user, "Access Refused. Patient status still unstable.")
+ if(!(occupant || mess))
+ to_chat(user, "Error: Pod has no occupant.")
return
else
- locked = 0
- to_chat(user, "System unlocked.")
+ connected_message("Authorized Ejection")
+ announce_radio_message("An authorized ejection of [occupant.real_name] has occured")
+ to_chat(user, "You force an emergency ejection.")
+ go_out()
//Removing cloning pod biomass
else if(istype(W, /obj/item/weapon/reagent_containers/food/snacks/meat))
@@ -374,7 +396,7 @@
qdel(W)
return
else if(istype(W, /obj/item/weapon/wrench))
- if(locked && (anchored || occupant))
+ if(occupant)
to_chat(user, "Can not do that while [src] is in use.")
else
if(anchored)
@@ -399,8 +421,6 @@
/obj/machinery/clonepod/emag_act(user)
if(isnull(occupant))
return
- to_chat(user, "You force an emergency ejection.")
- locked = 0
go_out()
/obj/machinery/clonepod/proc/update_clone_antag(var/mob/living/carbon/human/H)
@@ -435,21 +455,7 @@
connected.updateUsrDialog()
return 1
-/obj/machinery/clonepod/verb/eject()
- set name = "Eject Cloner"
- set category = "Object"
- set src in oview(1)
-
- if(!usr)
- return
- if(usr.incapacitated())
- return
- go_out()
- add_fingerprint(usr)
-
/obj/machinery/clonepod/proc/go_out()
- if(locked)
- return
countdown.stop()
if(mess) //Clean that mess and dump those gibs!
@@ -470,8 +476,11 @@
You feel like a new being.")
occupant.flash_eyes(visual = 1)
+ for(var/i in missing_organs)
+ qdel(i)
+ missing_organs.Cut()
occupant.forceMove(get_turf(src))
- eject_wait = 0 //If it's still set somehow.
+ occupant.update_body()
domutcheck(occupant) //Waiting until they're out before possible notransform.
occupant.shock_stage = 0 //Reset Shock
occupant = null
@@ -481,19 +490,24 @@
if(occupant)
connected_message("Critical Error!")
announce_radio_message("Critical error! Please contact a Thinktronic Systems technician, as your warranty may be affected.")
- mess = 1
- update_icon()
if(occupant.mind != clonemind)
clonemind.transfer_to(occupant)
occupant.grab_ghost() // We really just want to make you suffer.
to_chat(occupant, {"Agony blazes across your
consciousness as your body is torn apart.
Is this what dying is like? Yes it is."})
- playsound(loc, 'sound/machines/warning-buzzer.ogg', 50, 0)
occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)
+ for(var/i in missing_organs)
+ qdel(i)
+ missing_organs.Cut()
spawn(40)
qdel(occupant)
+
+ playsound(loc, 'sound/machines/warning-buzzer.ogg', 50, 0)
+ mess = TRUE
+ update_icon()
+
/obj/machinery/clonepod/update_icon()
..()
icon_state = "pod_0"
@@ -535,6 +549,33 @@
else
return
+/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H)
+ LAZYINITLIST(missing_organs)
+ for(var/i in missing_organs)
+ qdel(i)
+ missing_organs.Cut()
+
+ H.setCloneLoss(CLONE_INITIAL_DAMAGE)
+ H.setBrainLoss(BRAIN_INITIAL_DAMAGE)
+
+ for(var/o in H.internal_organs)
+ var/obj/item/organ/O = o
+ if(!istype(O) || O.vital)
+ continue
+ var/obj/item/I = O.remove(H, TRUE)
+ // Make this support stuff that turns into items when removed
+ I.forceMove(src)
+ missing_organs += I
+
+ var/static/list/zones = list("r_arm", "l_arm", "r_leg", "l_leg")
+ for(var/zone in zones)
+ var/obj/item/organ/external/E = H.get_organ(zone)
+ var/obj/item/I = E.remove(H, TRUE)
+ I.forceMove(src)
+ missing_organs += I
+
+ organs_number = LAZYLEN(missing_organs)
+
/*
* Diskette Box
*/
@@ -586,3 +627,5 @@
if(istype(A, /obj/machinery/clonepod))
A:malfunction()
*/
+
+#undef MINIMUM_HEAL_LEVEL
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 0d47420edc9..c1a115e8d96 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -310,6 +310,7 @@
temp = "Error: No cloning pod detected."
else
var/obj/machinery/clonepod/pod = selected_pod
+ var/cloneresult
if(!selected_pod)
temp = "Error: No cloning pod selected."
else if(pod.occupant)
@@ -320,13 +321,16 @@
temp = "Error: The cloning pod is malfunctioning."
else if(!config.revival_cloning)
temp = "Error: Unable to initiate cloning cycle."
- else if(pod.growclone(C))
- temp = "Initiating cloning cycle..."
- records.Remove(C)
- qdel(C)
- menu = 1
else
- temp = "[C.name] => Initialisation failure."
+ cloneresult = pod.growclone(C)
+ if(cloneresult)
+ if(cloneresult > 0)
+ temp = "Initiating cloning cycle..."
+ records.Remove(C)
+ qdel(C)
+ menu = 1
+ else
+ temp = "[C.name] => Initialisation failure."
else
temp = "Error: Data corruption."
diff --git a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
index 2cacdc4801e..a4a52b3ea5f 100644
--- a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
+++ b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
@@ -191,7 +191,6 @@ datum/genesequence
visible_message("[bicon(src)] [src] clones something from a reconstituted gene sequence!")
playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3)
pod1.occupant = new cloned_genesequence.spawned_type(pod1)
- pod1.locked = 1
pod1.icon_state = "pod_1"
//pod1.occupant.name = "[pod1.occupant.name] ([rand(0,999)])"
pod1.biomass -= CLONE_BIOMASS
diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm
index dd0c9655384..084e16f877e 100644
--- a/code/modules/surgery/organs/organ.dm
+++ b/code/modules/surgery/organs/organ.dm
@@ -316,18 +316,8 @@ var/list/organ_cache = list()
owner = null
return src
-/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
-
- if(!istype(target)) return
-
- owner = target
- processing_objects -= src
- affected.internal_organs |= src
- if(!target.get_int_organ(src))
- target.internal_organs += src
- loc = target
- if(robotic)
- status |= ORGAN_ROBOT
+/obj/item/organ/proc/replaced(var/mob/living/carbon/human/target)
+ return // Nothing uses this, it is always overridden
/obj/item/organ/proc/surgeryize()
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 6c775862373..7a87d3c6b39 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -74,9 +74,8 @@
A.Remove(M)
return src
-/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
+/obj/item/organ/internal/replaced(var/mob/living/carbon/human/target)
insert(target)
- ..()
/obj/item/organ/internal/item_action_slot_check(slot, mob/user)
return