[MIRROR] Resleeving console uses weakrefs, and synthfab fix (#11269)

Co-authored-by: Will <7099514+Willburd@users.noreply.github.com>
This commit is contained in:
Selis
2025-07-30 14:19:17 +02:00
committed by GitHub
parent 80138172f9
commit f50e7109be
3 changed files with 81 additions and 55 deletions

View File

@@ -16,9 +16,7 @@
var/list/sleevers = null //Linked resleeving booths. var/list/sleevers = null //Linked resleeving booths.
var/list/temp = null var/list/temp = null
var/menu = MENU_MAIN //Which menu screen to display var/menu = MENU_MAIN //Which menu screen to display
var/datum/transhuman/body_record/active_br = null
var/can_grow_active = FALSE var/can_grow_active = FALSE
var/datum/transhuman/mind_record/active_mr = null
var/can_sleeve_active = FALSE var/can_sleeve_active = FALSE
var/organic_capable = 1 var/organic_capable = 1
var/synthetic_capable = 1 var/synthetic_capable = 1
@@ -27,6 +25,8 @@
var/obj/machinery/transhuman/synthprinter/selected_printer var/obj/machinery/transhuman/synthprinter/selected_printer
var/obj/machinery/transhuman/resleever/selected_sleever var/obj/machinery/transhuman/resleever/selected_sleever
var/datum/weakref/current_br
var/datum/weakref/current_mr
// Resleeving database this machine interacts with. Blank for default database // Resleeving database this machine interacts with. Blank for default database
// Needs a matching /datum/transcore_db with key defined in code // Needs a matching /datum/transcore_db with key defined in code
@@ -105,10 +105,10 @@
return return
user.unEquip(W) user.unEquip(W)
W.forceMove(get_turf(src)) // Drop on top of us W.forceMove(get_turf(src)) // Drop on top of us
active_br = new /datum/transhuman/body_record(brDisk.stored) // Loads a COPY! current_br = WEAKREF(brDisk.stored)
to_chat(user, span_notice("\The [src] loads the body record from \the [W] before ejecting it.")) to_chat(user, span_notice("\The [src] loads the body record from \the [W] before ejecting it."))
attack_hand(user) attack_hand(user)
view_b_rec(REF(active_br)) view_b_rec(REF(brDisk.stored))
else else
..() ..()
return return
@@ -209,6 +209,7 @@
data["mindrecords"] = mindrecords_list_ui data["mindrecords"] = mindrecords_list_ui
data["active_b_rec"] = null data["active_b_rec"] = null
var/datum/transhuman/body_record/active_br = current_br?.resolve()
if(active_br) if(active_br)
data["active_b_rec"] = list( data["active_b_rec"] = list(
activerecord = REF(active_br), activerecord = REF(active_br),
@@ -222,6 +223,7 @@
) )
data["active_m_rec"] = null data["active_m_rec"] = null
var/datum/transhuman/mind_record/active_mr = current_mr?.resolve()
if(active_mr) if(active_mr)
data["active_m_rec"] = list( data["active_m_rec"] = list(
activerecord = REF(active_mr), activerecord = REF(active_mr),
@@ -243,28 +245,31 @@
view_b_rec(params["ref"]) view_b_rec(params["ref"])
. = TRUE . = TRUE
if("clear_b_rec") if("clear_b_rec")
active_br = null current_br = null
. = TRUE . = TRUE
if("view_m_rec") if("view_m_rec")
view_m_rec(params["ref"]) view_m_rec(params["ref"])
. = TRUE . = TRUE
if("clear_m_rec") if("clear_m_rec")
active_mr = null current_mr = null
. = TRUE . = TRUE
if("coredump") if("coredump")
if(disk) if(disk)
our_db.core_dump(disk) our_db.core_dump(disk)
sleep(5) sleep(5)
visible_message(span_warning("\The [src] spits out \the [disk].")) visible_message(span_warning("\The [src] spits out \the [disk]."))
current_br = null
disk.forceMove(get_turf(src)) disk.forceMove(get_turf(src))
disk = null disk = null
. = TRUE . = TRUE
if("ejectdisk") if("ejectdisk")
current_br = null
disk.forceMove(get_turf(src)) disk.forceMove(get_turf(src))
disk = null disk = null
. = TRUE . = TRUE
if("create") if("create")
. = TRUE . = TRUE
var/datum/transhuman/body_record/active_br = current_br?.resolve()
if(istype(active_br)) if(istype(active_br))
//Tried to grow a synth but no synth pods. //Tried to grow a synth but no synth pods.
if(active_br.synthetic && !spods.len) if(active_br.synthetic && !spods.len)
@@ -279,39 +284,39 @@
var/obj/machinery/transhuman/synthprinter/spod = selected_printer var/obj/machinery/transhuman/synthprinter/spod = selected_printer
if(!istype(spod)) if(!istype(spod))
set_temp("Error: No SynthFab selected.", "danger") set_temp("Error: No SynthFab selected.", "danger")
active_br = null current_br = null
return return
//Already doing someone. //Already doing someone.
if(spod.busy) if(spod.busy)
set_temp("Error: SynthFab is currently busy.", "danger") set_temp("Error: SynthFab is currently busy.", "danger")
active_br = null current_br = null
return return
//Not enough steel or glass //Not enough steel or glass
else if(spod.stored_material[MAT_STEEL] < spod.body_cost) else if(spod.stored_material[MAT_STEEL] < spod.body_cost)
set_temp("Error: Not enough [MAT_STEEL] in SynthFab.", "danger") set_temp("Error: Not enough [MAT_STEEL] in SynthFab.", "danger")
active_br = null current_br = null
return return
else if(spod.stored_material[MAT_GLASS] < spod.body_cost) else if(spod.stored_material[MAT_GLASS] < spod.body_cost)
set_temp("Error: Not enough glass in SynthFab.", "danger") set_temp("Error: Not enough glass in SynthFab.", "danger")
active_br = null current_br = null
return return
//Gross pod (broke mid-cloning or something). //Gross pod (broke mid-cloning or something).
else if(spod.broken) else if(spod.broken)
set_temp("Error: SynthFab malfunction.", "danger") set_temp("Error: SynthFab malfunction.", "danger")
active_br = null current_br = null
return return
//Do the cloning! //Do the cloning!
else if(spod.print(active_br)) else if(spod.print(current_br))
set_temp("Initiating printing cycle...", "success") set_temp("Initiating printing cycle...", "success")
active_br = null current_br = null
menu = 1 menu = 1
else else
set_temp("Initiating printing cycle... Error: Post-initialisation failed. Printing cycle aborted.", "danger") set_temp("Initiating printing cycle... Error: Post-initialisation failed. Printing cycle aborted.", "danger")
active_br = null current_br = null
return return
//We're cloning an organic. //We're cloning an organic.
@@ -319,58 +324,59 @@
var/obj/machinery/clonepod/transhuman/pod = selected_pod var/obj/machinery/clonepod/transhuman/pod = selected_pod
if(!istype(pod)) if(!istype(pod))
set_temp("Error: No clonepod selected.", "danger") set_temp("Error: No clonepod selected.", "danger")
active_br = null current_br = null
return return
//Already doing someone. //Already doing someone.
if(pod.get_occupant()) if(pod.get_occupant())
set_temp("Error: Growpod is currently occupied.", "danger") set_temp("Error: Growpod is currently occupied.", "danger")
active_br = null current_br = null
return return
//Not enough materials. //Not enough materials.
else if(pod.get_biomass() < CLONE_BIOMASS) else if(pod.get_biomass() < CLONE_BIOMASS)
set_temp("Error: Not enough biomass.", "danger") set_temp("Error: Not enough biomass.", "danger")
active_br = null current_br = null
return return
//Gross pod (broke mid-cloning or something). //Gross pod (broke mid-cloning or something).
else if(pod.mess) else if(pod.mess)
set_temp("Error: Growpod malfunction.", "danger") set_temp("Error: Growpod malfunction.", "danger")
active_br = null current_br = null
return return
//Disabled in config. //Disabled in config.
else if(!CONFIG_GET(flag/revival_cloning)) else if(!CONFIG_GET(flag/revival_cloning))
set_temp("Error: Unable to initiate growing cycle.", "danger") set_temp("Error: Unable to initiate growing cycle.", "danger")
active_br = null current_br = null
return return
//Do the cloning! //Do the cloning!
else if(pod.growclone(active_br)) else if(pod.growclone(active_br))
set_temp("Initiating growing cycle...", "success") set_temp("Initiating growing cycle...", "success")
active_br = null current_br = null
else else
set_temp("Initiating growing cycle... Error: Post-initialisation failed. Growing cycle aborted.", "danger") set_temp("Initiating growing cycle... Error: Post-initialisation failed. Growing cycle aborted.", "danger")
active_br = null current_br = null
return return
//The body record is broken somehow. //The body record is broken somehow.
else else
set_temp("Error: Data corruption.", "danger") set_temp("Error: Data corruption.", "danger")
active_br = null current_br = null
if("sleeve") if("sleeve")
var/datum/transhuman/mind_record/active_mr = current_mr?.resolve()
if(istype(active_mr)) if(istype(active_mr))
. = TRUE . = TRUE
if(!sleevers.len) if(!sleevers.len)
set_temp("Error: No sleevers detected.", "danger") set_temp("Error: No sleevers detected.", "danger")
active_mr = null current_mr = null
else else
var/mode = text2num(params["mode"]) var/mode = text2num(params["mode"])
var/override var/override
var/obj/machinery/transhuman/resleever/sleever = selected_sleever var/obj/machinery/transhuman/resleever/sleever = selected_sleever
if(!istype(sleever)) if(!istype(sleever))
set_temp("Error: No resleeving pod selected.", "danger") set_temp("Error: No resleeving pod selected.", "danger")
active_mr = null current_mr = null
return return
switch(mode) switch(mode)
@@ -378,19 +384,19 @@
//No body to sleeve into. //No body to sleeve into.
if(!sleever.get_occupant()) if(!sleever.get_occupant())
set_temp("Error: Resleeving pod is not occupied.", "danger") set_temp("Error: Resleeving pod is not occupied.", "danger")
active_mr = null current_mr = null
return return
//OOC body lock thing. //OOC body lock thing.
if(sleever.get_occupant().resleeve_lock && active_mr.ckey != sleever.get_occupant().resleeve_lock) if(sleever.get_occupant().resleeve_lock && active_mr.ckey != sleever.get_occupant().resleeve_lock)
set_temp("Error: Mind incompatible with body.", "danger") set_temp("Error: Mind incompatible with body.", "danger")
active_mr = null current_mr = null
return return
//Changeling lock. //Changeling lock.
if(sleever.get_occupant().changeling_locked && !is_changeling(active_mr.mind_ref)) if(sleever.get_occupant().changeling_locked && !is_changeling(active_mr.mind_ref))
set_temp("Error: Mind incompatible with body", "danger") set_temp("Error: Mind incompatible with body", "danger")
active_mr = null current_mr = null
return TRUE return TRUE
var/list/subtargets = list() var/list/subtargets = list()
@@ -403,13 +409,13 @@
override = tgui_input_list(ui.user,"Multiple bodies detected. Select target for resleeving of [active_mr.mindname] manually. Sleeving of primary body is unsafe with sub-contents, and is not listed.", "Resleeving Target", subtargets) override = tgui_input_list(ui.user,"Multiple bodies detected. Select target for resleeving of [active_mr.mindname] manually. Sleeving of primary body is unsafe with sub-contents, and is not listed.", "Resleeving Target", subtargets)
if(!override || oc_sanity != sleever.get_occupant() || !(override in sleever.get_occupant())) if(!override || oc_sanity != sleever.get_occupant() || !(override in sleever.get_occupant()))
set_temp("Error: Target selection aborted.", "danger") set_temp("Error: Target selection aborted.", "danger")
active_mr = null current_mr = null
return return
if(2) //Card resleeving if(2) //Card resleeving
if(sleever.sleevecards <= 0) if(sleever.sleevecards <= 0)
set_temp("Error: No available cards in resleever.", "danger") set_temp("Error: No available cards in resleever.", "danger")
active_mr = null current_mr = null
return return
//Body to sleeve into, but mind is in another living body. //Body to sleeve into, but mind is in another living body.
@@ -419,13 +425,17 @@
//They declined to be moved. //They declined to be moved.
if(answer != "Yes") if(answer != "Yes")
set_temp("Initiating resleeving... Error: Post-initialisation failed. Resleeving cycle aborted.", "danger") set_temp("Initiating resleeving... Error: Post-initialisation failed. Resleeving cycle aborted.", "danger")
active_mr = null current_mr = null
return TRUE return TRUE
//They were dead, or otherwise available. //They were dead, or otherwise available.
sleever.putmind(active_mr,mode,override,db_key = db_key) sleever.putmind(active_mr,mode,override,db_key = db_key)
set_temp("Initiating resleeving...") set_temp("Initiating resleeving...")
active_mr = null current_mr = null
//The mind record is broken somehow.
else
set_temp("Error: Data corruption.", "danger")
current_mr = null
if("selectpod") if("selectpod")
var/ref = params["ref"] var/ref = params["ref"]
@@ -456,6 +466,7 @@
. = TRUE . = TRUE
// Traitgenes edit begin - create a dna injector based off the BR currently selected, to allow normal doctors to reset someone's SEs // Traitgenes edit begin - create a dna injector based off the BR currently selected, to allow normal doctors to reset someone's SEs
if("genereset") if("genereset")
var/datum/transhuman/body_record/active_br = current_br?.resolve()
if(gene_sequencing) if(gene_sequencing)
set_temp("Sequencing Record... Please wait.") set_temp("Sequencing Record... Please wait.")
tgui_modal_clear(src) tgui_modal_clear(src)
@@ -472,6 +483,7 @@
I.has_radiation = FALSE // SAFE! I.has_radiation = FALSE // SAFE!
atom_say("Beginning injector synthesis.") atom_say("Beginning injector synthesis.")
addtimer(CALLBACK(src, PROC_REF(dispense_injector), I), 10 SECONDS, TIMER_DELETE_ME) addtimer(CALLBACK(src, PROC_REF(dispense_injector), I), 10 SECONDS, TIMER_DELETE_ME)
current_br = null
. = TRUE . = TRUE
if("cleartemp") if("cleartemp")
temp = null temp = null
@@ -530,33 +542,42 @@
if(!length(ref)) if(!length(ref))
return return
active_br = locate(ref) var/datum/transhuman/body_record/active_br = locate(ref)
if(istype(active_br)) if(istype(active_br))
can_grow_active = TRUE if(isnull(active_br.mydna))
if(!synthetic_capable && active_br.synthetic) //Disqualified due to being synthetic in an organic only. if(!QDELETED(active_br))
can_grow_active = FALSE qdel(active_br)
set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of synthfabs.", "danger") current_br = null
else if(!organic_capable && !active_br.synthetic) //Disqualified for the opposite. set_temp("Error: Record corrupt.", "danger")
can_grow_active = FALSE else
set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of cloners.", "danger") can_grow_active = TRUE
else if(!synthetic_capable && !organic_capable) //What have you done?? if(!synthetic_capable && active_br.synthetic) //Disqualified due to being synthetic in an organic only.
can_grow_active = FALSE can_grow_active = FALSE
set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of synthfabs and cloners.", "danger") set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of synthfabs.", "danger")
else if(active_br.toocomplex) else if(!organic_capable && !active_br.synthetic) //Disqualified for the opposite.
can_grow_active = FALSE can_grow_active = FALSE
set_temp("Error: Cannot grow [active_br.mydna.name] due to species complexity.", "danger") set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of cloners.", "danger")
else if(!synthetic_capable && !organic_capable) //What have you done??
can_grow_active = FALSE
set_temp("Error: Cannot grow [active_br.mydna.name] due to lack of synthfabs and cloners.", "danger")
else if(active_br.toocomplex)
can_grow_active = FALSE
set_temp("Error: Cannot grow [active_br.mydna.name] due to species complexity.", "danger")
// load it!
current_br = WEAKREF(active_br)
else else
active_br = null
set_temp("Error: Record missing.", "danger") set_temp("Error: Record missing.", "danger")
/obj/machinery/computer/transhuman/resleeving/proc/view_m_rec(ref) /obj/machinery/computer/transhuman/resleeving/proc/view_m_rec(ref)
if(!length(ref)) if(!length(ref))
return return
active_mr = locate(ref) var/datum/transhuman/mind_record/active_mr = locate(ref)
if(istype(active_mr)) if(istype(active_mr))
if(isnull(active_mr.ckey)) if(isnull(active_mr.ckey))
qdel(active_mr) if(!QDELETED(active_mr))
qdel(active_mr)
current_mr = null
set_temp("Error: Record corrupt.", "danger") set_temp("Error: Record corrupt.", "danger")
else else
can_sleeve_active = TRUE can_sleeve_active = TRUE
@@ -569,8 +590,9 @@
if(selected_sleever && !selected_sleever.get_occupant()) if(selected_sleever && !selected_sleever.get_occupant())
can_sleeve_active = FALSE can_sleeve_active = FALSE
set_temp("Error: Cannot sleeve due to lack of sleever occupant.", "danger") set_temp("Error: Cannot sleeve due to lack of sleever occupant.", "danger")
// load it!
current_mr = WEAKREF(active_mr)
else else
active_mr = null
set_temp("Error: Record missing.", "danger") set_temp("Error: Record missing.", "danger")
#undef MENU_MAIN #undef MENU_MAIN

View File

@@ -249,7 +249,7 @@
// These are broken up into steps, otherwise the proc gets massive and hard to read. // These are broken up into steps, otherwise the proc gets massive and hard to read.
var/mob/living/carbon/human/H = internal_producebody(location,backup_name) var/mob/living/carbon/human/H = internal_producebody(location,backup_name)
internal_producebody_handlesleevelock(H,force_unlock) internal_producebody_handlesleevelock(H,force_unlock)
internal_producebody_updatelimbandorgans(H) internal_producebody_updatelimbandorgans(H,is_synthfab)
internal_producebody_updatednastate(H,is_synthfab) internal_producebody_updatednastate(H,is_synthfab)
internal_producebody_virgoOOC(H) internal_producebody_virgoOOC(H)
internal_producebody_misc(H) internal_producebody_misc(H)

View File

@@ -136,7 +136,8 @@
var/busy = 0 //Busy cloning var/busy = 0 //Busy cloning
var/body_cost = 15000 //Cost of a cloned body (metal and glass ea.) var/body_cost = 15000 //Cost of a cloned body (metal and glass ea.)
var/max_res_amount = 30000 //Max the thing can hold var/max_res_amount = 30000 //Max the thing can hold
var/datum/transhuman/body_record/current_project var/datum/weakref/current_br
var/broken = 0 var/broken = 0
var/burn_value = 0 //Setting these to 0, if resleeving as organic with unupgraded sleevers gives them no damage, resleeving synths with unupgraded synthfabs should not give them potentially 105 damage. var/burn_value = 0 //Setting these to 0, if resleeving as organic with unupgraded sleevers gives them no damage, resleeving synths with unupgraded synthfabs should not give them potentially 105 damage.
var/brute_value = 0 var/brute_value = 0
@@ -176,7 +177,7 @@
if(stat & NOPOWER) if(stat & NOPOWER)
if(busy) if(busy)
busy = 0 busy = 0
current_project = null current_br = null
update_icon() update_icon()
return return
@@ -188,14 +189,14 @@
return return
/obj/machinery/transhuman/synthprinter/proc/print(var/datum/transhuman/body_record/BR) /obj/machinery/transhuman/synthprinter/proc/print(var/datum/weakref/BR)
if(!istype(BR) || busy) if(!BR?.resolve() || busy)
return 0 return 0
if(stored_material[MAT_STEEL] < body_cost || stored_material[MAT_GLASS] < body_cost) if(stored_material[MAT_STEEL] < body_cost || stored_material[MAT_GLASS] < body_cost)
return 0 return 0
current_project = BR current_br = BR
busy = 5 busy = 5
update_icon() update_icon()
@@ -203,8 +204,11 @@
/obj/machinery/transhuman/synthprinter/proc/make_body() /obj/machinery/transhuman/synthprinter/proc/make_body()
//Manage machine-specific stuff //Manage machine-specific stuff
var/datum/transhuman/body_record/current_project = current_br?.resolve()
if(!current_project) if(!current_project)
busy = 0 busy = 0
current_br = null
update_icon() update_icon()
return return