From 91349334423fdceae93146aa11a271eeddf3cc2c Mon Sep 17 00:00:00 2001 From: Aronai Sieyes Date: Sun, 30 May 2021 18:53:18 -0400 Subject: [PATCH] Allow multiple SStranscore databases (#10450) * Allow multiple SStranscore databases * Add key to backup implanter too * Key passing tweak * Fix issue Leshana spotted * Add optimization Leshana spotted * Fixxy more multitranscore bugs --- code/__defines/subsystems.dm | 3 +- code/controllers/subsystems/transcore_vr.dm | 166 ++++++++++++++---- code/game/machinery/cryopod.dm | 7 +- .../game/objects/items/devices/scanners_vr.dm | 13 +- code/modules/mob/dead/observer/free_vr.dm | 8 +- code/modules/mob/dead/observer/observer_vr.dm | 12 +- .../mob/living/carbon/human/life_vr.dm | 16 +- code/modules/resleeving/computers.dm | 22 ++- code/modules/resleeving/designer.dm | 11 +- code/modules/resleeving/implant.dm | 21 ++- code/modules/resleeving/infocore_records.dm | 8 +- code/modules/resleeving/infomorph.dm | 11 +- code/modules/resleeving/machines.dm | 4 +- code/modules/resleeving/sleevecard.dm | 4 +- 14 files changed, 214 insertions(+), 92 deletions(-) diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index a91df482b9..ba97a1114a 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -63,7 +63,8 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_PLANETS 18 #define INIT_ORDER_JOB 17 #define INIT_ORDER_ALARM 16 // Must initialize before atoms. -#define INIT_ORDER_ATOMS 15 +#define INIT_ORDER_TRANSCORE 15 // VOREStation Edit +#define INIT_ORDER_ATOMS 14 // VOREStation Edit #define INIT_ORDER_MACHINES 10 #define INIT_ORDER_SHUTTLES 3 #define INIT_ORDER_TIMER 1 diff --git a/code/controllers/subsystems/transcore_vr.dm b/code/controllers/subsystems/transcore_vr.dm index bd8786ed0c..36f2a77914 100644 --- a/code/controllers/subsystems/transcore_vr.dm +++ b/code/controllers/subsystems/transcore_vr.dm @@ -10,25 +10,34 @@ SUBSYSTEM_DEF(transcore) name = "Transcore" priority = 20 wait = 3 MINUTES - flags = SS_BACKGROUND|SS_NO_INIT + flags = SS_BACKGROUND runlevels = RUNLEVEL_GAME + init_order = INIT_ORDER_TRANSCORE // THINGS var/overdue_time = 15 MINUTES - var/core_dumped = FALSE // Core has been dumped! Also set can_fire = 0 when you set this. var/current_step = SSTRANSCORE_IMPLANTS var/cost_backups = 0 var/cost_implants = 0 - var/list/datum/transhuman/mind_record/backed_up = list() // All known mind records, indexed by MR.mindname/mind.name - var/list/datum/transhuman/mind_record/has_left = list() // Why do we even have this? - var/list/datum/transhuman/body_record/body_scans = list() // All known body records, indexed by BR.mydna.name - var/list/obj/item/weapon/implant/backup/implants = list() // All OPERATING implants that are being ticked + var/list/datum/transcore_db/databases = list() // Holds instances of each database + var/datum/transcore_db/default_db // The default if no specific one is used var/list/current_run = list() +/datum/controller/subsystem/transcore/Initialize() + default_db = new() + databases["default"] = default_db + for(var/t in subtypesof(/datum/transcore_db)) + var/datum/transcore_db/db = new t() + if(!db.key) + warning("Instantiated transcore DB without a key: [t]") + continue + databases[db.key] = db + return ..() + /datum/controller/subsystem/transcore/fire(resumed = 0) var/timer = TICK_USAGE @@ -37,30 +46,36 @@ SUBSYSTEM_DEF(transcore) /datum/controller/subsystem/transcore/proc/process_implants(resumed = 0) if (!resumed) - src.current_run = implants.Copy() + // Create a flat list of every implant in every db with a value of the db they're in + src.current_run.Cut() + for(var/key in databases) + var/datum/transcore_db/db = databases[key] + for(var/obj/item/weapon/implant/backup/imp as anything in db.implants) + src.current_run[imp] = db var/list/current_run = src.current_run while(current_run.len) var/obj/item/weapon/implant/backup/imp = current_run[current_run.len] + var/datum/transcore_db/db = current_run[imp] current_run.len-- //Remove if not in a human anymore. if(!imp || !isorgan(imp.loc)) - implants -= imp + db.implants -= imp continue //We're in an organ, at least. var/obj/item/organ/external/EO = imp.loc var/mob/living/carbon/human/H = EO.owner if(!H) - implants -= imp + db.implants -= imp continue //In a human BITSET(H.hud_updateflag, BACKUP_HUD) if(H == imp.imp_in && H.mind && H.stat < DEAD) - SStranscore.m_backup(H.mind,H.nif) + db.m_backup(H.mind,H.nif) persist_nif_data(H) if(MC_TICK_CHECK) @@ -68,18 +83,24 @@ SUBSYSTEM_DEF(transcore) /datum/controller/subsystem/transcore/proc/process_backups(resumed = 0) if (!resumed) - src.current_run = backed_up.Copy() + // Create a flat list of every implant in every db with a value of the db they're in + src.current_run.Cut() + for(var/key in databases) + var/datum/transcore_db/db = databases[key] + for(var/name in db.backed_up) + var/datum/transhuman/mind_record/mr = db.backed_up[name] + src.current_run[mr] = db var/list/current_run = src.current_run while(current_run.len) - var/name = current_run[current_run.len] - var/datum/transhuman/mind_record/curr_MR = current_run[name] - current_run -= name + var/datum/transhuman/mind_record/curr_MR = current_run[current_run.len] + var/datum/transcore_db/db = current_run[curr_MR] + current_run.len-- //Invalid record if(!curr_MR) log_debug("Tried to process [name] in transcore w/o a record!") - backed_up -= name + db.backed_up -= curr_MR.mindname continue //Onetimes do not get processing or notifications @@ -92,7 +113,7 @@ SUBSYSTEM_DEF(transcore) curr_MR.dead_state = MR_NORMAL else if(curr_MR.dead_state != MR_DEAD) //First time switching to dead - notify(name) + db.notify(curr_MR.mindname) curr_MR.last_notification = world.time curr_MR.dead_state = MR_DEAD @@ -101,30 +122,100 @@ SUBSYSTEM_DEF(transcore) /datum/controller/subsystem/transcore/stat_entry() var/msg = list() - if(core_dumped) - msg += "CORE DUMPED | " msg += "$:{" msg += "IM:[round(cost_implants,1)]|" msg += "BK:[round(cost_backups,1)]" msg += "} " msg += "#:{" - msg += "IM:[implants.len]|" - msg += "BK:[backed_up.len]" + msg += "DB:[databases.len]|" + if(!default_db) + msg += "DEFAULT DB MISSING" + else + msg += "DFM:[default_db.backed_up.len]|" + msg += "DFB:[default_db.body_scans.len]|" + msg += "DFI:[default_db.implants.len]" msg += "} " ..(jointext(msg, null)) /datum/controller/subsystem/transcore/Recover() - if (istype(SStranscore.body_scans)) - for(var/N in SStranscore.body_scans) - if(N && SStranscore.body_scans[N]) body_scans[N] = SStranscore.body_scans[N] - if(SStranscore.core_dumped) - core_dumped = TRUE - can_fire = FALSE - else if (istype(SStranscore.backed_up)) - for(var/N in SStranscore.backed_up) - if(N && SStranscore.backed_up[N]) backed_up[N] = SStranscore.backed_up[N] + for(var/key in SStranscore.databases) + if(!SStranscore.databases[key]) + warning("SStranscore recovery found missing database value for key: [key]") + continue + if(key == "default") + default_db = SStranscore.databases[key] -/datum/controller/subsystem/transcore/proc/m_backup(var/datum/mind/mind, var/obj/item/device/nif/nif, var/one_time = FALSE) + databases[key] = SStranscore.databases[key] + +/datum/controller/subsystem/transcore/proc/leave_round(var/mob/M) + if(!istype(M)) + warning("Non-mob asked to be removed from transcore: [M] [M?.type]") + return + if(!M.mind) + warning("No mind mob asked to be removed from transcore: [M] [M?.type]") + return + + for(var/key in databases) + var/datum/transcore_db/db = databases[key] + if(M.mind.name in db.backed_up) + var/datum/transhuman/mind_record/MR = db.backed_up[M.mind.name] + db.stop_backup(MR) + if(M.mind.name in db.body_scans) //This uses mind names to avoid people cryo'ing a printed body to delete body scans. + var/datum/transhuman/body_record/BR = db.body_scans[M.mind.name] + db.remove_body(BR) + +/datum/controller/subsystem/transcore/proc/db_by_key(var/key) + if(isnull(key)) + return default_db + if(!databases[key]) + warning("Tried to find invalid transcore database: [key]") + return default_db + return databases[key] + +/datum/controller/subsystem/transcore/proc/db_by_mind_name(var/name) + if(isnull(name)) + return null + for(var/key in databases) + var/datum/transcore_db/db = databases[key] + if(name in db.backed_up) + return db + +// These are now just interfaces to databases +/datum/controller/subsystem/transcore/proc/m_backup(var/datum/mind/mind, var/obj/item/device/nif/nif, var/one_time = FALSE, var/database_key) + var/datum/transcore_db/db = db_by_key(database_key) + db.m_backup(mind=mind, nif=nif, one_time=one_time) + +/datum/controller/subsystem/transcore/proc/add_backup(var/datum/transhuman/mind_record/MR, var/database_key) + var/datum/transcore_db/db = db_by_key(database_key) + db.add_backup(MR=MR) + +/datum/controller/subsystem/transcore/proc/stop_backup(var/datum/transhuman/mind_record/MR, var/database_key) + var/datum/transcore_db/db = db_by_key(database_key) + db.stop_backup(MR=MR) + +/datum/controller/subsystem/transcore/proc/add_body(var/datum/transhuman/body_record/BR, var/database_key) + var/datum/transcore_db/db = db_by_key(database_key) + db.add_body(BR=BR) + +/datum/controller/subsystem/transcore/proc/remove_body(var/datum/transhuman/body_record/BR, var/database_key) + var/datum/transcore_db/db = db_by_key(database_key) + db.remove_body(BR=BR) + +/datum/controller/subsystem/transcore/proc/core_dump(var/obj/item/weapon/disk/transcore/disk, var/database_key) + var/datum/transcore_db/db = db_by_key(database_key) + db.core_dump(disk=disk) + + +/datum/transcore_db + var/list/datum/transhuman/mind_record/backed_up = list() // All known mind records, indexed by MR.mindname/mind.name + var/list/datum/transhuman/mind_record/has_left = list() // Why do we even have this? + var/list/datum/transhuman/body_record/body_scans = list() // All known body records, indexed by BR.mydna.name + var/list/obj/item/weapon/implant/backup/implants = list() // All OPERATING implants that are being ticked + + var/core_dumped = FALSE + var/key // Key for this DB + +/datum/transcore_db/proc/m_backup(var/datum/mind/mind, var/obj/item/device/nif/nif, var/one_time = FALSE) ASSERT(mind) if(!mind.name || core_dumped) return 0 @@ -154,12 +245,12 @@ SUBSYSTEM_DEF(transcore) MR.nif_savedata = null else - MR = new(mind, mind.current, add_to_db = TRUE, one_time = one_time) + MR = new(mind, mind.current, add_to_db = TRUE, one_time = one_time, database_key = src.key) return 1 // Send a past-due notification to the medical radio channel. -/datum/controller/subsystem/transcore/proc/notify(var/name, var/repeated = FALSE) +/datum/transcore_db/proc/notify(var/name, var/repeated = FALSE) ASSERT(name) if(repeated) global_announcer.autosay("This is a repeat notification that [name] is past-due for a mind backup.", "TransCore Oversight", "Medical") @@ -167,14 +258,14 @@ SUBSYSTEM_DEF(transcore) global_announcer.autosay("[name] is past-due for a mind backup.", "TransCore Oversight", "Medical") // Called from mind_record to add itself to the transcore. -/datum/controller/subsystem/transcore/proc/add_backup(var/datum/transhuman/mind_record/MR) +/datum/transcore_db/proc/add_backup(var/datum/transhuman/mind_record/MR) ASSERT(MR) backed_up[MR.mindname] = MR backed_up = sortAssoc(backed_up) log_debug("Added [MR.mindname] to transcore DB.") // Remove a mind_record from the backup-checking list. Keeps track of it in has_left // Why do we do that? ~Leshana -/datum/controller/subsystem/transcore/proc/stop_backup(var/datum/transhuman/mind_record/MR) +/datum/transcore_db/proc/stop_backup(var/datum/transhuman/mind_record/MR) ASSERT(MR) has_left[MR.mindname] = MR backed_up.Remove("[MR.mindname]") @@ -182,20 +273,20 @@ SUBSYSTEM_DEF(transcore) log_debug("Put [MR.mindname] in transcore suspended DB.") // Called from body_record to add itself to the transcore. -/datum/controller/subsystem/transcore/proc/add_body(var/datum/transhuman/body_record/BR) +/datum/transcore_db/proc/add_body(var/datum/transhuman/body_record/BR) ASSERT(BR) body_scans[BR.mydna.name] = BR body_scans = sortAssoc(body_scans) log_debug("Added [BR.mydna.name] to transcore body DB.") // Remove a body record from the database (Usually done when someone cryos) // Why? ~Leshana -/datum/controller/subsystem/transcore/proc/remove_body(var/datum/transhuman/body_record/BR) +/datum/transcore_db/proc/remove_body(var/datum/transhuman/body_record/BR) ASSERT(BR) body_scans.Remove("[BR.mydna.name]") log_debug("Removed [BR.mydna.name] from transcore body DB.") // Moves all mind records from the databaes into the disk and shuts down all backup canary processing. -/datum/controller/subsystem/transcore/proc/core_dump(var/obj/item/weapon/disk/transcore/disk) +/datum/transcore_db/proc/core_dump(var/obj/item/weapon/disk/transcore/disk) ASSERT(disk) global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Command") global_announcer.autosay("An emergency core dump has been initiated!", "TransCore Oversight", "Medical") @@ -203,7 +294,6 @@ SUBSYSTEM_DEF(transcore) disk.stored += backed_up backed_up.Cut() core_dumped = TRUE - can_fire = FALSE return disk.stored.len #undef SSTRANSCORE_BACKUPS diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 7ed6abed40..3cd05e69b5 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -461,12 +461,7 @@ //VOREStation Edit - Resleeving. if(to_despawn.mind) - if(to_despawn.mind.name in SStranscore.backed_up) - var/datum/transhuman/mind_record/MR = SStranscore.backed_up[to_despawn.mind.name] - SStranscore.stop_backup(MR) - if(to_despawn.mind.name in SStranscore.body_scans) //This uses mind names to avoid people cryo'ing a printed body to delete body scans. - var/datum/transhuman/body_record/BR = SStranscore.body_scans[to_despawn.mind.name] - SStranscore.remove_body(BR) + SStranscore.leave_round(to_despawn) //VOREStation Edit End - Resleeving. //Handle job slot/tater cleanup. diff --git a/code/game/objects/items/devices/scanners_vr.dm b/code/game/objects/items/devices/scanners_vr.dm index 5740a7df86..b5adabdb6e 100644 --- a/code/game/objects/items/devices/scanners_vr.dm +++ b/code/game/objects/items/devices/scanners_vr.dm @@ -19,7 +19,14 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob var/ooc_notes = null //For holding prefs + // Resleeving database this machine interacts with. Blank for default database + // Needs a matching /datum/transcore_db with key defined in code + var/db_key + var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref +/obj/item/device/sleevemate/Initialize() + . = ..() + our_db = SStranscore.db_by_key(db_key) //These don't perform any checks and need to be wrapped by checks /obj/item/device/sleevemate/proc/clear_mind() @@ -77,7 +84,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob clear_mind() if("Backup") to_chat(user,"Internal copy of [stored_mind.name] backed up to database.") - SStranscore.m_backup(stored_mind,null,one_time = TRUE) + our_db.m_backup(stored_mind,null,one_time = TRUE) if("Cancel") return @@ -183,7 +190,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob usr.visible_message("[usr] begins scanning [target]'s mind.","You begin scanning [target]'s mind.") if(do_after(usr,8 SECONDS,target)) - SStranscore.m_backup(target.mind,nif,one_time = TRUE) + our_db.m_backup(target.mind,nif,one_time = TRUE) to_chat(usr,"Mind backed up!") else to_chat(usr,"You must remain close to your target!") @@ -200,7 +207,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob usr.visible_message("[usr] begins scanning [target]'s body.","You begin scanning [target]'s body.") if(do_after(usr,8 SECONDS,target)) var/datum/transhuman/body_record/BR = new() - BR.init_from_mob(H, TRUE, TRUE) + BR.init_from_mob(H, TRUE, TRUE, database_key = db_key) to_chat(usr,"Body scanned!") else to_chat(usr,"You must remain close to your target!") diff --git a/code/modules/mob/dead/observer/free_vr.dm b/code/modules/mob/dead/observer/free_vr.dm index dca361725f..6cbb09900c 100644 --- a/code/modules/mob/dead/observer/free_vr.dm +++ b/code/modules/mob/dead/observer/free_vr.dm @@ -32,12 +32,8 @@ var/global/list/prevent_respawns = list() qdel(O) //Resleeving cleanup - if(src.mind.name in SStranscore.backed_up) - var/datum/transhuman/mind_record/MR = SStranscore.backed_up[src.mind.name] - SStranscore.stop_backup(MR) - if(src.mind.name in SStranscore.body_scans) //This uses mind names to avoid people cryo'ing a printed body to delete body scans. - var/datum/transhuman/body_record/BR = SStranscore.body_scans[src.mind.name] - SStranscore.remove_body(BR) + if(mind) + SStranscore.leave_round(src) //Job slot cleanup var/job = src.mind.assigned_role diff --git a/code/modules/mob/dead/observer/observer_vr.dm b/code/modules/mob/dead/observer/observer_vr.dm index 2e54e6414e..636db5e347 100644 --- a/code/modules/mob/dead/observer/observer_vr.dm +++ b/code/modules/mob/dead/observer/observer_vr.dm @@ -62,18 +62,22 @@ set name = "Notify Transcore" set desc = "If your past-due backup notification was missed or ignored, you can use this to send a new one." - if(src.mind && (src.mind.name in SStranscore.backed_up)) - var/datum/transhuman/mind_record/record = SStranscore.backed_up[src.mind.name] + if(!mind) + to_chat(src,"Your ghost is missing game values that allow this functionality, sorry.") + return + var/datum/transcore_db/db = SStranscore.db_by_mind_name(mind.name) + if(db) + var/datum/transhuman/mind_record/record = db.backed_up[src.mind.name] if(!(record.dead_state == MR_DEAD)) to_chat(src, "Your backup is not past-due yet.") else if((world.time - record.last_notification) < 10 MINUTES) to_chat(src, "Too little time has passed since your last notification.") else - SStranscore.notify(record.mindname, TRUE) + db.notify(record.mindname, TRUE) record.last_notification = world.time to_chat(src, "New notification has been sent.") else - to_chat(src, "No mind record found!") + to_chat(src,"No backup record could be found, sorry.") /mob/observer/dead/verb/findghostpod() //Moves the ghost instead of just changing the ghosts's eye -Nodrak set category = "Ghost" diff --git a/code/modules/mob/living/carbon/human/life_vr.dm b/code/modules/mob/living/carbon/human/life_vr.dm index c5248fc862..fc4f613418 100644 --- a/code/modules/mob/living/carbon/human/life_vr.dm +++ b/code/modules/mob/living/carbon/human/life_vr.dm @@ -38,14 +38,14 @@ for(var/obj/item/organ/external/E in organs) for(var/obj/item/weapon/implant/I in E.implants) - if(I.implanted) - if(istype(I,/obj/item/weapon/implant/backup)) - if(!mind) - holder.icon_state = "hud_backup_nomind" - else if(!(mind.name in SStranscore.body_scans)) - holder.icon_state = "hud_backup_nobody" - else - holder.icon_state = "hud_backup_norm" + if(I.implanted && istype(I,/obj/item/weapon/implant/backup)) + var/obj/item/weapon/implant/backup/B = I + if(!mind) + holder.icon_state = "hud_backup_nomind" + else if(!(mind.name in B.our_db.body_scans)) + holder.icon_state = "hud_backup_nobody" + else + holder.icon_state = "hud_backup_norm" apply_hud(BACKUP_HUD, holder) diff --git a/code/modules/resleeving/computers.dm b/code/modules/resleeving/computers.dm index e49c886247..58edeffa9f 100644 --- a/code/modules/resleeving/computers.dm +++ b/code/modules/resleeving/computers.dm @@ -25,11 +25,17 @@ var/obj/machinery/transhuman/synthprinter/selected_printer var/obj/machinery/transhuman/resleever/selected_sleever + // Resleeving database this machine interacts with. Blank for default database + // Needs a matching /datum/transcore_db with key defined in code + var/db_key + var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref + /obj/machinery/computer/transhuman/resleeving/Initialize() . = ..() pods = list() spods = list() sleevers = list() + our_db = SStranscore.db_by_key(db_key) updatemodules() /obj/machinery/computer/transhuman/resleeving/Destroy() @@ -82,7 +88,7 @@ P.connected = src P.name = "[initial(P.name)] #[pods.len]" to_chat(user, "You connect [P] to [src].") - else if(istype(W, /obj/item/weapon/disk/transcore) && SStranscore && !SStranscore.core_dumped) + else if(istype(W, /obj/item/weapon/disk/transcore) && !our_db.core_dumped) user.unEquip(W) disk = W disk.forceMove(src) @@ -172,7 +178,7 @@ data["sleevers"] = temppods.Copy() temppods.Cut() - data["coredumped"] = SStranscore.core_dumped + data["coredumped"] = our_db.core_dumped data["emergency"] = disk data["temp"] = temp data["selected_pod"] = "\ref[selected_pod]" @@ -180,14 +186,14 @@ data["selected_sleever"] = "\ref[selected_sleever]" var/bodyrecords_list_ui[0] - for(var/N in SStranscore.body_scans) - var/datum/transhuman/body_record/BR = SStranscore.body_scans[N] + for(var/N in our_db.body_scans) + var/datum/transhuman/body_record/BR = our_db.body_scans[N] bodyrecords_list_ui[++bodyrecords_list_ui.len] = list("name" = N, "recref" = "\ref[BR]") data["bodyrecords"] = bodyrecords_list_ui var/mindrecords_list_ui[0] - for(var/N in SStranscore.backed_up) - var/datum/transhuman/mind_record/MR = SStranscore.backed_up[N] + for(var/N in our_db.backed_up) + var/datum/transhuman/mind_record/MR = our_db.backed_up[N] mindrecords_list_ui[++mindrecords_list_ui.len] = list("name" = N, "recref" = "\ref[MR]") data["mindrecords"] = mindrecords_list_ui @@ -251,7 +257,7 @@ set_temp("Error: Record missing.", "danger") if("coredump") if(disk) - SStranscore.core_dump(disk) + our_db.core_dump(disk) sleep(5) visible_message("\The [src] spits out \the [disk].") disk.forceMove(get_turf(src)) @@ -407,7 +413,7 @@ return TRUE //They were dead, or otherwise available. - sleever.putmind(active_mr,mode,override) + sleever.putmind(active_mr,mode,override,db_key = db_key) set_temp("Initiating resleeving...") tgui_modal_clear(src) diff --git a/code/modules/resleeving/designer.dm b/code/modules/resleeving/designer.dm index 8e4578fd25..49a8180efd 100644 --- a/code/modules/resleeving/designer.dm +++ b/code/modules/resleeving/designer.dm @@ -29,6 +29,11 @@ var/mob/living/carbon/human/dummy/mannequin/mannequin = null var/obj/item/weapon/disk/body_record/disk = null + // Resleeving database this machine interacts with. Blank for default database + // Needs a matching /datum/transcore_db with key defined in code + var/db_key + var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref + /obj/machinery/computer/transhuman/designer/Initialize() . = ..() map_name = "transhuman_designer_[REF(src)]_map" @@ -51,6 +56,8 @@ west_preview.del_on_map_removal = FALSE west_preview.screen_loc = "[map_name]:0,1" + our_db = SStranscore.db_by_key(db_key) + /obj/machinery/computer/transhuman/designer/Destroy() active_br = null mannequin = null @@ -100,8 +107,8 @@ if(menu == MENU_BODYRECORDS) var/bodyrecords_list_ui[0] - for(var/N in SStranscore.body_scans) - var/datum/transhuman/body_record/BR = SStranscore.body_scans[N] + for(var/N in our_db.body_scans) + var/datum/transhuman/body_record/BR = our_db.body_scans[N] bodyrecords_list_ui[++bodyrecords_list_ui.len] = list("name" = N, "recref" = "\ref[BR]") if(bodyrecords_list_ui.len) data["bodyrecords"] = bodyrecords_list_ui diff --git a/code/modules/resleeving/implant.dm b/code/modules/resleeving/implant.dm index 95ea041dee..86dfa603aa 100644 --- a/code/modules/resleeving/implant.dm +++ b/code/modules/resleeving/implant.dm @@ -13,6 +13,11 @@ icon_state = "backup_implant" known_implant = TRUE + // Resleeving database this machine interacts with. Blank for default database + // Needs a matching /datum/transcore_db with key defined in code + var/db_key + var/datum/transcore_db/our_db // These persist all round and are never destroyed, just keep a hard ref + /obj/item/weapon/implant/backup/get_data() var/dat = {" Implant Specifications:
@@ -26,14 +31,22 @@ Integrity: Generally very survivable. Susceptible to being destroyed by acid."} return dat +/obj/item/weapon/implant/backup/New(newloc, db_key) + . = ..() + src.db_key = db_key + +/obj/item/weapon/implant/backup/Initialize() + . = ..() + our_db = SStranscore.db_by_key(db_key) + /obj/item/weapon/implant/backup/Destroy() - SStranscore.implants -= src + our_db.implants -= src return ..() /obj/item/weapon/implant/backup/post_implant(var/mob/living/carbon/human/H) if(istype(H)) BITSET(H.hud_updateflag, BACKUP_HUD) - SStranscore.implants |= src + our_db.implants |= src return 1 @@ -53,10 +66,12 @@ var/list/obj/item/weapon/implant/backup/imps = list() var/max_implants = 4 //Iconstates need to exist due to the update proc! + var/db_key // To give to the baby implants + /obj/item/weapon/backup_implanter/New() ..() for(var/i = 1 to max_implants) - var/obj/item/weapon/implant/backup/imp = new(src) + var/obj/item/weapon/implant/backup/imp = new(src, db_key) imps |= imp imp.germ_level = 0 update() diff --git a/code/modules/resleeving/infocore_records.dm b/code/modules/resleeving/infocore_records.dm index e32c28e66b..25844ec765 100644 --- a/code/modules/resleeving/infocore_records.dm +++ b/code/modules/resleeving/infocore_records.dm @@ -31,7 +31,7 @@ var/one_time = FALSE -/datum/transhuman/mind_record/New(var/datum/mind/mind, var/mob/living/carbon/human/M, var/add_to_db = TRUE, var/one_time = FALSE) +/datum/transhuman/mind_record/New(var/datum/mind/mind, var/mob/living/carbon/human/M, var/add_to_db = TRUE, var/one_time = FALSE, var/database_key) ASSERT(mind) src.one_time = one_time @@ -62,7 +62,7 @@ last_update = world.time if(add_to_db) - SStranscore.add_backup(src) + SStranscore.add_backup(src, database_key = database_key) /////// Body Record /////// /datum/transhuman/body_record @@ -100,7 +100,7 @@ organ_data.Cut() return QDEL_HINT_HARDDEL // For now at least there is no easy way to clear references to this in machines etc. -/datum/transhuman/body_record/proc/init_from_mob(var/mob/living/carbon/human/M, var/add_to_db = 0, var/ckeylock = 0) +/datum/transhuman/body_record/proc/init_from_mob(var/mob/living/carbon/human/M, var/add_to_db = 0, var/ckeylock = 0, var/database_key) ASSERT(!QDELETED(M)) ASSERT(istype(M)) @@ -185,7 +185,7 @@ genetic_modifiers.Add(mod.type) if(add_to_db) - SStranscore.add_body(src) + SStranscore.add_body(src, database_key = database_key) /** diff --git a/code/modules/resleeving/infomorph.dm b/code/modules/resleeving/infomorph.dm index 77eae4e51d..f9bc21804a 100644 --- a/code/modules/resleeving/infomorph.dm +++ b/code/modules/resleeving/infomorph.dm @@ -58,6 +58,7 @@ var/list/infomorph_emotions = list( var/obj/item/weapon/pai_cable/cable // The cable we produce and use when door or camera jacking var/silence_time // Timestamp when we were silenced (normally via EMP burst), set to null after silence has faded + var/db_key // Various software-specific vars @@ -83,7 +84,7 @@ var/list/infomorph_emotions = list( var/datum/data/record/securityActive1 // Could probably just combine all these into one var/datum/data/record/securityActive2 -/mob/living/silicon/infomorph/New(var/obj/item/device/sleevecard/SC, var/name = "Unknown") +/mob/living/silicon/infomorph/New(var/obj/item/device/sleevecard/SC, var/name = "Unknown", var/db_key) ASSERT(SC) name = "[initial(name)] ([name])" src.forceMove(SC) @@ -95,6 +96,8 @@ var/list/infomorph_emotions = list( card.radio = new (card) radio = card.radio + src.db_key = db_key + //Default languages without universal translator software add_language(LANGUAGE_EAL, 1) add_language(LANGUAGE_SIGN, 0) @@ -406,9 +409,7 @@ var/list/infomorph_emotions = list( close_up() //Resleeving 'cryo' - if(mind && (mind.name in SStranscore.backed_up)) - var/datum/transhuman/mind_record/MR = SStranscore.backed_up[mind.name] - SStranscore.stop_backup(MR) + SStranscore.leave_round(src) card.removePersonality() clear_client() @@ -588,7 +589,7 @@ var/global/list/default_infomorph_software = list() //Only every so often if(air_master.current_cycle%30 == 1) - SStranscore.m_backup(mind) + SStranscore.m_backup(mind, database_key = db_key) if(health <= 0) death(null,"gives one shrill beep before falling lifeless.") diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm index de9f7a0dd2..cfdaf17e59 100644 --- a/code/modules/resleeving/machines.dm +++ b/code/modules/resleeving/machines.dm @@ -539,13 +539,13 @@ add_fingerprint(user) -/obj/machinery/transhuman/resleever/proc/putmind(var/datum/transhuman/mind_record/MR, mode = 1, var/mob/living/carbon/human/override = null) +/obj/machinery/transhuman/resleever/proc/putmind(var/datum/transhuman/mind_record/MR, mode = 1, var/mob/living/carbon/human/override = null, var/db_key) if((!occupant || !istype(occupant) || occupant.stat >= DEAD) && mode == 1) return 0 if(mode == 2 && sleevecards) //Card sleeving var/obj/item/device/sleevecard/card = new /obj/item/device/sleevecard(get_turf(src)) - card.sleeveInto(MR) + card.sleeveInto(MR, db_key = db_key) sleevecards-- return 1 diff --git a/code/modules/resleeving/sleevecard.dm b/code/modules/resleeving/sleevecard.dm index 8e8bb68a77..086468de0f 100644 --- a/code/modules/resleeving/sleevecard.dm +++ b/code/modules/resleeving/sleevecard.dm @@ -53,8 +53,8 @@ to_chat(user,"\The [src] displays the name '[infomorph]'.") //This is a 'hard' proc, it does no permission checking, do that on the computer -/obj/item/device/sleevecard/proc/sleeveInto(var/datum/transhuman/mind_record/MR) - infomorph = new(src,MR.mindname) +/obj/item/device/sleevecard/proc/sleeveInto(var/datum/transhuman/mind_record/MR, var/db_key) + infomorph = new(src,MR.mindname,db_key=db_key) for(var/datum/language/L in MR.languages) infomorph.add_language(L.name)