diff --git a/code/controllers/subsystems/initialization/robots.dm b/code/controllers/subsystems/initialization/robots.dm index 75c70a7fe4cc..337f8c14e593 100644 --- a/code/controllers/subsystems/initialization/robots.dm +++ b/code/controllers/subsystems/initialization/robots.dm @@ -10,14 +10,11 @@ SUBSYSTEM_DEF(robots) var/list/robot_alt_titles = list() var/list/mob_types_by_title = list( - "cyborg, flying" = /mob/living/silicon/robot/flying, "robot, flying" = /mob/living/silicon/robot/flying ) - var/list/mmi_types_by_title = list( - "cyborg" = /obj/item/organ/internal/brain_interface, + var/list/processor_types_by_title = list( "robot" = /obj/item/organ/internal/brain/robotic, - "cyborg, flying" = /obj/item/organ/internal/brain_interface, "robot, flying" = /obj/item/organ/internal/brain/robotic ) @@ -25,7 +22,7 @@ SUBSYSTEM_DEF(robots) . = ..() // This is done via loop instead of just assignment in order to trim associations. - for(var/title in (mob_types_by_title|mmi_types_by_title)) + for(var/title in (mob_types_by_title|processor_types_by_title)) robot_alt_titles |= capitalize(title) sortTim(robot_alt_titles, /proc/cmp_text_asc) @@ -58,7 +55,7 @@ SUBSYSTEM_DEF(robots) .[include_override] = modules[include_override] /datum/controller/subsystem/robots/proc/get_brain_type_by_title(var/check_title) - . = mmi_types_by_title[lowertext(trim(check_title))] || /obj/item/organ/internal/brain/robotic + . = processor_types_by_title[lowertext(trim(check_title))] || /obj/item/organ/internal/brain/robotic /datum/controller/subsystem/robots/proc/get_mob_type_by_title(var/check_title) . = mob_types_by_title[lowertext(trim(check_title))] || /mob/living/silicon/robot \ No newline at end of file diff --git a/code/datums/trading/traders/goods.dm b/code/datums/trading/traders/goods.dm index 81d294268dcd..c497455ab77f 100644 --- a/code/datums/trading/traders/goods.dm +++ b/code/datums/trading/traders/goods.dm @@ -247,7 +247,6 @@ Sells devices, odds and ends, and medical stuff /obj/item/synthesized_instrument/violin = TRADER_THIS_TYPE, /obj/item/hailer = TRADER_THIS_TYPE, /obj/item/uv_light = TRADER_THIS_TYPE, - /obj/item/organ/internal/brain_interface = TRADER_SUBTYPES_ONLY, /obj/item/robotanalyzer = TRADER_THIS_TYPE, /obj/item/chems/toner_cartridge = TRADER_THIS_TYPE, /obj/item/camera_film = TRADER_THIS_TYPE, diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 79bb78e9540e..b023cc39b312 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -51,7 +51,7 @@ var/global/list/empty_playable_ai_cores = list() if(open_for_latejoin) empty_playable_ai_cores += D else - var/mob/living/silicon/ai/A = new /mob/living/silicon/ai ( loc, laws, brain ) + var/mob/living/silicon/ai/A = new /mob/living/silicon/ai ( loc, laws, brain.get_brainmob() ) if(A) //if there's no brain, the mob is deleted and a structure/AIcore is created A.on_mob_init() A.rename_self("ai", 1) diff --git a/code/game/objects/items/robot/robot_frame.dm b/code/game/objects/items/robot/robot_frame.dm index 2759cbc834e3..b4edb454766e 100644 --- a/code/game/objects/items/robot/robot_frame.dm +++ b/code/game/objects/items/robot/robot_frame.dm @@ -32,6 +32,9 @@ SSstatistics.add_field("cyborg_frames_built",1) return TRUE +/obj/item/robot_parts/robot_suit/proc/is_valid_processor(obj/item/used_item) + return istype(used_item, /obj/item/organ/internal/brain/robotic) + /obj/item/robot_parts/robot_suit/attackby(obj/item/used_item, mob/user) // Uninstall a robotic part. @@ -61,28 +64,28 @@ return TRUE // Install a brain. - else if(istype(used_item, /obj/item/organ/internal/brain_interface)) + else if(istype(used_item, /obj/item/organ/internal) && is_valid_processor(used_item)) + var/obj/item/organ/internal/processor = used_item if(!isturf(loc)) - to_chat(user, SPAN_WARNING("You can't put \the [used_item] in without the frame being on the ground.")) + to_chat(user, SPAN_WARNING("You can't put \the [processor] in without the frame being on the ground.")) return TRUE if(!check_completion()) to_chat(user, SPAN_WARNING("The frame is not ready for the central processor to be installed.")) return TRUE - var/obj/item/organ/internal/brain_interface/M = used_item - var/mob/living/brainmob = M?.get_brainmob() + var/mob/living/brainmob = processor.get_brainmob() if(!brainmob) - to_chat(user, SPAN_WARNING("Sticking an empty [used_item.name] into the frame would sort of defeat the purpose.")) + to_chat(user, SPAN_WARNING("Sticking an empty [processor.name] into the frame would sort of defeat the purpose.")) return TRUE if(jobban_isbanned(brainmob, ASSIGNMENT_ROBOT)) - to_chat(user, SPAN_WARNING("\The [used_item] does not seem to fit.")) + to_chat(user, SPAN_WARNING("\The [processor] does not seem to fit.")) return TRUE if(brainmob.stat == DEAD) - to_chat(user, SPAN_WARNING("Sticking a dead [used_item.name] into the frame would sort of defeat the purpose.")) + to_chat(user, SPAN_WARNING("Sticking a dead [processor.name] into the frame would sort of defeat the purpose.")) return TRUE var/ghost_can_reenter = 0 @@ -95,10 +98,10 @@ else ghost_can_reenter = 1 if(!ghost_can_reenter) - to_chat(user, SPAN_WARNING("\The [used_item] is completely unresponsive; there's no point.")) + to_chat(user, SPAN_WARNING("\The [processor] is completely unresponsive; there's no point.")) return TRUE - if(!user.try_unequip(used_item)) + if(!user.try_unequip(processor)) return TRUE SSstatistics.add_field("cyborg_frames_built",1) @@ -106,7 +109,7 @@ if(!O) return TRUE - O.central_processor = used_item + O.central_processor = processor O.set_invisibility(INVISIBILITY_NONE) O.custom_name = created_name O.updatename("Default") @@ -120,7 +123,7 @@ var/obj/item/robot_parts/chest/chest = parts[BP_CHEST] chest.cell.forceMove(O) - used_item.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. + processor.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. // Since we "magically" installed a cell, we also have to update the correct component. if(O.cell) diff --git a/code/modules/bodytype/bodytype_prosthetic.dm b/code/modules/bodytype/bodytype_prosthetic.dm index 7423faf51b70..9cc143a05500 100644 --- a/code/modules/bodytype/bodytype_prosthetic.dm +++ b/code/modules/bodytype/bodytype_prosthetic.dm @@ -35,7 +35,6 @@ 'sound/foley/metal1.ogg' ) has_organ = list( - BP_BRAIN = /obj/item/organ/internal/brain_interface, BP_EYES = /obj/item/organ/internal/eyes, BP_CELL = /obj/item/organ/internal/cell ) diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm index 68570144c141..c225408cfa0d 100644 --- a/code/modules/clothing/spacesuits/rig/modules/computer.dm +++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm @@ -59,6 +59,7 @@ var/mob/living/integrated_ai // Direct reference to the actual mob held in the suit. var/obj/item/ai_card // Reference to the object previously holding the AI. var/obj/item/ai_verbs/verb_holder + var/list/simple_insert_types = list(/obj/item/paicard) /mob/living var/get_rig_stats = 0 @@ -136,7 +137,7 @@ return 1 // Okay, it wasn't a terminal being touched, check for all the simple insertions. - if(input_device.type in list(/obj/item/paicard, /obj/item/organ/internal/brain_interface)) + if(is_type_in_list(input_device, simple_insert_types)) if(integrated_ai) integrated_ai.attackby(input_device,user) // If the transfer was successful, we can clear out our vars. diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm index b91444de9608..dd9e49236490 100644 --- a/code/modules/emotes/emote_mob.dm +++ b/code/modules/emotes/emote_mob.dm @@ -15,8 +15,8 @@ /mob/living/check_mob_can_emote(var/emote_type) return ..() && !(HAS_STATUS(src, STAT_SILENCE) && emote_type == AUDIBLE_MESSAGE) -/mob/living/brain/check_mob_can_emote(var/emote_type) - return ..() && istype(get_container(), /obj/item/organ/internal/brain_interface) +/mob/living/brain/check_mob_can_emote(var/emote_type, allow_brain_emote = FALSE) + return ..() && allow_brain_emote #define EMOTE_REFRESH_SPAM_COOLDOWN (5 SECONDS) /mob/proc/emote(var/act, var/m_type, var/message) diff --git a/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm b/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm index 3b52762f8f94..2dd5145d0b56 100644 --- a/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm +++ b/code/modules/fabrication/designs/protolathe/designs_machine_intelligence.dm @@ -1,16 +1,10 @@ /datum/fabricator_recipe/protolathe/brains category = "Machine Intelligence" - path = /obj/item/organ/internal/brain_interface/empty + path = /obj/item/organ/internal/brain/robotic /datum/fabricator_recipe/protolathe/brains/get_product_name() . = "intelligence storage ([..()])" -/datum/fabricator_recipe/protolathe/brains/robotic - path = /obj/item/organ/internal/brain/robotic - -/datum/fabricator_recipe/protolathe/brains/mmi_radio - path = /obj/item/organ/internal/brain_interface/radio_enabled/empty - /datum/fabricator_recipe/protolathe/brains/paicard path = /obj/item/paicard diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index a565d1e1aae0..8f2f8a2212f0 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -389,6 +389,11 @@ for(var/thing in get_held_items()) try_unequip(thing, drop_loc) +/mob/proc/drop_equipped_items(drop_loc = loc, include_carried = FALSE) + SHOULD_CALL_PARENT(TRUE) + for(var/thing in get_equipped_items(include_carried)) + try_unequip(thing, drop_loc) + //Returns the item equipped to the specified slot, if any. /mob/proc/get_equipped_item(var/slot) SHOULD_CALL_PARENT(TRUE) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 7fbab9b36654..ea6366c8c7e2 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -41,18 +41,18 @@ /mob/living/brain/proc/get_container() return get_recursive_loc_of_type(/obj/item/organ/internal) +/mob/living/brain/proc/on_container_login(obj/item/organ/internal/container) + container.update_icon() + /mob/living/brain/Login() . = ..() var/obj/item/organ/internal/container = get_container() if(istype(container)) - var/obj/item/organ/internal/brain_interface/interface = container - if(istype(interface)) - interface.locked = TRUE - container.update_icon() + on_container_login(container) /mob/living/brain/proc/is_in_interface() var/container = get_container() - return istype(container, /obj/item/organ/internal/brain_interface) || istype(container, /obj/item/organ/internal/brain/robotic) + return istype(container, /obj/item/organ/internal/brain/robotic) /mob/living/brain/can_emote(emote_type, show_message) return is_in_interface() && ..() diff --git a/code/modules/mob/living/brain/death.dm b/code/modules/mob/living/brain/death.dm index 1c185d241c60..ee2313275490 100644 --- a/code/modules/mob/living/brain/death.dm +++ b/code/modules/mob/living/brain/death.dm @@ -1,25 +1,12 @@ -/mob/living/brain/get_death_message(gibbed) - var/obj/item/organ/internal/brain_interface/container = get_container() - if(!gibbed && istype(container)) - return "beeps shrilly as \the [container] flatlines!" - return ..() - /mob/living/brain/death(gibbed) var/obj/item/organ/holder = loc - var/obj/item/organ/internal/brain_interface/container = get_container() . = ..() if(.) if(stat == DEAD && istype(holder)) holder.die() - if(istype(container) && !QDELETED(container)) - container.update_icon() /mob/living/brain/gib(do_gibs = TRUE) - var/obj/item/organ/internal/brain_interface/container = get_container() var/obj/item/organ/internal/brain/sponge = loc . = ..() - if(.) - if(istype(container) && !QDELETED(container)) - qdel(container) - if(istype(sponge) && !QDELETED(sponge)) - qdel(sponge) + if(. && istype(sponge) && !QDELETED(sponge)) + qdel(sponge) diff --git a/code/modules/mob/living/brain/say.dm b/code/modules/mob/living/brain/say.dm index c2542360968b..98946a423659 100644 --- a/code/modules/mob/living/brain/say.dm +++ b/code/modules/mob/living/brain/say.dm @@ -10,7 +10,3 @@ if(radio) radio.hear_talk(src, sanitize(message), verb, speaking) -/mob/living/brain/get_radio() - var/obj/item/organ/internal/brain_interface/container = get_container() - if(istype(container)) - return container.get_radio() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index e72e3798f8cc..28beeb784990 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -103,7 +103,7 @@ var/global/list/ai_verbs_default = list( src.verbs -= ai_verbs_default src.verbs += /mob/living/verb/ghost -/mob/living/silicon/ai/Initialize(mapload, var/datum/ai_laws/L, var/obj/item/organ/internal/brain_interface/B, var/safety = 0) +/mob/living/silicon/ai/Initialize(mapload, var/datum/ai_laws/L, var/mob/living/brain/brainmob, var/safety = 0) announcement = new() announcement.title = "A.I. Announcement" announcement.announcement_type = "A.I. Announcement" @@ -143,7 +143,6 @@ var/global/list/ai_verbs_default = list( add_language(/decl/language/sign, 0) if(!safety)//Only used by AIize() to successfully spawn an AI. - var/mob/living/brainmob = B?.get_brainmob() if(!brainmob) // If there is no player/brain inside. empty_playable_ai_cores += new/obj/structure/aicore/deactivated(loc)//New empty terminal. . = INITIALIZE_HINT_QDEL diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 969dd3dac640..fa013a27914f 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -76,7 +76,6 @@ can_hold = list( /obj/item/cell, /obj/item/stock_parts, - /obj/item/organ/internal/brain_interface, /obj/item/robot_parts, /obj/item/borg/upgrade, /obj/item/flash, diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index bebc25e3b4b5..d358e28ba7d4 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -51,8 +51,8 @@ /mob/living/AIize(move = TRUE) if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return - for(var/t in get_external_organs()) - qdel(t) + delete_organs() + drop_equipped_items() for(var/obj/item/thing in src) drop_from_inventory(thing) ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) @@ -65,7 +65,7 @@ sound_to(src, sound(null, repeat = 0, wait = 0, volume = 85, channel = sound_channels.lobby_channel))// stop the jams for AIs - var/mob/living/silicon/ai/O = new (loc, global.using_map.default_law_type,,1)//No brain but safety is in effect. + var/mob/living/silicon/ai/O = new (loc, global.using_map.default_law_type,null,1)//No brain but safety is in effect. O.set_invisibility(INVISIBILITY_NONE) O.aiRestorePowerRoutine = 0 if(mind) @@ -101,28 +101,23 @@ qdel(src) return O -//human -> robot -/mob/living/human/proc/Robotize(var/supplied_robot_type = /mob/living/silicon/robot) +//living mob -> robot +/mob/living/proc/Robotize(var/supplied_robot_type = ASSIGNMENT_ROBOT, skip_qdel = FALSE) if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return - QDEL_NULL_LIST(worn_underwear) - for(var/obj/item/thing in src) - drop_from_inventory(thing) - try_refresh_visible_overlays() ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) - icon = null - set_invisibility(INVISIBILITY_ABSTRACT) - for(var/t in get_external_organs()) - qdel(t) - - var/mob/living/silicon/robot/O = new supplied_robot_type( loc ) + drop_equipped_items() + var/robot_type_path = SSrobots.get_mob_type_by_title(supplied_robot_type) + var/mob/living/silicon/robot/O = new robot_type_path(loc) - O.set_gender(gender) + O.set_gender(get_gender()) O.set_invisibility(INVISIBILITY_NONE) if(!mind) mind_initialize() mind.assigned_role = ASSIGNMENT_ROBOT + if(supplied_robot_type != ASSIGNMENT_ROBOT) + mind.role_alt_title = supplied_robot_type mind.active = TRUE mind.transfer_to(O) if(O.mind && O.mind.assigned_role == ASSIGNMENT_ROBOT) @@ -135,7 +130,8 @@ RAISE_EVENT(/decl/observ/cyborg_created, O) O.Namepick() - qdel(src) + if(!skip_qdel) + qdel(src) return O /mob/living/human/proc/corgize() diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 7e498de80efc..7628644b405a 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -9,59 +9,57 @@ /obj/item/projectile/change/on_hit(var/atom/change) wabbajack(change) -/obj/item/projectile/change/proc/get_random_transformation_options(var/mob/M) +/obj/item/projectile/change/proc/get_random_transformation_options(var/mob/living/victim) . = list() - if(!isrobot(M)) + if(!isrobot(victim)) . += "robot" for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) . += species.uid - if(ishuman(M)) - var/mob/living/human/H = M - . -= H.species.uid + if(ishuman(victim)) + var/mob/living/human/human_victim = victim + . -= human_victim.species.uid -/obj/item/projectile/change/proc/apply_transformation(var/mob/M, var/choice) +/obj/item/projectile/change/proc/make_robot(var/mob/living/victim, robot_title = ASSIGNMENT_ROBOT) + return victim.Robotize(robot_title, skip_qdel = TRUE) + +/obj/item/projectile/change/proc/apply_transformation(var/mob/living/victim, var/choice) if(choice == "robot") - var/mob/living/silicon/robot/robot = new(get_turf(M)) - robot.set_gender(M.get_gender()) - robot.job = ASSIGNMENT_ROBOT - robot.central_processor = new /obj/item/organ/internal/brain_interface(robot) - transfer_key_from_mob_to_mob(M, robot) - return robot + return make_robot() if(decls_repository.get_decl_by_id(choice)) - var/mob/living/human/H = M - if(!istype(H)) - H = new(get_turf(M)) - H.set_gender(M.get_gender()) - H.name = "unknown" // This will cause set_species() to randomize the mob name. - H.real_name = H.name - H.change_species(choice) - H.universal_speak = TRUE + var/mob/living/human/human_victim = victim + if(!istype(human_victim)) + human_victim = new(get_turf(victim)) + human_victim.set_gender(victim.get_gender()) + human_victim.name = "unknown" // This will cause set_species() to randomize the mob name. + human_victim.real_name = human_victim.name + human_victim.change_species(choice) + human_victim.universal_speak = TRUE var/datum/preferences/A = new() - A.randomize_appearance_and_body_for(H) - return H + A.randomize_appearance_and_body_for(human_victim) + return human_victim -/obj/item/projectile/change/proc/wabbajack(var/mob/M) +/obj/item/projectile/change/proc/wabbajack(var/mob/living/victim) - if(!isliving(M) || M.stat == DEAD) + if(!isliving(victim) || victim.stat == DEAD) return - if(HAS_TRANSFORMATION_MOVEMENT_HANDLER(M)) + if(HAS_TRANSFORMATION_MOVEMENT_HANDLER(victim)) return - M.handle_pre_transformation() - var/choice = pick(get_random_transformation_options(M)) - var/mob/living/new_mob = apply_transformation(M, choice) + victim.handle_pre_transformation() + var/choice = pick(get_random_transformation_options(victim)) + var/mob/living/new_mob = apply_transformation(victim, choice) if(new_mob) new_mob.set_intent(I_FLAG_HARM) - new_mob.copy_abilities_from(M) - transfer_key_from_mob_to_mob(M, new_mob) + new_mob.copy_abilities_from(victim) + transfer_key_from_mob_to_mob(victim, new_mob) to_chat(new_mob, "Your form morphs into that of \a [choice].") else - new_mob = M + new_mob = victim if(new_mob) to_chat(new_mob, SPAN_WARNING("Your form morphs into that of \a [choice].")) - if(new_mob != M && !QDELETED(M)) - qdel(M) + if(new_mob != victim && !QDELETED(victim)) + qdel(victim) diff --git a/maps/exodus/exodus.dm b/maps/exodus/exodus.dm index a5bb07e061cf..3553f269e878 100644 --- a/maps/exodus/exodus.dm +++ b/maps/exodus/exodus.dm @@ -7,6 +7,7 @@ #include "../../mods/content/beekeeping/_beekeeping.dme" #include "../../mods/content/bigpharma/_bigpharma.dme" #include "../../mods/content/blob/_blob.dme" + #include "../../mods/content/brain_interface/_brain_interface.dme" #include "../../mods/content/corporate/_corporate.dme" #include "../../mods/content/government/_government.dme" #include "../../mods/content/integrated_electronics/_integrated_electronics.dme" diff --git a/maps/ministation/ministation.dm b/maps/ministation/ministation.dm index a44a244232b9..cf34155e64f2 100644 --- a/maps/ministation/ministation.dm +++ b/maps/ministation/ministation.dm @@ -23,6 +23,7 @@ Twice... #include "../../mods/content/augments/_augments.dme" #include "../../mods/content/bigpharma/_bigpharma.dme" #include "../../mods/content/blob/_blob.dme" + #include "../../mods/content/brain_interface/_brain_interface.dme" #include "../../mods/content/corporate/_corporate.dme" #include "../../mods/content/government/_government.dme" #include "../../mods/content/integrated_electronics/_integrated_electronics.dme" diff --git a/maps/modpack_testing/modpack_testing.dm b/maps/modpack_testing/modpack_testing.dm index 47b6b1468144..47e16e7a41be 100644 --- a/maps/modpack_testing/modpack_testing.dm +++ b/maps/modpack_testing/modpack_testing.dm @@ -13,6 +13,7 @@ #include "../../mods/content/biomods/_biomods.dme" #include "../../mods/content/blacksmithy/_blacksmithy.dme" #include "../../mods/content/blob/_blob.dme" + #include "../../mods/content/brain_interface/_brain_interface.dme" #include "../../mods/content/breath_holding/_breath_holding.dme" #include "../../mods/content/byond_membership/_byond_membership.dm" #include "../../mods/content/corporate/_corporate.dme" diff --git a/maps/tradeship/tradeship.dm b/maps/tradeship/tradeship.dm index 28f3b208c5a1..2101d73bb84f 100644 --- a/maps/tradeship/tradeship.dm +++ b/maps/tradeship/tradeship.dm @@ -20,6 +20,7 @@ #include "../../mods/content/beekeeping/_beekeeping.dme" #include "../../mods/content/bigpharma/_bigpharma.dme" #include "../../mods/content/blob/_blob.dme" + #include "../../mods/content/brain_interface/_brain_interface.dme" #include "../../mods/content/breath_holding/_breath_holding.dme" #include "../../mods/content/corporate/_corporate.dme" #include "../../mods/content/dungeon_loot/_dungeon_loot.dme" diff --git a/mods/content/brain_interface/_brain_interface.dme b/mods/content/brain_interface/_brain_interface.dme new file mode 100644 index 000000000000..41d2d720d0d7 --- /dev/null +++ b/mods/content/brain_interface/_brain_interface.dme @@ -0,0 +1,11 @@ +#ifndef CONTENT_PACK_BRAIN_INTERFACE +#define CONTENT_PACK_BRAIN_INTERFACE +// BEGIN_INCLUDE +#include "brain_interface.dm" +#include "brain_interface_organ.dm" +#include "brainmob_overrides.dm" +#include "fabricator_recipes.dm" +#include "interface_radio.dm" +#include "misc_overrides.dm" +// END_INCLUDE +#endif \ No newline at end of file diff --git a/mods/content/brain_interface/brain_interface.dm b/mods/content/brain_interface/brain_interface.dm new file mode 100644 index 000000000000..e861d74778a9 --- /dev/null +++ b/mods/content/brain_interface/brain_interface.dm @@ -0,0 +1,3 @@ +/decl/modpack/brain_interface + name = "Brain Interface" + desc = "Adds brain-computer interfaces, used as organs in full-body prostheses and in cyborgs." diff --git a/code/modules/brain_interface/_brain_interface.dm b/mods/content/brain_interface/brain_interface_organ.dm similarity index 98% rename from code/modules/brain_interface/_brain_interface.dm rename to mods/content/brain_interface/brain_interface_organ.dm index abd19c34b0f9..6696cc39b37f 100644 --- a/code/modules/brain_interface/_brain_interface.dm +++ b/mods/content/brain_interface/brain_interface_organ.dm @@ -5,7 +5,7 @@ organ_tag = BP_BRAIN parent_organ = BP_HEAD origin_tech = @'{"biotech":3}' - icon = 'icons/obj/items/brain_interface_organic.dmi' + icon = 'mods/content/brain_interface/icons/brain_interface_organic.dmi' icon_state = ICON_STATE_WORLD req_access = list(access_robotics) material = /decl/material/solid/metal/steel diff --git a/mods/content/brain_interface/brainmob_overrides.dm b/mods/content/brain_interface/brainmob_overrides.dm new file mode 100644 index 000000000000..d01d72a31d91 --- /dev/null +++ b/mods/content/brain_interface/brainmob_overrides.dm @@ -0,0 +1,35 @@ +/mob/living/brain/get_radio() + var/obj/item/organ/internal/brain_interface/container = get_container() + if(istype(container)) + return container.get_radio() + +/mob/living/brain/get_death_message(gibbed) + var/obj/item/organ/internal/brain_interface/container = get_container() + if(!gibbed && istype(container)) + return "beeps shrilly as \the [container] flatlines!" + return ..() + +/mob/living/brain/death(gibbed) + var/obj/item/organ/internal/brain_interface/container = get_container() + . = ..() + if(. && istype(container) && !QDELETED(container)) + container.update_icon() + +/mob/living/brain/gib(do_gibs = TRUE) + var/obj/item/organ/internal/brain_interface/container = get_container() + . = ..() + if(. && istype(container) && !QDELETED(container)) + qdel(container) + +/mob/living/brain/on_container_login(obj/item/organ/internal/container) + var/obj/item/organ/internal/brain_interface/interface = container + if(istype(interface)) + interface.locked = TRUE + . = ..() + +/mob/living/brain/is_in_interface() + var/container = get_container() + return ..() || istype(container, /obj/item/organ/internal/brain_interface) + +/mob/living/brain/check_mob_can_emote(var/emote_type, allow_brain_emote = FALSE) + return ..(emote_type, istype(get_container(), /obj/item/organ/internal/brain_interface)) diff --git a/mods/content/brain_interface/fabricator_recipes.dm b/mods/content/brain_interface/fabricator_recipes.dm new file mode 100644 index 000000000000..9ccce7c6fddc --- /dev/null +++ b/mods/content/brain_interface/fabricator_recipes.dm @@ -0,0 +1,5 @@ +/datum/fabricator_recipe/protolathe/brains/mmi + path = /obj/item/organ/internal/brain_interface/empty + +/datum/fabricator_recipe/protolathe/brains/mmi_radio + path = /obj/item/organ/internal/brain_interface/radio_enabled/empty \ No newline at end of file diff --git a/icons/obj/items/brain_interface_organic.dmi b/mods/content/brain_interface/icons/brain_interface_organic.dmi similarity index 100% rename from icons/obj/items/brain_interface_organic.dmi rename to mods/content/brain_interface/icons/brain_interface_organic.dmi diff --git a/code/modules/brain_interface/interface_radio.dm b/mods/content/brain_interface/interface_radio.dm similarity index 100% rename from code/modules/brain_interface/interface_radio.dm rename to mods/content/brain_interface/interface_radio.dm diff --git a/mods/content/brain_interface/misc_overrides.dm b/mods/content/brain_interface/misc_overrides.dm new file mode 100644 index 000000000000..9c11536d62cd --- /dev/null +++ b/mods/content/brain_interface/misc_overrides.dm @@ -0,0 +1,31 @@ +/datum/trader/devices/New() + LAZYSET(possible_trading_items, /obj/item/organ/internal/brain_interface, TRADER_SUBTYPES_ONLY) + . = ..() + +/datum/controller/subsystem/robots/PreInit() + . = ..() + LAZYSET(mob_types_by_title, "cyborg, flying", /mob/living/silicon/robot/flying) + LAZYSET(processor_types_by_title, "cyborg", /obj/item/organ/internal/brain_interface) + LAZYSET(processor_types_by_title, "cyborg, flying", /obj/item/organ/internal/brain_interface) + +// Override to use MMIs for mobs with brains +/obj/item/projectile/change/make_robot(var/mob/living/victim, robot_title = ASSIGNMENT_ROBOT) + var/obj/item/organ/internal/brain/victim_brain = victim.get_organ(BP_BRAIN, /obj/item/organ/internal/brain) + if(istype(victim_brain) && victim_brain.can_use_brain_interface) + robot_title = "Cyborg" + return ..(victim, robot_title) + +/obj/item/robot_parts/robot_suit/is_valid_processor(obj/item/used_item) + return ..() || istype(used_item, /obj/item/organ/internal/brain_interface) + +/decl/bodytype/prosthetic/Initialize() + LAZYSET(has_organ, BP_BRAIN, /obj/item/organ/internal/brain_interface) + . = ..() + +/obj/item/rig_module/ai_container/Initialize(mapload) + simple_insert_types |= /obj/item/organ/internal/brain_interface + . = ..() + +/obj/item/gripper/research/Initialize(ml, material_key) + can_hold += /obj/item/organ/internal/brain_interface + . = ..() diff --git a/mods/content/integrated_electronics/components/manipulation.dm b/mods/content/integrated_electronics/components/manipulation.dm index 4148ac842ee5..0a231032e345 100644 --- a/mods/content/integrated_electronics/components/manipulation.dm +++ b/mods/content/integrated_electronics/components/manipulation.dm @@ -652,9 +652,11 @@ aicard = null controlling = null +/obj/item/integrated_circuit/manipulation/ai/proc/can_load_ai(obj/item/used_item, mob/user) + return istype(used_item, /obj/item/aicard) || istype(used_item, /obj/item/paicard) || istype(used_item, /obj/item/organ/internal/brain/robotic) /obj/item/integrated_circuit/manipulation/ai/attackby(var/obj/item/used_item, var/mob/user) - if(is_type_in_list(used_item, list(/obj/item/aicard, /obj/item/paicard, /obj/item/organ/internal/brain_interface))) + if(can_load_ai(used_item, user)) load_ai(user, used_item) return TRUE else return ..() diff --git a/mods/content/standard_jobs/jobs/synthetics.dm b/mods/content/standard_jobs/jobs/synthetics.dm index 23f768d4ac62..cbea8c6bf826 100644 --- a/mods/content/standard_jobs/jobs/synthetics.dm +++ b/mods/content/standard_jobs/jobs/synthetics.dm @@ -70,7 +70,7 @@ /datum/job/standard/robot/handle_variant_join(var/mob/living/human/H, var/alt_title) if(H) - return H.Robotize(SSrobots.get_mob_type_by_title(alt_title || title)) + return H.Robotize(alt_title || title) /datum/job/standard/robot/equip_job(var/mob/living/human/H) return !!H diff --git a/mods/~compatibility/patches/circuits.dm b/mods/~compatibility/patches/circuits.dm index afa15ae3f36c..ed8e9ad9b1ef 100644 --- a/mods/~compatibility/patches/circuits.dm +++ b/mods/~compatibility/patches/circuits.dm @@ -9,4 +9,8 @@ // Add augment assembly for circuits. #ifdef CONTENT_PACK_AUGMENTS #include "circuits/augment_circuits.dm" +#endif +// Add support for MMIs to the AI manipulator circuit. +#ifdef CONTENT_PACK_BRAIN_INTERFACE +#include "circuits/brain_interface_circuits.dm" #endif \ No newline at end of file diff --git a/mods/~compatibility/patches/circuits/brain_interface_circuits.dm b/mods/~compatibility/patches/circuits/brain_interface_circuits.dm new file mode 100644 index 000000000000..83d0b5c9c6c9 --- /dev/null +++ b/mods/~compatibility/patches/circuits/brain_interface_circuits.dm @@ -0,0 +1,2 @@ +/obj/item/integrated_circuit/manipulation/ai/can_load_ai(obj/item/used_item, mob/user) + return ..() || istype(used_item, /obj/item/organ/internal/brain_interface) \ No newline at end of file diff --git a/nebula.dme b/nebula.dme index 857fed1654f1..5d078bfb281e 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1854,8 +1854,6 @@ #include "code\modules\bodytype\bodytype_prosthetic_models.dm" #include "code\modules\bodytype\bodytype_quadruped.dm" #include "code\modules\bodytype\bodytype_random.dm" -#include "code\modules\brain_interface\_brain_interface.dm" -#include "code\modules\brain_interface\interface_radio.dm" #include "code\modules\butchery\_butchery.dm" #include "code\modules\butchery\butchery_data.dm" #include "code\modules\butchery\butchery_data_animal.dm"