From bb6c77dd5782fa83e7e83b8edfab290b86a7d66b Mon Sep 17 00:00:00 2001 From: BlackMajor Date: Mon, 19 Sep 2022 14:40:29 +1200 Subject: [PATCH] Total Reassembly --- code/modules/organs/organ_external.dm | 3 +- .../species/station/protean/protean_powers.dm | 128 ++++-------------- .../species/station/protean/protean_rig.dm | 44 +++--- .../mob/living/carbon/human/update_icons.dm | 45 ++++++ 4 files changed, 100 insertions(+), 120 deletions(-) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 52e4e164c9..cd2a045a2d 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -117,8 +117,7 @@ /obj/item/organ/external/emp_act(severity) for(var/obj/O as anything in src.contents) O.emp_act(severity) - - if((!(robotic >= ORGAN_ROBOT)) || (robotic = ORGAN_NANOFORM)) //CHOMPEdit - Proteans handle EMP's differently + if(!(robotic >= ORGAN_ROBOT) || robotic == ORGAN_NANOFORM) //CHOMPEdit - Proteans handle EMP's differently return var/burn_damage = 0 for(var/i = 1; i <= robotic; i++) diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm index 55110ea1f2..452abf136a 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_powers.dm @@ -89,113 +89,39 @@ update_icons_body() /mob/living/carbon/human/proc/nano_regenerate() - set name = "Total Reassembly (wip)" - set desc = "Completely reassemble yourself from whatever save slot you have loaded in preferences. Assuming you meet the requirements." + set name = "Total Reassembly" + set desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded." set category = "Abilities" set hidden = 1 var/mob/living/caller = src if(temporary_form) caller = temporary_form - to_chat(caller,"This function isn't coded yet. Soon, my child.") - else - to_chat(src,"This function isn't coded yet. Soon, my child.") - - - - /*if(stat) - to_chat(src,"You must be awake and standing to perform this action!") + var/input = tgui_alert(caller,{"Do you want to rebuild or reassemble yourself? + Rebuilding will cost 10,000 steel and will rebuild all of your limbs as well as repair all damage over a 40s period. + Reassembling costs no steel and will copy the appearance data of your currently loaded save slot."},"Reassembly",list("Rebuild","Reassemble","Cancel")) + if(input == "Cancel" || !input) return - - if(!isturf(loc)) - to_chat(src,"You need more space to perform this action!") - return - - var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory() - //Missing the organ that does this - if(!istype(refactory)) - to_chat(src,"You don't have a working refactory module!") - return - - //Already regenerating - if(active_regen) - to_chat(src, "You are already refactoring!") - return - - var/swap_not_rebuild = tgui_alert(src,"Do you want to rebuild, or reshape?","Rebuild or Reshape",list("Reshape","Cancel","Rebuild")) - if(swap_not_rebuild == "Cancel") - return - if(swap_not_rebuild == "Reshape") - var/list/usable_manufacturers = list() - for(var/company in chargen_robolimbs) - var/datum/robolimb/M = chargen_robolimbs[company] - if(!(BP_TORSO in M.parts)) - continue - if(impersonate_bodytype in M.species_cannot_use) - continue - if(M.whitelisted_to && !(ckey in M.whitelisted_to)) - continue - usable_manufacturers[company] = M - if(!usable_manufacturers.len) - return - var/manu_choice = tgui_input_list(src, "Which manufacturer do you wish to mimic?", "Manufacturer", usable_manufacturers) - - if(!manu_choice) - return //Changed mind - if(!organs_by_name[BP_TORSO]) - return //Ain't got a torso! - - var/obj/item/organ/external/torso = organs_by_name[BP_TORSO] - to_chat(src, "Remain still while the process takes place! It will take 5 seconds.") - visible_message("[src]'s form collapses into an amorphous blob of black ichor...") - - var/mob/living/simple_mob/protean_blob/blob = nano_intoblob() - active_regen = 1 - if(do_after(blob,5 SECONDS)) - synthetic = usable_manufacturers[manu_choice] - torso.robotize(manu_choice) //Will cascade to all other organs. - regenerate_icons() - visible_message("[src]'s form reshapes into a new one...") - active_regen = 0 - nano_outofblob(blob) - return - - //Not enough resources (AND spends the resources, should be the last check) - if(!refactory.use_stored_material(MAT_STEEL,refactory.max_storage)) - to_chat(src, "You need to be maxed out on normal metal to do this!") - return - - var/delay_length = round(active_regen_delay * species.active_regen_mult) - to_chat(src, "Remain still while the process takes place! It will take [delay_length/10] seconds.") - visible_message("[src]'s form begins to shift and ripple as if made of oil...") - active_regen = 1 - - var/mob/living/simple_mob/protean_blob/blob = nano_intoblob() - if(do_after(blob, delay_length, null, 0)) - if(stat != DEAD && refactory) - var/list/holder = refactory.materials - species.create_organs(src) - var/obj/item/organ/external/torso = organs_by_name[BP_TORSO] - torso.robotize() //synthetic wasn't defined here. - LAZYCLEARLIST(blood_DNA) - LAZYCLEARLIST(feet_blood_DNA) - blood_color = null - feet_blood_color = null - regenerate_icons() //Probably worth it, yeah. - var/obj/item/organ/internal/nano/refactory/new_refactory = locate() in internal_organs - if(!new_refactory) - log_debug("[src] protean-regen'd but lacked a refactory when done.") - else - new_refactory.materials = holder - to_chat(src, "Your refactoring is complete.") //Guarantees the message shows no matter how bad the timing. - to_chat(blob, "Your refactoring is complete!") + if(input == "Rebuild") + var/obj/item/organ/internal/nano/refactory/refactory = nano_get_refactory() + if(refactory.get_stored_material(MAT_STEEL) >= 10000) + to_chat(caller, "You begin to rebuild. You will need to remain still.") + if(do_after(caller, 400)) + if(species?:OurRig) //Unsafe, but we should only ever be using this with a Protean + species?:OurRig?:make_alive(src,1) //Re-using this proc + refactory.use_stored_material(MAT_STEEL,refactory.get_stored_material(MAT_STEEL)) //Use all of our steel + else + to_chat(caller, "Somehow, you are missing your protean rig. You are unable to rebuild without one.") else - to_chat(src, "Your refactoring has failed.") - to_chat(blob, "Your refactoring has failed!") + to_chat(caller, "You do not have enough steel stored for this operation.") else - to_chat(src, "Your refactoring is interrupted.") - to_chat(blob, "Your refactoring is interrupted!") - active_regen = 0 - nano_outofblob(blob)*/ + to_chat(caller, "You begin to reassemble. You will need to remain still.") + caller.visible_message("[caller] rapidly contorts and shifts!", "You begin to reassemble.") + if(do_after(caller, 40)) + if(client.prefs) //Make sure we didn't d/c + var/obj/item/weapon/rig/protean/Rig = species?:OurRig + GetAppearanceFromPrefs() + species?:OurRig = Rig //Get a reference to our Rig and put it back after reassembling + caller.visible_message("[caller] adopts a new form!", "You have reassembled.") //// // Storing metal @@ -511,8 +437,8 @@ to_call = /mob/living/carbon/human/proc/nano_partswap /obj/effect/protean_ability/reform_body - ability_name = "Total Reassembly (wip)" - desc = "Completely reassemble yourself from whatever save slot you have loaded in preferences. Assuming you meet the requirements." + ability_name = "Total Reassembly" + desc = "Fully repair yourself or reload your appearance from whatever character slot you have loaded." icon_state = "body" to_call = /mob/living/carbon/human/proc/nano_regenerate diff --git a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_rig.dm b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_rig.dm index df1f663224..8119f08655 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_rig.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/species/station/protean/protean_rig.dm @@ -362,7 +362,7 @@ if(PL.use(5)) to_chat(user, "You feed plasteel to the Protean, they will be able to reconstitute in ten minutes from now.") to_chat(myprotean, "You've been fed the necessary plasteel to reconstitute your form, you will be able to reconstitute in ten minutes.") - addtimer(CALLBACK(src, .proc/make_alive, myprotean), 6000) + addtimer(CALLBACK(src, .proc/make_alive, myprotean?:humanform), 6000) return else to_chat(user, "This Protean is already reconstituting") @@ -375,11 +375,8 @@ AssimilateBag(user,0,W) ..() -/obj/item/weapon/rig/protean/proc/make_alive(var/mob/living/simple_mob/protean_blob/P) - var/mob/living/carbon/human/H - var/datum/species/protean/S - if(P.humanform) - H = P.humanform +/obj/item/weapon/rig/protean/proc/make_alive(var/mob/living/carbon/human/H, var/partial) + if(H) H.setToxLoss(0) H.setOxyLoss(0) H.setCloneLoss(0) @@ -393,17 +390,30 @@ H.ear_deaf = 0 H.ear_damage = 0 H.heal_overall_damage(H.getActualBruteLoss(), H.getActualFireLoss(), 1) - dead_mob_list.Remove(H) - living_mob_list += H - H.tod = null - H.timeofdeath = 0 - H.set_stat(CONSCIOUS) - if(istype(H.species, /datum/species/protean)) - S = H.species - S.pseudodead = 0 - dead = 0 - reviving = 0 - to_chat(P, "You have finished reconstituting.") + for(var/I in H.organs_by_name) + if(!H.organs_by_name[I] || istype(H.organs_by_name[I], /obj/item/organ/external/stump)) + if(H.organs_by_name[I]) + var/obj/item/organ/external/oldlimb = H.organs_by_name[I] + oldlimb.removed() + qdel(oldlimb) + var/list/organ_data = H.species.has_limbs[I] + var/limb_path = organ_data["path"] + var/obj/item/organ/external/new_eo = new limb_path(H) + new_eo.robotize(H.synthetic ? H.synthetic.company : null) + new_eo.sync_colour_to_human(H) + if(!partial) + dead_mob_list.Remove(H) + living_mob_list += H + H.tod = null + H.timeofdeath = 0 + H.set_stat(CONSCIOUS) + if(istype(H.species, /datum/species/protean)) + var/datum/species/protean/S + S = H.species + S.pseudodead = 0 + dead = 0 + reviving = 0 + to_chat(myprotean, "You have finished reconstituting.") /obj/item/weapon/rig/protean/take_hit(damage, source, is_emp=0) return //We don't do that here diff --git a/modular_chomp/code/modules/mob/living/carbon/human/update_icons.dm b/modular_chomp/code/modules/mob/living/carbon/human/update_icons.dm index 7ead82c834..b9a8ef70c6 100644 --- a/modular_chomp/code/modules/mob/living/carbon/human/update_icons.dm +++ b/modular_chomp/code/modules/mob/living/carbon/human/update_icons.dm @@ -103,3 +103,48 @@ spawn(12) struggle_anim_taur = FALSE update_vore_tail_sprite() + +/mob/living/carbon/human/proc/GetAppearanceFromPrefs() + /* Jank code that effectively creates the client's mob from save, then copies its appearance to our current mob. + Intended to be used with shapeshifter species so we don't reset their organs in doing so.*/ + var/mob/living/carbon/human/dummy/mannequin/Dummy = new + if(client.prefs) + client.prefs.copy_to(Dummy) + //Important, since some sprites only work for specific species + if(Dummy.species.base_species == "Promethean") + impersonate_bodytype = "Human" + else + impersonate_bodytype = Dummy.species.base_species + custom_species = Dummy.custom_species + var/list/traits = dna.species_traits.Copy() + dna = Dummy.dna.Clone() + dna.species_traits.Cut() + dna.species_traits = traits.Copy() + UpdateAppearance() + icon = Dummy.icon + qdel(Dummy) + +/* Alternative version of the above proc, incase it turns out cloning our dummy mob's DNA is an awful, terrible bad idea. +Would need to fix this proc up to work as smoothly as the above proc, though. +/mob/living/carbon/human/proc/GetAppearanceFromPrefs() + /* Jank code that effectively creates the client's mob from save, then copies its appearance to our current mob. + Intended to be used with shapeshifter species so we don't reset their organs in doing so.*/ + var/mob/living/carbon/human/dummy/mannequin/Dummy = new + if(client.prefs) + client.prefs.copy_to(Dummy) + //Important, since some sprites only work for specific species + if(Dummy.species.base_species == "Promethean") + impersonate_bodytype = "Human" + else + impersonate_bodytype = Dummy.species.base_species + custom_species = Dummy.custom_species + for(var/tag in Dummy.dna.body_markings) + var/obj/item/organ/external/E = organs_by_name[tag] + if(E) + E.markings.Cut() + var/list/marklist = Dummy.dna.body_markings[tag] + E.markings = marklist.Copy() + UpdateAppearance(Dummy.dna.UI.Copy()) + icon = Dummy.icon + qdel(Dummy) +*/ \ No newline at end of file