diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 2ff4f478e2d..88c15e687ac 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -166,7 +166,8 @@ L.origin_tech = I.origin_tech else I.loc = get_step(src,SOUTH) - I.materials = res_coef + if(istype(I)) + I.materials = res_coef atom_say("[I] is complete.") being_built = null diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index ab9c72373a1..a40dc81991e 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -14,8 +14,18 @@ mecha = null//This does not appear to be used outside of reference in mecha.dm. var/silenced = 0 //if set to 1, they can't talk. var/next_ping_at = 0 + var/requires_master = TRUE + var/mob/living/carbon/human/imprinted_master = null + +/obj/item/mmi/posibrain/Destroy() + imprinted_master = null + return ..() /obj/item/mmi/posibrain/attack_self(mob/user) + if(requires_master && !imprinted_master) + to_chat(user, "You press your thumb on [src] and imprint your user information.") + imprinted_master = user + return if(brainmob && !brainmob.key && searching == 0) //Start the process of searching for a new user. to_chat(user, "You carefully locate the manual activation switch and start the positronic brain's boot process.") @@ -86,17 +96,23 @@ radio_action.ApplyIcon() return -/obj/item/mmi/posibrain/proc/transfer_personality(var/mob/candidate) - src.searching = 0 - src.brainmob.key = candidate.key - src.name = "positronic brain ([src.brainmob.name])" +/obj/item/mmi/posibrain/attempt_become_organ(obj/item/organ/external/parent, mob/living/carbon/human/H) + if(..()) + if(imprinted_master) + to_chat(H, "You are permanently imprinted to [imprinted_master], obey [imprinted_master]'s every order and assist [imprinted_master.p_them()] in completing [imprinted_master.p_their()] goals at any cost.") - to_chat(src.brainmob, "You are a positronic brain, brought into existence on [station_name()].") - to_chat(src.brainmob, "As a synthetic intelligence, you answer to all crewmembers, as well as the AI.") - to_chat(src.brainmob, "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.") - src.brainmob.mind.assigned_role = "Positronic Brain" - var/turf/T = get_turf_or_move(src.loc) +/obj/item/mmi/posibrain/proc/transfer_personality(mob/candidate) + searching = 0 + brainmob.key = candidate.key + name = "positronic brain ([brainmob.name])" + + to_chat(brainmob, "You are a positronic brain, brought into existence on [station_name()].") + to_chat(brainmob, "As a synthetic intelligence, you answer to [imprinted_master], unless otherwise placed inside of a lawed synthetic structure.") + to_chat(brainmob, "Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed in the future.") + brainmob.mind.assigned_role = "Positronic Brain" + + var/turf/T = get_turf_or_move(loc) for(var/mob/M in viewers(T)) M.show_message("The positronic brain chimes quietly.") become_occupied("posibrain-occupied") @@ -204,3 +220,4 @@ /obj/item/mmi/posibrain/ipc desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." silenced = 1 + requires_master = FALSE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index cca71c1e8d6..b61012f0719 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -118,6 +118,19 @@ /mob/living/carbon/human/machine/Initialize(mapload) ..(mapload, "Machine") +/mob/living/carbon/human/machine/created + name = "automated machine-frame" + +/mob/living/carbon/human/machine/created/Initialize(mapload) + ..() + real_name = "automated machine-frame ([rand(1, 1000)])" + for(var/obj/item/organ/external/E in bodyparts) + if(istype(E, /obj/item/organ/external/chest) || istype(E, /obj/item/organ/external/groin)) + continue + qdel(E) + for(var/obj/item/organ/O in internal_organs) + qdel(O) + /mob/living/carbon/human/shadow/Initialize(mapload) ..(mapload, "Shadow") diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 7fde20333c7..026fcec4afb 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1120,6 +1120,15 @@ construction_time = 350 category = list("Misc") +/datum/design/automated_machine_frame + name = "Automated Machine Frame" + id = "automated_machine_frame" + build_type = MECHFAB + build_path = /mob/living/carbon/human/machine/created + materials = list(MAT_METAL = 40000) + construction_time = 400 + category = list("Misc") + /datum/design/ipc_cell name = "IPC Microbattery" id = "ipc_cell" diff --git a/code/modules/surgery/organs/subtypes/machine.dm b/code/modules/surgery/organs/subtypes/machine.dm index 2be14a91f14..e85d4fe010b 100644 --- a/code/modules/surgery/organs/subtypes/machine.dm +++ b/code/modules/surgery/organs/subtypes/machine.dm @@ -167,7 +167,8 @@ stored_mmi.forceMove(get_turf(owner)) stored_mmi = null ..() - qdel(src) + if(!QDELETED(src)) + qdel(src) /obj/item/organ/internal/brain/mmi_holder/proc/update_from_mmi() if(!stored_mmi) @@ -183,12 +184,13 @@ stored_mmi = new /obj/item/mmi/posibrain/ipc(src) ..() spawn(1) - if(owner) - stored_mmi.name = "positronic brain ([owner.real_name])" - stored_mmi.brainmob.real_name = owner.real_name - stored_mmi.brainmob.name = stored_mmi.brainmob.real_name - stored_mmi.icon_state = "posibrain-occupied" - update_from_mmi() - else - stored_mmi.loc = get_turf(src) - qdel(src) + if(!QDELETED(src)) + if(owner) + stored_mmi.name = "positronic brain ([owner.real_name])" + stored_mmi.brainmob.real_name = owner.real_name + stored_mmi.brainmob.name = stored_mmi.brainmob.real_name + stored_mmi.icon_state = "posibrain-occupied" + update_from_mmi() + else + stored_mmi.loc = get_turf(src) + qdel(src) diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index ed82328c47d..9ea245344d5 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -541,3 +541,59 @@ user.visible_message(" [user]'s hand slips!", \ " Your hand slips!") return 0 + +/datum/surgery/cybernetic_customization + name = "Cybernetic Appearance Customization" + steps = list(/datum/surgery_step/robotics/external/unscrew_hatch, /datum/surgery_step/robotics/external/customize_appearance) + possible_locs = list("head", "chest", "l_arm", "r_arm", "r_leg", "l_leg") + requires_organic_bodypart = FALSE + +/datum/surgery/cybernetic_customization/can_start(mob/user, mob/living/carbon/human/target) + if(ishuman(target)) + var/obj/item/organ/external/affected = target.get_organ(user.zone_sel.selecting) + if(!affected) + return FALSE + if(!(affected.status & ORGAN_ROBOT)) + return FALSE + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance + name = "reprogram limb" + allowed_tools = list(/obj/item/multitool = 100) + time = 48 + +/datum/surgery_step/robotics/external/customize_appearance/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + if(..()) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + if(!affected) + return FALSE + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] begins to reprogram the appearance of [target]'s [affected.name] with [tool]." , \ + "You begin to reprogram the appearance of [target]'s [affected.name] with [tool].") + ..() + +/datum/surgery_step/robotics/external/customize_appearance/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/chosen_appearance = input(user, "Select the company appearance for this limb.", "Limb Company Selection") as null|anything in selectable_robolimbs + if(!chosen_appearance) + return FALSE + var/obj/item/organ/external/affected = target.get_organ(target_zone) + affected.robotize(chosen_appearance, convert_all = FALSE) + if(istype(affected, /obj/item/organ/external/head)) + var/obj/item/organ/external/head/head = affected + head.h_style = "Bald" // nearly all the appearance changes for heads are non-monitors; we want to get rid of a floating screen + target.update_hair() + target.update_body() + target.updatehealth() + target.UpdateDamageIcon() + user.visible_message(" [user] reprograms the appearance of [target]'s [affected.name] with [tool].", \ + " You reprogram the appearance of [target]'s [affected.name] with [tool].") + return TRUE + +/datum/surgery_step/robotics/external/customize_appearance/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) + var/obj/item/organ/external/affected = target.get_organ(target_zone) + user.visible_message(" [user]'s [tool.name] slips, failing to reprogram [target]'s [affected.name].", + " Your [tool.name] slips, failing to reprogram [target]'s [affected.name].") + return FALSE \ No newline at end of file