From 3b289565d5f131d4bb4a27cee3ca484ea056e55d Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Tue, 28 Nov 2023 21:26:36 +0000 Subject: [PATCH 1/9] protean reconstitutor --- code/game/machinery/protean_reconstitutor.dm | 196 +++++++++++++++++++ icons/obj/protean_recon.dmi | Bin 0 -> 760 bytes 2 files changed, 196 insertions(+) create mode 100644 code/game/machinery/protean_reconstitutor.dm create mode 100644 icons/obj/protean_recon.dmi diff --git a/code/game/machinery/protean_reconstitutor.dm b/code/game/machinery/protean_reconstitutor.dm new file mode 100644 index 00000000000..0b6b3f420c2 --- /dev/null +++ b/code/game/machinery/protean_reconstitutor.dm @@ -0,0 +1,196 @@ +/obj/machinery/protean_reconstitutor + name = "protean reconstitutor" + desc = "A complex machine that is most definitely not just a large tub into which one pours a large amount of untethered nanites, then adds a protean positronic brain and orchestrator, in order to reconstitute a disintegrated protean... it's complicated, really!" + description_info = "Use a protean positronic brain, orchestrator, optionally a refactory, and nanopaste to \'fill\' the machine, then interact with it once it's ready. Protean components can be retrieved using a wrench, but any nanopaste inserted will be converted and cannot be reclaimed!" + icon = 'icons/obj/protean_recon.dmi' + icon_state = "recon-nopower" + var/state_base = "recon" + anchored = TRUE + density = TRUE + power_channel = EQUIP + use_power = USE_POWER_IDLE + idle_power_usage = 10 + active_power_usage = 1000 + clicksound = 'sound/machines/buttonbeep.ogg' + var/dingsound = 'sound/machines/kitchen/microwave/microwave-end.ogg' + + //vars for basic functionality + var/obj/item/device/mmi/digital/posibrain/nano/protean_brain = null //only allow protean brains + var/obj/item/organ/internal/nano/orchestrator/protean_orchestrator = null + var/obj/item/organ/internal/nano/refactory/protean_refactory = null //not essential, but nice to have; lets us transfer stored materials + var/nanomass_reserve = 0 //starting reserve + var/nanotank_max = 300 //how much we can store at once, todo: upgradable + var/nanomass_required = 60 //how much we need in order to make a new body, base + var/nanomass_efficiency = 1 //multiplier to nanomass required, todo: upgradable + var/paste_inefficiency = 5 //divisor to mech_repair value of paste added; higher = less effective + +/obj/machinery/protean_reconstitutor/update_icon() + cut_overlays() + if(stat & (NOPOWER|BROKEN) || !anchored) + if(stat & BROKEN) + icon_state = "[state_base]-broken" + else + icon_state = "[state_base]-nopower" + return + icon_state = state_base + if(protean_brain) + add_overlay("[state_base]-brain") + if(protean_orchestrator) + add_overlay("[state_base]-orchestrator") + if(protean_refactory) + add_overlay("[state_base]-refactory") + if(nanomass_reserve >= nanomass_required * nanomass_efficiency) + add_overlay("[state_base]-tank_full") + +/obj/machinery/protean_reconstitutor/examine() + . = ..() + if(protean_refactory) + . += "A protean refactory appears to be present." + if(protean_brain && !protean_orchestrator) + . += "It currently has a protean positronic brain ready, but still needs an orchestrator." + else if(protean_orchestrator && !protean_brain) + . += "It currently has an orchestrator ready, but lacks a protean positronic brain." + else if(protean_orchestrator && protean_brain) + . += "It currently has both a positronic brain and orchestrator ready!" + else + . += "It currently lacks both a positronic brain and orchestrator." + . += "The readout shows that it has [nanomass_reserve] units of nanites ready for use. It requires [nanomass_required * nanomass_efficiency] per \'revive\' process, and has a maximum capacity of [nanotank_max] units." + +/obj/machinery/protean_reconstitutor/attackby(obj/item/W as obj, mob/user as mob) + src.add_fingerprint(user) + + if(istype(W,/obj/item/device/mmi/digital/posibrain/nano)) + var/obj/item/device/mmi/digital/posibrain/nano/NB = W + to_chat(user,"You slot \the [NB] into \the [src].") + user.drop_from_inventory(NB) + NB.loc = src + protean_brain = NB + + if(istype(W,/obj/item/organ/internal/nano/orchestrator)) + to_chat(user,"You slot \the [W] into \the [src].") + user.drop_from_inventory(W) + W.loc = src + protean_orchestrator = W + + if(istype(W,/obj/item/organ/internal/nano/refactory)) + to_chat(user,"You slot \the [W] into \the [src].") + user.drop_from_inventory(W) + W.loc = src + protean_refactory = W + + if(istype(W,/obj/item/stack/nanopaste)) + var/obj/item/stack/nanopaste/NP = W + if(nanomass_reserve >= nanotank_max) + to_chat(user,"The tank is full!") + return + nanomass_reserve += NP.amount * max(1,NP.mech_repair / paste_inefficiency) + if(nanomass_reserve > nanotank_max) + nanomass_reserve = nanotank_max + to_chat(user,"You fill \the [src] with paste from \the [NP]. The display now reads [nanomass_reserve]/[nanotank_max] units.") + qdel(NP) + + if(W.has_tool_quality(TOOL_WRENCH)) + if(protean_brain || protean_orchestrator || protean_refactory) + var/choice = tgui_input_list(usr, "What component would you like to remove?", "Remove Component", list(protean_brain,protean_orchestrator,protean_refactory)) + if(!choice) return + + if(choice == protean_brain) + to_chat(user, "You fish \the [protean_brain] out of \the [src].") + protean_brain.forceMove(get_turf(src)) + playsound(src, W.usesound, 50, 1) + src.protean_brain = null + if(choice == protean_refactory) + to_chat(user, "You fish \the [protean_refactory] out of \the [src].") + protean_refactory.forceMove(get_turf(src)) + playsound(src, W.usesound, 50, 1) + src.protean_refactory = null + else if(choice == protean_orchestrator) + to_chat(user, "You fish \the [protean_orchestrator] out of \the [src].") + protean_orchestrator.forceMove(get_turf(src)) + playsound(src, W.usesound, 50, 1) + src.protean_orchestrator = null + else + to_chat(user, "\The [src] does not have any protean components you can retrieve.") + + update_icon() + return ..() + +/obj/machinery/protean_reconstitutor/attack_hand(mob/user as mob) + if(!protean_brain || !protean_orchestrator || (nanomass_reserve < (nanomass_required * nanomass_efficiency))) + to_chat(user,"Essential components missing, or insufficient materials available!") + update_icon() + return + else if(protean_brain && protean_orchestrator && (nanomass_reserve > (nanomass_required * nanomass_efficiency))) + //we're good, let's get recombobulating! + src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: 1 minute.\"") + power_change() + if(prob(2)) + playsound(src, 'sound/machines/blender.ogg', 50, 1) + nanomass_reserve -= nanomass_required * nanomass_efficiency + sleep(20 SECONDS) //1 minute default, testing placeholder + var/mob/living/carbon/human/protean/P = new /mob/living/carbon/human/protean + var/mats_cached + var/list/materials_cache + P.loc = src + for(var/organ in P.internal_organs_by_name) + var/obj/item/O = P.internal_organs_by_name[organ] + if(istype(O,/obj/item/organ/internal/nano/refactory)) + if(protean_refactory) //if we have a refactory present, install it, otherwise they get a free replacement (for now; perhaps no free replacement but they can be made printable at the prosfab?) + src.visible_message("\The [src] chirps, \"Refactory reboot complete...\"") + else + src.visible_message("\The [src] chirps, \"Linking nanoswarm to orchestrator...\"") + P.internal_organs_by_name.Remove(O) + P.internal_organs.Remove(O) + P.contents.Remove(O) + qdel(O) + P.internal_organs_by_name.Add(list(O_ORCH = protean_orchestrator)) + P.internal_organs.Add(protean_orchestrator) + protean_orchestrator.loc = P + protean_orchestrator = null + src.visible_message("\The [src] chirps, \"Synchronizing positronic neural architecture...\"") + var/obj/item/organ/internal/mmi_holder/posibrain/nano/BR = O + BR.stored_mmi = null //toss the dummy... + BR.contents.Cut() + BR.stored_mmi = protean_brain //...and implant the salvaged mmi in its place + BR.contents.Add(protean_brain) + P.ckey = protean_brain.brainmob.ckey + P.mind = protean_brain.brainmob.mind + P.client = protean_brain.brainmob.client + protean_brain.loc = BR + protean_brain = null + src.visible_message("\The [src] chirps, \"Refactory storage indexing complete...\"") + RF.materials = materials_cache.Copy() + materials_cache.Cut() + mats_cached = FALSE + var/obj/item/device/nif/protean/new_nif = new() + new_nif.quick_implant(P) + //finally... drop them in front of the machine! + sleep(1 SECOND) + src.visible_message("N;P`5Ho5;n$D$e8h6l;oyznHA=Rbu6kRfnA8mlE@Y)_ ze=x1Sbl$3WKEltE3JZ7juCF{NSFTt-d&l<~Epr2&9quYD*(*^0@2AkLb!|Yixu3qy z-x91fDTRT7iO?FUJhbO=|Gk0n{Y|SJ<BF4j&DTCIKdz>^^x?J7`tz$_UOPX% zIB(nceJ|3DWq*89I4}F*rNZ=n-OA*-tP*Vx-&i_sq_}-@ZIye|7o)C)uYB zW~<(h=}%^u!I;3-AjyyhWVm_P-~E#v*WvoNIlk{XkHpnIvX5GC^vv3PKyrf;TZ7N( z35;%A^E>^4G+56g%LM_|fAx=l_L6u|dVp&O%i0!3hI`ymg3Jea7>pU-ys>(4t#4!0 zi;vS|Cg|RLTgIP$z-jt#=jU?z_If{Ob#xqi`%)*J;S7U8{xQ*A&e2cTW&Gb|KUe(R zImX)i;gyWB*JJ0-D9bh9^S(NzI3)M(LfK^;dX5GV!-2X;VQdI}+jnnk?9{oH*|!?E zuVOfVLY1TKeV?D^MSaGty&W0x=l<`@{Qq;t|M_9rbN)XuVa}52De5^basE^>(19C# zSvHI9{wHtA3=b=!7_&LjCQp&x+&702=vcpM=hLbSuRV+DWz2dTRBV1{tN!k->s4hH Syrh6hnZeW5&t;ucLK6Uvi$}Bo literal 0 HcmV?d00001 From 760f08fd0eed28736a2f1388c53c177791c84b47 Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 04:06:50 +0000 Subject: [PATCH 2/9] Update protean_reconstitutor.dm --- code/game/machinery/protean_reconstitutor.dm | 68 ++++++++++++++------ 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/code/game/machinery/protean_reconstitutor.dm b/code/game/machinery/protean_reconstitutor.dm index 0b6b3f420c2..96ea83b24c1 100644 --- a/code/game/machinery/protean_reconstitutor.dm +++ b/code/game/machinery/protean_reconstitutor.dm @@ -11,18 +11,28 @@ use_power = USE_POWER_IDLE idle_power_usage = 10 active_power_usage = 1000 - clicksound = 'sound/machines/buttonbeep.ogg' - var/dingsound = 'sound/machines/kitchen/microwave/microwave-end.ogg' + var/inuse = FALSE + clicksound = 'sound/machines/buttonbeep.ogg' //standard initialization sound + var/dingsound = 'sound/machines/kitchen/microwave/microwave-end.ogg' //sound to play when the process is complete //vars for basic functionality - var/obj/item/device/mmi/digital/posibrain/nano/protean_brain = null //only allow protean brains - var/obj/item/organ/internal/nano/orchestrator/protean_orchestrator = null - var/obj/item/organ/internal/nano/refactory/protean_refactory = null //not essential, but nice to have; lets us transfer stored materials + var/obj/item/device/mmi/digital/posibrain/nano/protean_brain = null //only allow protean brains, no midround upgrades to bypass the whitelist! + var/obj/item/organ/internal/nano/orchestrator/protean_orchestrator = null //essential + var/obj/item/organ/internal/nano/refactory/protean_refactory = null //not essential, but nice to have; lets us transfer stored materials var/nanomass_reserve = 0 //starting reserve var/nanotank_max = 300 //how much we can store at once, todo: upgradable var/nanomass_required = 60 //how much we need in order to make a new body, base var/nanomass_efficiency = 1 //multiplier to nanomass required, todo: upgradable var/paste_inefficiency = 5 //divisor to mech_repair value of paste added; higher = less effective + var/base_cook_time = 30 SECONDS //how long to initially delay before starting the overall cooking cycle + var/per_organ_delay = 5 SECONDS //how long to delay the cycle per organ and per synch step (multiply by six to get time for all three organs), then add base cook time for total time + + //TODO: component vars + //bin + +/obj/machinery/protean_reconstitutor/Initialize() + //TODO: spawn starting components + . = ..() /obj/machinery/protean_reconstitutor/update_icon() cut_overlays() @@ -117,41 +127,53 @@ /obj/machinery/protean_reconstitutor/attack_hand(mob/user as mob) if(!protean_brain || !protean_orchestrator || (nanomass_reserve < (nanomass_required * nanomass_efficiency))) + //no brain, no orchestrator, and/or not enough goo to_chat(user,"Essential components missing, or insufficient materials available!") update_icon() return - else if(protean_brain && protean_orchestrator && (nanomass_reserve > (nanomass_required * nanomass_efficiency))) + if(inuse) + //we're currently processing a patient, chill out! + src.visible_message("\The [src] chirps, \"Currently reconstituting [protean_brain.stored_mmi.brainmob.name], please wait!\"<\span>") + return + else if(!inuse && protean_brain && protean_orchestrator && (nanomass_reserve > (nanomass_required * nanomass_efficiency))) //we're good, let's get recombobulating! src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: 1 minute.\"") + inuse = TRUE power_change() if(prob(2)) playsound(src, 'sound/machines/blender.ogg', 50, 1) + else + playsound(src, clicksound, 50, 1) nanomass_reserve -= nanomass_required * nanomass_efficiency - sleep(20 SECONDS) //1 minute default, testing placeholder + sleep(base_cook_time) //base cook time var/mob/living/carbon/human/protean/P = new /mob/living/carbon/human/protean var/mats_cached var/list/materials_cache P.loc = src for(var/organ in P.internal_organs_by_name) + sleep(per_organ_delay) var/obj/item/O = P.internal_organs_by_name[organ] if(istype(O,/obj/item/organ/internal/nano/refactory)) if(protean_refactory) //if we have a refactory present, install it, otherwise they get a free replacement (for now; perhaps no free replacement but they can be made printable at the prosfab?) - src.visible_message("\The [src] chirps, \"Reinitializing refactory...\"") P.internal_organs_by_name.Remove(O) P.contents.Remove(O) qdel(O) P.internal_organs_by_name.Add(list(O_FACT = protean_refactory)) P.internal_organs.Add(protean_refactory) + //cache our mats otherwise they get wiped by the revive materials_cache = protean_refactory.materials.Copy() mats_cached = TRUE protean_refactory.loc = P protean_refactory = null - src.visible_message("\The [src] chirps, \"Refactory reboot complete...\"") else - src.visible_message("\The [src] chirps, \"No refactory detected in storage, fabricating replacement...\"") + sleep(per_organ_delay) continue if(istype(O,/obj/item/organ/internal/nano/orchestrator)) - src.visible_message("\The [src] chirps, \"Linking nanoswarm to orchestrator...\"") P.internal_organs_by_name.Remove(O) P.internal_organs.Remove(O) P.contents.Remove(O) @@ -160,9 +182,10 @@ P.internal_organs.Add(protean_orchestrator) protean_orchestrator.loc = P protean_orchestrator = null - src.visible_message("\The [src] chirps, \"Secure nanoswarm network established...\"") if(istype(O,/obj/item/organ/internal/mmi_holder/posibrain/nano)) - src.visible_message("\The [src] chirps, \"Synchronizing positronic neural architecture...\"") var/obj/item/organ/internal/mmi_holder/posibrain/nano/BR = O BR.stored_mmi = null //toss the dummy... BR.contents.Cut() @@ -173,24 +196,31 @@ P.client = protean_brain.brainmob.client protean_brain.loc = BR protean_brain = null - src.visible_message("\The [src] chirps, \"Neural architecture [BR.stored_mmi.brainmob.name] synchronized to network...\"") + //run a little revive, load their prefs, and boot a new NIF on them for the finishing touches and cleanup... (yes, we need to initialize a new NIF, they don't get one from the revive process) + //using revive is honestly a bit overkill since it kinda deletes-and-replaces most of the guts anyway (hence the cache and restore of refactory contents; otherwise they get wiped!), but it also ensures the new protean comes out in their "base form" as well as cleaning up some loose ends in the resurrection process P.revive() + P.apply_vore_prefs() + var/obj/item/device/nif/protean/new_nif = new() + new_nif.quick_implant(P) + //revive complete, now restore the cached mats (if we had any) if(mats_cached == TRUE) + src.visible_message("\The [src] chirps, \"Reindexing archived refactory materials storage.\"") for(var/organ in P.internal_organs_by_name) var/obj/item/O = P.internal_organs_by_name[organ] if(istype(O,/obj/item/organ/internal/nano/refactory)) var/obj/item/organ/internal/nano/refactory/RF = O - src.visible_message("\The [src] chirps, \"Refactory storage indexing complete...\"") RF.materials = materials_cache.Copy() materials_cache.Cut() mats_cached = FALSE - var/obj/item/device/nif/protean/new_nif = new() - new_nif.quick_implant(P) //finally... drop them in front of the machine! sleep(1 SECOND) - src.visible_message("\The [src] chirps, \"Protean reconstitution cycle complete!\"") + to_chat(P,"You feel your sense of self expanding, spreading out to inhabit your new \'body\'. You feel... ALIVE!") playsound(src, dingsound, 100, 1, -1) //soup's on! P.loc = src.loc + inuse = FALSE update_icon() update_icon() From e1b5c96f3f5a08608568b4c596b9d3cb5447134c Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 06:11:03 +0000 Subject: [PATCH 3/9] Update protean_reconstitutor.dm --- code/game/machinery/protean_reconstitutor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/protean_reconstitutor.dm b/code/game/machinery/protean_reconstitutor.dm index 96ea83b24c1..01215c2998e 100644 --- a/code/game/machinery/protean_reconstitutor.dm +++ b/code/game/machinery/protean_reconstitutor.dm @@ -133,7 +133,7 @@ return if(inuse) //we're currently processing a patient, chill out! - src.visible_message("\The [src] chirps, \"Currently reconstituting [protean_brain.stored_mmi.brainmob.name], please wait!\"<\span>") + src.visible_message("\The [src] chirps, \"Currently reconstituting [protean_brain.stored_mmi.brainmob.name], please wait!\"") return else if(!inuse && protean_brain && protean_orchestrator && (nanomass_reserve > (nanomass_required * nanomass_efficiency))) //we're good, let's get recombobulating! From ad5920ba94a412b57cae07b17d4c513d3f67a999 Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 09:03:21 +0000 Subject: [PATCH 4/9] Update protean_reconstitutor.dm --- code/game/machinery/protean_reconstitutor.dm | 81 ++++++++++++++------ 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/code/game/machinery/protean_reconstitutor.dm b/code/game/machinery/protean_reconstitutor.dm index 01215c2998e..0920462cc84 100644 --- a/code/game/machinery/protean_reconstitutor.dm +++ b/code/game/machinery/protean_reconstitutor.dm @@ -11,7 +11,7 @@ use_power = USE_POWER_IDLE idle_power_usage = 10 active_power_usage = 1000 - var/inuse = FALSE + var/processing_revive = FALSE clicksound = 'sound/machines/buttonbeep.ogg' //standard initialization sound var/dingsound = 'sound/machines/kitchen/microwave/microwave-end.ogg' //sound to play when the process is complete @@ -25,7 +25,8 @@ var/nanomass_efficiency = 1 //multiplier to nanomass required, todo: upgradable var/paste_inefficiency = 5 //divisor to mech_repair value of paste added; higher = less effective var/base_cook_time = 30 SECONDS //how long to initially delay before starting the overall cooking cycle - var/per_organ_delay = 5 SECONDS //how long to delay the cycle per organ and per synch step (multiply by six to get time for all three organs), then add base cook time for total time + var/per_organ_delay = 10 SECONDS //how long to delay the cycle per organ and per synch step (multiply by three to get time for all three organs), then add base cook time for total time + var/finalize_time = 30 SECONDS //finally, how long we need before popping them out of the tank //TODO: component vars //bin @@ -131,25 +132,28 @@ to_chat(user,"Essential components missing, or insufficient materials available!") update_icon() return - if(inuse) + if(processing_revive) //we're currently processing a patient, chill out! - src.visible_message("\The [src] chirps, \"Currently reconstituting [protean_brain.stored_mmi.brainmob.name], please wait!\"") + src.visible_message("\The [src] chirps, \"Reconstitution cycle currently in progress, please wait!\"") return - else if(!inuse && protean_brain && protean_orchestrator && (nanomass_reserve > (nanomass_required * nanomass_efficiency))) + else if(!processing_revive && protean_brain && protean_orchestrator && (nanomass_reserve >= (nanomass_required * nanomass_efficiency))) //we're good, let's get recombobulating! - src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: 1 minute.\"") - inuse = TRUE + src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: 1 minute, 30 seconds.\"") + processing_revive = TRUE power_change() if(prob(2)) playsound(src, 'sound/machines/blender.ogg', 50, 1) else playsound(src, clicksound, 50, 1) nanomass_reserve -= nanomass_required * nanomass_efficiency - sleep(base_cook_time) //base cook time + sleep(base_cook_time) var/mob/living/carbon/human/protean/P = new /mob/living/carbon/human/protean var/mats_cached var/list/materials_cache P.loc = src + P.name = "Unfinished Protean" + P.real_name = "Unfinished Protean" + P.AdjustSleeping(60) //be eepy until well after the synch process completes for(var/organ in P.internal_organs_by_name) sleep(per_organ_delay) var/obj/item/O = P.internal_organs_by_name[organ] @@ -166,11 +170,8 @@ mats_cached = TRUE protean_refactory.loc = P protean_refactory = null - sleep(per_organ_delay) - src.visible_message("\The [src] chirps, \"Refactory reboot complete...\"") else src.visible_message("\The [src] chirps, \"No refactory detected in storage, fabricating replacement...\"") - sleep(per_organ_delay) continue if(istype(O,/obj/item/organ/internal/nano/orchestrator)) src.visible_message("\The [src] chirps, \"Linking nanoswarm to orchestrator...\"") @@ -182,8 +183,6 @@ P.internal_organs.Add(protean_orchestrator) protean_orchestrator.loc = P protean_orchestrator = null - sleep(per_organ_delay) - src.visible_message("\The [src] chirps, \"Secure nanoswarm network established...\"") if(istype(O,/obj/item/organ/internal/mmi_holder/posibrain/nano)) src.visible_message("\The [src] chirps, \"Synchronizing positronic neural architecture...\"") var/obj/item/organ/internal/mmi_holder/posibrain/nano/BR = O @@ -191,17 +190,53 @@ BR.contents.Cut() BR.stored_mmi = protean_brain //...and implant the salvaged mmi in its place BR.contents.Add(protean_brain) - P.ckey = protean_brain.brainmob.ckey - P.mind = protean_brain.brainmob.mind - P.client = protean_brain.brainmob.client + var/client/posibrain_client = protean_brain.brainmob.client + var/picked_ckey = posibrain_client.ckey + var/picked_slot = posibrain_client.prefs.default_slot + var/charjob + var/datum/data/record/record_found + record_found = find_general_record("name",posibrain_client.prefs.real_name) + if(record_found) + charjob = record_found.fields["real_rank"] + else + return + if(P.dna) + P.dna.ResetUIFrom(P) + P.sync_organ_dna() + + if(P.mind) + P.mind.loaded_from_ckey = picked_ckey + P.mind.loaded_from_slot = picked_slot + var/datum/antagonist/antag_data = get_antag_data(P.mind.special_role) + if(antag_data) + antag_data.add_antagonist(P.mind) + antag_data.place_mob(P) + P.mind.assigned_role = charjob + P.mind.role_alt_title = job_master.GetPlayerAltTitle(P, charjob) + + //no need to be particularly thorough about language handover, we can safely assume that they were allowed to have it if they had it to begin with + P.languages.Cut() + P.languages = protean_brain.brainmob.languages.Copy() + + for(var/key in posibrain_client.prefs.language_custom_keys) + if(posibrain_client.prefs.language_custom_keys[key]) + var/datum/language/keylang = GLOB.all_languages[posibrain_client.prefs.language_custom_keys[key]] + if(keylang) + P.language_keys[key] = keylang + + if(posibrain_client.prefs.preferred_language) + var/datum/language/def_lang = GLOB.all_languages[posibrain_client.prefs.preferred_language] + if(def_lang) + P.default_language = def_lang + + protean_brain.brainmob.mind.transfer_to(P) protean_brain.loc = BR protean_brain = null - sleep(per_organ_delay) - src.visible_message("\The [src] chirps, \"Neural architecture [BR.stored_mmi.brainmob.name] synchronized to network...\"") - //run a little revive, load their prefs, and boot a new NIF on them for the finishing touches and cleanup... (yes, we need to initialize a new NIF, they don't get one from the revive process) - //using revive is honestly a bit overkill since it kinda deletes-and-replaces most of the guts anyway (hence the cache and restore of refactory contents; otherwise they get wiped!), but it also ensures the new protean comes out in their "base form" as well as cleaning up some loose ends in the resurrection process + sleep(finalize_time) //let 'em cook a tiny bit longer P.revive() P.apply_vore_prefs() + //run a little revive, load their prefs, and boot a new NIF on them for the finishing touches and cleanup... (yes, we need to initialize a new NIF, they don't get one from the revive process) + //using revive is honestly a bit overkill since it kinda deletes-and-replaces most of the guts anyway (hence the cache and restore of refactory contents; otherwise they get wiped!), but it also ensures the new protean comes out in their "base form" as well as hopefully cleaning up any loose ends in the resurrection process var/obj/item/device/nif/protean/new_nif = new() new_nif.quick_implant(P) //revive complete, now restore the cached mats (if we had any) @@ -211,16 +246,14 @@ var/obj/item/O = P.internal_organs_by_name[organ] if(istype(O,/obj/item/organ/internal/nano/refactory)) var/obj/item/organ/internal/nano/refactory/RF = O - src.visible_message("\The [src] chirps, \"Refactory storage indexing complete...\"") RF.materials = materials_cache.Copy() materials_cache.Cut() mats_cached = FALSE - //finally... drop them in front of the machine! - sleep(1 SECOND) + //finally... drop them in front of the machine src.visible_message("\The [src] chirps, \"Protean reconstitution cycle complete!\"") to_chat(P,"You feel your sense of self expanding, spreading out to inhabit your new \'body\'. You feel... ALIVE!") playsound(src, dingsound, 100, 1, -1) //soup's on! P.loc = src.loc - inuse = FALSE + processing_revive = FALSE update_icon() update_icon() From e41b05f472fb223dacd7093de12134bc0a599bd1 Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 09:03:34 +0000 Subject: [PATCH 5/9] Update nano.dm some necessary fixes for procs --- code/modules/organs/subtypes/nano.dm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/code/modules/organs/subtypes/nano.dm b/code/modules/organs/subtypes/nano.dm index bab2ac7b653..f717ef3f1fc 100644 --- a/code/modules/organs/subtypes/nano.dm +++ b/code/modules/organs/subtypes/nano.dm @@ -93,6 +93,14 @@ /mob/living/carbon/human/proc/self_diagnostics ) +/obj/item/organ/internal/nano/orchestrator/robotize() + . = ..() + icon_state = "orchestrator" + +/obj/item/organ/internal/nano/orchestrator/mechassist() + . = ..() + icon_state = "orchestrator" + /obj/item/organ/internal/nano/refactory name = "refactory module" desc = "A miniature metal processing unit and nanite factory." @@ -107,6 +115,14 @@ /mob/living/carbon/human/proc/reagent_purge ) +/obj/item/organ/internal/nano/refactory/robotize() + . = ..() + icon_state = "refactory" + +/obj/item/organ/internal/nano/refactory/mechassist() + . = ..() + icon_state = "refactory" + /obj/item/organ/internal/nano/refactory/proc/get_stored_material(var/material) if(status & ORGAN_DEAD) return 0 From ce93d40c1ca11ed161874a0a69587520a7a736eb Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:54:19 +0000 Subject: [PATCH 6/9] protean reconstitutor construction, components, and upgrades --- code/game/machinery/protean_reconstitutor.dm | 72 ++++++++++++++----- .../circuitboards/machinery/research.dm | 11 +++ .../research/designs/circuits/circuits.dm | 7 ++ 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/code/game/machinery/protean_reconstitutor.dm b/code/game/machinery/protean_reconstitutor.dm index 0920462cc84..9bd314a70f7 100644 --- a/code/game/machinery/protean_reconstitutor.dm +++ b/code/game/machinery/protean_reconstitutor.dm @@ -1,7 +1,7 @@ /obj/machinery/protean_reconstitutor name = "protean reconstitutor" desc = "A complex machine that is most definitely not just a large tub into which one pours a large amount of untethered nanites, then adds a protean positronic brain and orchestrator, in order to reconstitute a disintegrated protean... it's complicated, really!" - description_info = "Use a protean positronic brain, orchestrator, optionally a refactory, and nanopaste to \'fill\' the machine, then interact with it once it's ready. Protean components can be retrieved using a wrench, but any nanopaste inserted will be converted and cannot be reclaimed!" + description_info = "Use a protean positronic brain, orchestrator, optionally a refactory, and nanopaste to \'fill\' the machine, then interact with it once it's ready. Protean components can be retrieved using a wrench, but any nanopaste inserted will be converted, cannot be reclaimed, and will be lost if the machine is disassembled!" icon = 'icons/obj/protean_recon.dmi' icon_state = "recon-nopower" var/state_base = "recon" @@ -19,22 +19,40 @@ var/obj/item/device/mmi/digital/posibrain/nano/protean_brain = null //only allow protean brains, no midround upgrades to bypass the whitelist! var/obj/item/organ/internal/nano/orchestrator/protean_orchestrator = null //essential var/obj/item/organ/internal/nano/refactory/protean_refactory = null //not essential, but nice to have; lets us transfer stored materials - var/nanomass_reserve = 0 //starting reserve - var/nanotank_max = 300 //how much we can store at once, todo: upgradable - var/nanomass_required = 60 //how much we need in order to make a new body, base - var/nanomass_efficiency = 1 //multiplier to nanomass required, todo: upgradable - var/paste_inefficiency = 5 //divisor to mech_repair value of paste added; higher = less effective - var/base_cook_time = 30 SECONDS //how long to initially delay before starting the overall cooking cycle - var/per_organ_delay = 10 SECONDS //how long to delay the cycle per organ and per synch step (multiply by three to get time for all three organs), then add base cook time for total time - var/finalize_time = 30 SECONDS //finally, how long we need before popping them out of the tank + var/nanomass_reserve = 0 //starting reserve - will be wiped if it's deconstructed! + var/nanotank_max = 300 //how much we can store at once, higher = better + var/nanomass_required = 150 //how much we need in order to make a new body, non-adjustable + var/paste_inefficiency = 5 //divisor to mech_repair value of paste added; higher = less effective; adv paste is +40 reserve at base, or +200 at max! + var/base_cook_time = 150 SECONDS //how long to initially delay before starting the overall cooking cycle + var/per_organ_delay = 30 SECONDS //how long to delay the cycle per organ and per synch step (multiply by three to get time for all three organs), then add base cook time for total time + var/finalize_time = 150 SECONDS //finally, how long we need before popping them out of the tank - //TODO: component vars - //bin + //component vars + circuit = /obj/item/weapon/circuitboard/protean_reconstitutor /obj/machinery/protean_reconstitutor/Initialize() - //TODO: spawn starting components + component_parts = list() + component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) + component_parts += new /obj/item/weapon/stock_parts/manipulator(src) + component_parts += new /obj/item/weapon/stock_parts/console_screen(src) + component_parts += new /obj/item/stack/cable_coil(src, 5) + RefreshParts() . = ..() +/obj/machinery/protean_reconstitutor/RefreshParts() + //total paste storage cap (300 * the rating, straightforward) + var/store_rating = initial(nanotank_max) + for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) + store_rating = store_rating * MB.rating + nanotank_max = store_rating + + //inefficiency of adding paste (amount of uses * (mech_repair / inefficiency)); most complex, good way to get good bang for your buck tho + var/paste_rating = initial(paste_inefficiency) + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + paste_rating = paste_rating - (M.rating - 1) + paste_inefficiency = paste_rating + ..() + /obj/machinery/protean_reconstitutor/update_icon() cut_overlays() if(stat & (NOPOWER|BROKEN) || !anchored) @@ -50,7 +68,7 @@ add_overlay("[state_base]-orchestrator") if(protean_refactory) add_overlay("[state_base]-refactory") - if(nanomass_reserve >= nanomass_required * nanomass_efficiency) + if(nanomass_reserve >= nanomass_required) add_overlay("[state_base]-tank_full") /obj/machinery/protean_reconstitutor/examine() @@ -65,13 +83,26 @@ . += "It currently has both a positronic brain and orchestrator ready!" else . += "It currently lacks both a positronic brain and orchestrator." - . += "The readout shows that it has [nanomass_reserve] units of nanites ready for use. It requires [nanomass_required * nanomass_efficiency] per \'revive\' process, and has a maximum capacity of [nanotank_max] units." + . += "The readout shows that it has [nanomass_reserve] units of nanites ready for use. It requires [nanomass_required] per \'revive\' process, and has a maximum capacity of [nanotank_max] units." /obj/machinery/protean_reconstitutor/attackby(obj/item/W as obj, mob/user as mob) src.add_fingerprint(user) + if(processing_revive) + to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") + return + + if(default_deconstruction_screwdriver(user, W)) + return + if(default_deconstruction_crowbar(user, W)) + return + if(default_part_replacement(user, W)) + return if(istype(W,/obj/item/device/mmi/digital/posibrain/nano)) var/obj/item/device/mmi/digital/posibrain/nano/NB = W + if(!NB.brainmob.client) + to_chat(user,"You cannot use an inactive positronic brain for this process.") + return to_chat(user,"You slot \the [NB] into \the [src].") user.drop_from_inventory(NB) NB.loc = src @@ -124,10 +155,10 @@ to_chat(user, "\The [src] does not have any protean components you can retrieve.") update_icon() - return ..() + ..() /obj/machinery/protean_reconstitutor/attack_hand(mob/user as mob) - if(!protean_brain || !protean_orchestrator || (nanomass_reserve < (nanomass_required * nanomass_efficiency))) + if(!protean_brain || !protean_orchestrator || (nanomass_reserve < nanomass_required)) //no brain, no orchestrator, and/or not enough goo to_chat(user,"Essential components missing, or insufficient materials available!") update_icon() @@ -136,16 +167,19 @@ //we're currently processing a patient, chill out! src.visible_message("\The [src] chirps, \"Reconstitution cycle currently in progress, please wait!\"") return - else if(!processing_revive && protean_brain && protean_orchestrator && (nanomass_reserve >= (nanomass_required * nanomass_efficiency))) + if(!protean_brain.brainmob.client) + src.visible_message("\The [src] chirps, \"Warning, no positronic neural network activity detected! Recommend removing inactive core.\"") + return + else if(!processing_revive && protean_brain && protean_orchestrator && (nanomass_reserve >= nanomass_required)) //we're good, let's get recombobulating! - src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: 1 minute, 30 seconds.\"") + src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: [base_cook_time+(per_organ_delay*3)+finalize_time SECONDS] seconds.\"") processing_revive = TRUE power_change() if(prob(2)) playsound(src, 'sound/machines/blender.ogg', 50, 1) else playsound(src, clicksound, 50, 1) - nanomass_reserve -= nanomass_required * nanomass_efficiency + nanomass_reserve -= nanomass_required sleep(base_cook_time) var/mob/living/carbon/human/protean/P = new /mob/living/carbon/human/protean var/mats_cached diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/weapons/circuitboards/machinery/research.dm index 380de53fd26..8f23291f8aa 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/research.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/research.dm @@ -94,3 +94,14 @@ origin_tech = list(TECH_DATA = 4) req_components = list( /obj/item/stack/cable_coil = 15) + +/obj/item/weapon/circuitboard/protean_reconstitutor + name = T_BOARD("protean reconstitutor") + board_type = new /datum/frame/frame_types/machine + build_path = /obj/machinery/protean_reconstitutor + origin_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5) + req_components = list( + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/stock_parts/manipulator = 1, + /obj/item/weapon/stock_parts/console_screen = 1, + /obj/item/stack/cable_coil = 5) diff --git a/code/modules/research/designs/circuits/circuits.dm b/code/modules/research/designs/circuits/circuits.dm index cd28842f00a..0c73a001b4c 100644 --- a/code/modules/research/designs/circuits/circuits.dm +++ b/code/modules/research/designs/circuits/circuits.dm @@ -441,6 +441,13 @@ CIRCUITS BELOW build_path = /obj/item/weapon/circuitboard/arf_generator sort_string = "LAAAD" +/datum/design/circuit/protean_reconstitutor + name = "protean reconstitutor" + id = "protean_recon" + req_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_DATA = 5) + build_path = /obj/item/weapon/circuitboard/protean_reconstitutor + sort_string = "LAAAE" + /datum/design/circuit/mecha req_tech = list(TECH_DATA = 3) From e029a9e558562f6aac7c498dc4bb9f293ce6ced1 Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 10:57:13 +0000 Subject: [PATCH 7/9] Update vorestation.dme --- vorestation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/vorestation.dme b/vorestation.dme index e18f429d42f..d7c3cced313 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -876,6 +876,7 @@ #include "code\game\machinery\pointdefense.dm" #include "code\game\machinery\portable_turret.dm" #include "code\game\machinery\portable_turret_vr.dm" +#include "code\game\machinery\protean_reconstitutor.dm" #include "code\game\machinery\recharger.dm" #include "code\game\machinery\rechargestation.dm" #include "code\game\machinery\requests_console.dm" From 4f2c96bc3b56c5ed78f838f9398e75b17c271d0b Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Fri, 1 Dec 2023 21:39:24 +0000 Subject: [PATCH 8/9] Update protean_reconstitutor.dm safety check for loss of client mid-procedure, stops the machine from getting jammed up --- code/game/machinery/protean_reconstitutor.dm | 44 +++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/code/game/machinery/protean_reconstitutor.dm b/code/game/machinery/protean_reconstitutor.dm index 9bd314a70f7..9ae0261d077 100644 --- a/code/game/machinery/protean_reconstitutor.dm +++ b/code/game/machinery/protean_reconstitutor.dm @@ -14,6 +14,7 @@ var/processing_revive = FALSE clicksound = 'sound/machines/buttonbeep.ogg' //standard initialization sound var/dingsound = 'sound/machines/kitchen/microwave/microwave-end.ogg' //sound to play when the process is complete + var/buzzsound = 'sound/items/nif_tone_bad.ogg' //sound to play when we have to abort due to loss of posibrain client //vars for basic functionality var/obj/item/device/mmi/digital/posibrain/nano/protean_brain = null //only allow protean brains, no midround upgrades to bypass the whitelist! @@ -23,9 +24,11 @@ var/nanotank_max = 300 //how much we can store at once, higher = better var/nanomass_required = 150 //how much we need in order to make a new body, non-adjustable var/paste_inefficiency = 5 //divisor to mech_repair value of paste added; higher = less effective; adv paste is +40 reserve at base, or +200 at max! + + //time vars var/base_cook_time = 150 SECONDS //how long to initially delay before starting the overall cooking cycle - var/per_organ_delay = 30 SECONDS //how long to delay the cycle per organ and per synch step (multiply by three to get time for all three organs), then add base cook time for total time - var/finalize_time = 150 SECONDS //finally, how long we need before popping them out of the tank + var/per_organ_delay = 5 SECONDS //how long to delay the cycle per organ and per synch step (multiply by three to get time for all three organs), then add base cook time for total time + var/finalize_time = 135 SECONDS //finally, how long we need before popping them out of the tank //component vars circuit = /obj/item/weapon/circuitboard/protean_reconstitutor @@ -74,21 +77,20 @@ /obj/machinery/protean_reconstitutor/examine() . = ..() if(protean_refactory) - . += "A protean refactory appears to be present." - if(protean_brain && !protean_orchestrator) - . += "It currently has a protean positronic brain ready, but still needs an orchestrator." - else if(protean_orchestrator && !protean_brain) - . += "It currently has an orchestrator ready, but lacks a protean positronic brain." - else if(protean_orchestrator && protean_brain) - . += "It currently has both a positronic brain and orchestrator ready!" - else - . += "It currently lacks both a positronic brain and orchestrator." + . += "A protean refactory is present." + if(protean_orchestrator) + . += "A protean orchestrator is present." + if(protean_brain) + . += "It currently has a protean positronic brain." + if(!protean_brain.brainmob.client) + . += "The positronic brain appears to be inactive!" . += "The readout shows that it has [nanomass_reserve] units of nanites ready for use. It requires [nanomass_required] per \'revive\' process, and has a maximum capacity of [nanotank_max] units." /obj/machinery/protean_reconstitutor/attackby(obj/item/W as obj, mob/user as mob) src.add_fingerprint(user) if(processing_revive) to_chat(user, "\The [src] is busy. Please wait for completion of previous operation.") + playsound(src, buzzsound, 100, 1, -1) return if(default_deconstruction_screwdriver(user, W)) @@ -161,18 +163,20 @@ if(!protean_brain || !protean_orchestrator || (nanomass_reserve < nanomass_required)) //no brain, no orchestrator, and/or not enough goo to_chat(user,"Essential components missing, or insufficient materials available!") + playsound(src, buzzsound, 100, 1, -1) update_icon() return if(processing_revive) //we're currently processing a patient, chill out! src.visible_message("\The [src] chirps, \"Reconstitution cycle currently in progress, please wait!\"") + playsound(src, buzzsound, 100, 1, -1) return if(!protean_brain.brainmob.client) src.visible_message("\The [src] chirps, \"Warning, no positronic neural network activity detected! Recommend removing inactive core.\"") return else if(!processing_revive && protean_brain && protean_orchestrator && (nanomass_reserve >= nanomass_required)) //we're good, let's get recombobulating! - src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: [base_cook_time+(per_organ_delay*3)+finalize_time SECONDS] seconds.\"") + src.visible_message("[user] initializes \the [src]. It chirps, \"Please stand by, synchronizing components... estimated time to completion: five minutes.\"") processing_revive = TRUE power_change() if(prob(2)) @@ -187,7 +191,6 @@ P.loc = src P.name = "Unfinished Protean" P.real_name = "Unfinished Protean" - P.AdjustSleeping(60) //be eepy until well after the synch process completes for(var/organ in P.internal_organs_by_name) sleep(per_organ_delay) var/obj/item/O = P.internal_organs_by_name[organ] @@ -203,7 +206,6 @@ materials_cache = protean_refactory.materials.Copy() mats_cached = TRUE protean_refactory.loc = P - protean_refactory = null else src.visible_message("\The [src] chirps, \"No refactory detected in storage, fabricating replacement...\"") continue @@ -216,9 +218,17 @@ P.internal_organs_by_name.Add(list(O_ORCH = protean_orchestrator)) P.internal_organs.Add(protean_orchestrator) protean_orchestrator.loc = P - protean_orchestrator = null if(istype(O,/obj/item/organ/internal/mmi_holder/posibrain/nano)) src.visible_message("\The [src] chirps, \"Synchronizing positronic neural architecture...\"") + //on the offchance our client blipped before getting to this step, abort, schloop the organs back into the machine, dissolve the body, and refund the nanos + if(!protean_brain.brainmob.client) + src.visible_message("\The [src] buzzes, \"No positronic neural activity detected! Aborting cycle!\"") + playsound(src, buzzsound, 100, 1, -1) + processing_revive = FALSE + qdel(P) + nanomass_reserve += nanomass_required + update_icon() + return var/obj/item/organ/internal/mmi_holder/posibrain/nano/BR = O BR.stored_mmi = null //toss the dummy... BR.contents.Cut() @@ -265,7 +275,9 @@ protean_brain.brainmob.mind.transfer_to(P) protean_brain.loc = BR - protean_brain = null + protean_refactory = null + protean_brain = null + protean_orchestrator = null sleep(finalize_time) //let 'em cook a tiny bit longer P.revive() P.apply_vore_prefs() From da279dc6a55e38214588461b3d5b1d677c94240b Mon Sep 17 00:00:00 2001 From: Killian <49700375+KillianKirilenko@users.noreply.github.com> Date: Sat, 2 Dec 2023 08:15:43 +0000 Subject: [PATCH 9/9] resprited and mapped in --- icons/obj/protean_recon.dmi | Bin 760 -> 1059 bytes maps/stellar_delight/stellar_delight1.dmm | 16 +++++++----- maps/tether/tether-03-surface3.dmm | 29 ++++++++++++++++------ 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/icons/obj/protean_recon.dmi b/icons/obj/protean_recon.dmi index f34e0a109226cec494516247f28eae5f7f608ae5..9620e5f504a84df1aaa5f55112f0279432942f8d 100644 GIT binary patch literal 1059 zcmV+;1l;?HP)C0000#P)t-sz`(!& z006GB#Yak8U}JR{86P(~OO%(Z|Ns96JpdHk0AgZdX=!OqO-)BiT#JyZOHN^C|1-eA zz%!Zu|I7d%txZh;0004WQchCV=-0C=2@k--Xs zFbsyz?Nb!J>e#02w#!h4hxrPlYFvw5JJN3A+pkX8KpaRe`NPMbpCn|b{9KeQyA<>V zXr2EO~N|vz_$THZFH>7!}NdwC5=Su=Q~PTpw`qq4pmUVD7_ z$A>I0v(IbZ_x^bpa}c330008YNklL7I|FmVv;4R~ z-4q#6m%j-Kqoj=SG?-ZzVHABuI5C*`Vftdh%3FeYF3ePX!S#Xh{8)eg z#Pxx5_<{9-bNG?J4RC{L6~ljk!6ts*edNxebu(>c-hqACp#{YSM8x@#jbN<=2Eu zSHI?OQ+;2-ok8H?+fbuRkrTb-%dr)o#qw*U2@jKe@SApJlbDu;fL$ z2Ez3DIZU{;-WKV-Pkq+6*W24qH^5@CSS%Kc#bU8oEY{c1`#T-;@$sDvuvjb> di^Y1H{sX-*YjS&Vw!{Dc002ovPDHLkV1f>l2nzrJ literal 760 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoORGX6N?cNllZ!G7N;32F7#J$% z^qxP<)odWZ@}T&WNcTM5zq_9WO_|iZ&&jhiw`rE{?A)dK_nVi?aqT>N;P`5Ho5;n$D$e8h6l;oyznHA=Rbu6kRfnA8mlE@Y)_ ze=x1Sbl$3WKEltE3JZ7juCF{NSFTt-d&l<~Epr2&9quYD*(*^0@2AkLb!|Yixu3qy z-x91fDTRT7iO?FUJhbO=|Gk0n{Y|SJ<BF4j&DTCIKdz>^^x?J7`tz$_UOPX% zIB(nceJ|3DWq*89I4}F*rNZ=n-OA*-tP*Vx-&i_sq_}-@ZIye|7o)C)uYB zW~<(h=}%^u!I;3-AjyyhWVm_P-~E#v*WvoNIlk{XkHpnIvX5GC^vv3PKyrf;TZ7N( z35;%A^E>^4G+56g%LM_|fAx=l_L6u|dVp&O%i0!3hI`ymg3Jea7>pU-ys>(4t#4!0 zi;vS|Cg|RLTgIP$z-jt#=jU?z_If{Ob#xqi`%)*J;S7U8{xQ*A&e2cTW&Gb|KUe(R zImX)i;gyWB*JJ0-D9bh9^S(NzI3)M(LfK^;dX5GV!-2X;VQdI}+jnnk?9{oH*|!?E zuVOfVLY1TKeV?D^MSaGty&W0x=l<`@{Qq;t|M_9rbN)XuVa}52De5^basE^>(19C# zSvHI9{wHtA3=b=!7_&LjCQp&x+&702=vcpM=hLbSuRV+DWz2dTRBV1{tN!k->s4hH Syrh6hnZeW5&t;ucLK6Uvi$}Bo diff --git a/maps/stellar_delight/stellar_delight1.dmm b/maps/stellar_delight/stellar_delight1.dmm index 10768614d8d..15f67ee6a03 100644 --- a/maps/stellar_delight/stellar_delight1.dmm +++ b/maps/stellar_delight/stellar_delight1.dmm @@ -219,6 +219,9 @@ icon_state = "0-4" }, /obj/item/weapon/storage/box/backup_kit, +/obj/machinery/atmospherics/unary/vent_pump/on{ + dir = 1 + }, /turf/simulated/floor/tiled/steel_dirty, /area/assembly/robotics) "aw" = ( @@ -1029,6 +1032,8 @@ /obj/machinery/light{ dir = 1 }, +/obj/structure/table/standard, +/obj/machinery/cell_charger, /turf/simulated/floor/bluegrid, /area/assembly/robotics) "bX" = ( @@ -8541,6 +8546,9 @@ /obj/effect/floor_decal/steeldecal/steel_decals4{ dir = 6 }, +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 6 + }, /turf/simulated/floor/tiled/steel_dirty, /area/assembly/robotics) "rw" = ( @@ -8967,16 +8975,12 @@ /turf/simulated/floor, /area/maintenance/security_port) "sq" = ( -/obj/structure/table/standard, -/obj/machinery/cell_charger, /obj/structure/cable/green{ color = "#42038a"; icon_state = "4-8" }, /obj/machinery/light, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 1 - }, +/obj/machinery/protean_reconstitutor, /turf/simulated/floor/tiled/steel, /area/assembly/robotics) "sr" = ( @@ -19770,7 +19774,7 @@ /area/medical/exam_room) "Qq" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 6 + dir = 4 }, /turf/simulated/floor/tiled/steel, /area/assembly/robotics) diff --git a/maps/tether/tether-03-surface3.dmm b/maps/tether/tether-03-surface3.dmm index b288e9854d2..c832f86200a 100644 --- a/maps/tether/tether-03-surface3.dmm +++ b/maps/tether/tether-03-surface3.dmm @@ -34770,10 +34770,13 @@ /obj/machinery/alarm{ pixel_y = 30 }, +/obj/machinery/atmospherics/unary/vent_scrubber/on, +/obj/effect/floor_decal/industrial/warning{ + dir = 4 + }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/robotics/resleeving) "bky" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on, /obj/machinery/button/windowtint{ id = "robo_resleeving"; pixel_x = 10; @@ -34783,7 +34786,8 @@ pixel_x = -10; pixel_y = 22 }, -/turf/simulated/floor/tiled/steel_grid, +/obj/machinery/protean_reconstitutor, +/turf/simulated/floor/tiled/dark, /area/rnd/robotics/resleeving) "bkz" = ( /obj/machinery/light{ @@ -34798,6 +34802,9 @@ /obj/structure/cable/green{ icon_state = "0-2" }, +/obj/effect/floor_decal/industrial/warning{ + dir = 8 + }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/robotics/resleeving) "bkA" = ( @@ -34888,30 +34895,36 @@ /turf/simulated/floor/tiled/steel_grid, /area/rnd/robotics/resleeving) "bkJ" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 10 }, /obj/structure/cable/green{ icon_state = "4-8" }, -/turf/simulated/floor/tiled/steel_grid, -/area/rnd/robotics/resleeving) -"bkK" = ( /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 9 }, +/obj/effect/floor_decal/industrial/warning/corner{ + dir = 4 + }, +/turf/simulated/floor/tiled/steel_grid, +/area/rnd/robotics/resleeving) +"bkK" = ( /obj/structure/cable/green{ icon_state = "4-8" }, +/obj/effect/floor_decal/industrial/warning{ + dir = 1 + }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/robotics/resleeving) "bkL" = ( /obj/structure/cable/green{ icon_state = "1-8" }, +/obj/effect/floor_decal/industrial/warning/corner{ + dir = 1 + }, /turf/simulated/floor/tiled/steel_grid, /area/rnd/robotics/resleeving) "bkM" = (