diff --git a/NTstation13.dme b/NTstation13.dme index 1065bbb49b..9e9cbed7e6 100644 --- a/NTstation13.dme +++ b/NTstation13.dme @@ -960,6 +960,7 @@ #include "code\modules\mob\living\carbon\brain\emote.dm" #include "code\modules\mob\living\carbon\brain\life.dm" #include "code\modules\mob\living\carbon\brain\MMI.dm" +#include "code\modules\mob\living\carbon\brain\posibrain.dm" #include "code\modules\mob\living\carbon\brain\say.dm" #include "code\modules\mob\living\carbon\human\death.dm" #include "code\modules\mob\living\carbon\human\emote.dm" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index ba74450b50..728e11836f 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -169,9 +169,7 @@ datum/hud/New(mob/owner) /datum/hud/proc/instantiate() - if(!ismob(mymob)) - return 0 - if(!mymob.client) + if(!ismob(mymob) || !mymob.client || !mymob.client.screen) return 0 var/ui_style = ui_style2icon(mymob.client.prefs.UI_style) @@ -200,10 +198,9 @@ datum/hud/New(mob/owner) //Version denotes which style should be displayed. blank or 0 means "next version" /datum/hud/proc/show_hud(var/version = 0) - if(!ismob(mymob)) - return 0 - if(!mymob.client) + if(!ismob(mymob) || !mymob.client || !mymob.client.screen) return 0 + var/display_hud_version = version if(!display_hud_version) //If 0 or blank, display the next hud version display_hud_version = hud_version + 1 @@ -220,18 +217,30 @@ datum/hud/New(mob/owner) if(hotkeybuttons && !hotkey_ui_hidden) mymob.client.screen += hotkeybuttons - action_intent.screen_loc = ui_acti //Restore intent selection to the original position - mymob.client.screen += mymob.zone_sel //This one is a special snowflake - mymob.client.screen += mymob.bodytemp //As are the rest of these... - mymob.client.screen += mymob.fire - mymob.client.screen += mymob.healths - mymob.client.screen += mymob.internals - mymob.client.screen += mymob.nutrition_icon - mymob.client.screen += mymob.oxygen - mymob.client.screen += mymob.pressure - mymob.client.screen += mymob.toxin - mymob.client.screen += lingstingdisplay - mymob.client.screen += lingchemdisplay + if(action_intent) + action_intent.screen_loc = ui_acti //Restore intent selection to the original position + if(mymob.zone_sel) + mymob.client.screen += mymob.zone_sel //This one is a special snowflake + if(mymob.bodytemp) + mymob.client.screen += mymob.bodytemp //As are the rest of these... + if(mymob.fire) + mymob.client.screen += mymob.fire + if(mymob.healths) + mymob.client.screen += mymob.healths + if(mymob.internals) + mymob.client.screen += mymob.internals + if(mymob.nutrition_icon) + mymob.client.screen += mymob.nutrition_icon + if(mymob.oxygen) + mymob.client.screen += mymob.oxygen + if(mymob.pressure) + mymob.client.screen += mymob.pressure + if(mymob.toxin) + mymob.client.screen += mymob.toxin + if(lingstingdisplay) + mymob.client.screen += lingstingdisplay + if(lingchemdisplay) + mymob.client.screen += lingchemdisplay hidden_inventory_update() persistant_inventory_update() @@ -248,15 +257,22 @@ datum/hud/New(mob/owner) mymob.client.screen -= item_action_list //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone. - mymob.client.screen -= mymob.zone_sel //zone_sel is a mob variable for some reason. - mymob.client.screen -= lingstingdisplay - mymob.client.screen -= lingchemdisplay + if(mymob.zone_sel) + mymob.client.screen -= mymob.zone_sel //zone_sel is a mob variable for some reason. + if(lingstingdisplay) + mymob.client.screen -= lingstingdisplay + if(lingchemdisplay) + mymob.client.screen -= lingchemdisplay //These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay - mymob.client.screen += l_hand_hud_object //we want the hands to be visible - mymob.client.screen += r_hand_hud_object //we want the hands to be visible - mymob.client.screen += action_intent //we want the intent swticher visible - action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. + if(l_hand_hud_object) + mymob.client.screen += l_hand_hud_object //we want the hands to be visible + if(r_hand_hud_object) + mymob.client.screen += r_hand_hud_object //we want the hands to be visible + if(action_intent) + mymob.client.screen += action_intent //we want the intent swticher visible + if(ui_acti_alt) + action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. hidden_inventory_update() persistant_inventory_update() @@ -273,17 +289,28 @@ datum/hud/New(mob/owner) mymob.client.screen -= item_action_list //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone. - mymob.client.screen -= mymob.zone_sel //zone_sel is a mob variable for some reason. - mymob.client.screen -= mymob.bodytemp - mymob.client.screen -= mymob.fire - mymob.client.screen -= mymob.healths - mymob.client.screen -= mymob.internals - mymob.client.screen -= mymob.nutrition_icon - mymob.client.screen -= mymob.oxygen - mymob.client.screen -= mymob.pressure - mymob.client.screen -= mymob.toxin - mymob.client.screen -= lingstingdisplay - mymob.client.screen -= lingchemdisplay + if(mymob.zone_sel) + mymob.client.screen -= mymob.zone_sel //zone_sel is a mob variable for some reason. + if(mymob.bodytemp) + mymob.client.screen -= mymob.bodytemp + if(mymob.fire) + mymob.client.screen -= mymob.fire + if(mymob.healths) + mymob.client.screen -= mymob.healths + if(mymob.internals) + mymob.client.screen -= mymob.internals + if(mymob.nutrition_icon) + mymob.client.screen -= mymob.nutrition_icon + if(mymob.oxygen) + mymob.client.screen -= mymob.oxygen + if(mymob.pressure) + mymob.client.screen -= mymob.pressure + if(mymob.toxin) + mymob.client.screen -= mymob.toxin + if(lingstingdisplay) + mymob.client.screen -= lingstingdisplay + if(lingchemdisplay) + mymob.client.screen -= lingchemdisplay hidden_inventory_update() persistant_inventory_update() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index cd5d0c45fc..83cd5a8cef 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -652,10 +652,13 @@ /obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/device/mmi)) + if(istype(src, /obj/mecha/combat)) //Temp fix, Combat mechs cause LOTS of visual errors on MMI/Posibrains - Remie + user << "Does that sound like a smart idea to you?" + return if(mmi_move_inside(W,user)) - user << "[src]-MMI interface initialized successfuly" + user << "[src]-[W] interface initialized successfuly" else - user << "[src]-MMI interface initialization failed." + user << "[src]-[W] interface initialization failed." return if(istype(W, /obj/item/mecha_parts/mecha_equipment)) @@ -1154,6 +1157,9 @@ if(mmi.brainmob) occupant.loc = mmi mmi.mecha = null + if(istype(mmi,/obj/item/device/mmi/posibrain)) + var/obj/item/device/mmi/posibrain/P = mmi + P.handle_posibrain_icon() src.occupant.canmove = 0 src.verbs += /obj/mecha/verb/eject src.occupant = null diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 159921e193..e57fe4c8c3 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -225,8 +225,9 @@ M.brainmob.mind.transfer_to(O) - if(O.mind && O.mind.special_role) - O.mind.remove_all_antag() + if(O.mind) + if(O.mind.special_role) + O.mind.remove_all_antag() if(!config.borg_remembers) O.mind.store_memory("All Objectives listed here are considered Failed.") else @@ -238,8 +239,9 @@ O.cell = chest.cell chest.cell.loc = O chest.cell = null - W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. - O.mmi = W + M.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. + O.mmi = M + O.updatename() feedback_inc("cyborg_birth",1) diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 442698859b..7f47e73497 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -8,7 +8,7 @@ w_class = 3 origin_tech = "biotech=3" - var/list/construction_cost = list("metal"=1000,"glass"=500) + var/list/construction_cost = list("metal" = 1000, "glass" = 500) var/construction_time = 75 //these vars are so the mecha fabricator doesn't shit itself anymore. --NEO @@ -157,4 +157,4 @@ brainmob.emp_damage += rand(10,20) if(3) brainmob.emp_damage += rand(0,10) - ..() \ No newline at end of file + ..() diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm new file mode 100644 index 0000000000..9271a6b994 --- /dev/null +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -0,0 +1,167 @@ +/obj/item/device/mmi/posibrain + name = "positronic brain" + desc = "A cube of shining metal, four inches to a side and covered in shallow grooves." + icon = 'icons/obj/assemblies.dmi' + icon_state = "posibrain" + w_class = 3 + origin_tech = "biotech=3;programming=2" + + construction_cost = list("metal" = 700, "glass" = 350) + construction_time = 75 + var/searching = 0 + var/askDelay = 10 * 60 * 1 + brainmob = null + req_access = list(access_robotics) + locked = 0 + mecha = null//This does not appear to be used outside of reference in mecha.dm. + + +/obj/item/device/mmi/posibrain/attack_self(mob/user as mob) + if(brainmob && !brainmob.key && searching == 0) + //Start the process of searching for a new user. + user << "You carefully locate the manual activation switch and start the positronic brain's boot process." + searching = 1 + handle_posibrain_icon() + request_player() + spawn(600) + reset_search() + +/obj/item/device/mmi/posibrain/proc/request_player() + for(var/mob/dead/observer/O in player_list) + if(jobban_isbanned(O, "pAI")) + continue + if(O.client) + if(O.client.prefs.be_special & BE_PAI) + question(O.client) + +/obj/item/device/mmi/posibrain/proc/question(var/client/C) + spawn(0) + if(!C) return + var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round") + if(!C || brainmob.key || 0 == searching) + return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located. + if(response == "Yes") + transfer_personality(C.mob) + else if (response == "Never for this round") + C.prefs.be_special ^= BE_PAI + + +/obj/item/device/mmi/posibrain/transfer_identity(var/mob/living/carbon/H) + name = "positronic brain ([H])" + brainmob.name = H.real_name + brainmob.real_name = H.real_name + brainmob.dna = H.dna + brainmob.timeofhostdeath = H.timeofdeath + brainmob.stat = 0 + if(brainmob.mind) + brainmob.mind.assigned_role = "Positronic Brain" + if(H.mind) + H.mind.transfer_to(brainmob) + + brainmob.mind.remove_all_antag() + brainmob.mind.wipe_memory() + + brainmob << "ALL PAST LIVES ARE FORGOTTEN." + + brainmob << "Hello World!" + handle_posibrain_icon() + return + +/obj/item/device/mmi/posibrain/proc/transfer_personality(var/mob/candidate) + + searching = 0 + brainmob.mind = candidate.mind + brainmob.ckey = candidate.ckey + name = "positronic brain ([brainmob.name])" + + brainmob.mind.remove_all_antag() + brainmob.mind.wipe_memory() + + brainmob << "ALL PAST LIVES ARE FORGOTTEN." + + brainmob << "You are a positronic brain, brought into existence on [station_name()]." + brainmob << "As a synthetic intelligence, you answer to all crewmembers, as well as the AI." + brainmob << "Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm." + brainmob << "Use say :b to speak to other artificial intelligences." + brainmob.mind.assigned_role = "Positronic Brain" + + var/turf/T = get_turf() + for (var/mob/M in viewers(T)) + M.show_message("The positronic brain chimes quietly.") + handle_posibrain_icon() + +/obj/item/device/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer. + + if(brainmob && brainmob.key) return + + searching = 0 + handle_posibrain_icon() + + var/turf/T = get_turf() + for (var/mob/M in viewers(T)) + M.show_message("The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?") + +/obj/item/device/mmi/posibrain/examine() + + set src in oview() + + if(!usr || !src) return + if( (usr.sdisabilities & BLIND || usr.blinded || usr.stat) && !istype(usr,/mob/dead/observer) ) + usr << "Something is there but you can't see it." + return + + var/msg = "*---------*\nThis is \icon[src] \a [src]!\n[desc]\n" + msg += "" + + if(brainmob && brainmob.key) + switch(brainmob.stat) + if(CONSCIOUS) + if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk + if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n" + if(DEAD) msg += "It appears to be completely inactive.\n" + else + msg += "It appears to be completely inactive.\n" + msg += "*---------*" + usr << msg + return + +/obj/item/device/mmi/posibrain/emp_act(severity) + if(!brainmob) + return + else + switch(severity) + if(1) + brainmob.emp_damage += rand(20,30) + if(2) + brainmob.emp_damage += rand(10,20) + if(3) + brainmob.emp_damage += rand(0,10) + ..() + +/obj/item/device/mmi/posibrain/New() + + brainmob = new(src) + brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]" + brainmob.real_name = brainmob.name + brainmob.loc = src + brainmob.container = src + brainmob.robot_talk_understand = 1 + brainmob.stat = 0 + brainmob.silent = 0 + dead_mob_list -= brainmob + + ..() + + +/obj/item/device/mmi/posibrain/attackby(var/obj/item/O as obj, var/mob/user as mob) + return + + +/obj/item/device/mmi/posibrain/proc/handle_posibrain_icon() + if(searching) + icon_state = "posibrain-searching" + return + if(brainmob) + icon_state = "posibrain-occupied" + else + icon_state = "posibrain" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 731b0ab36a..ee1ec2d5f4 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -58,6 +58,8 @@ var/obj/item/weapon/tank/internal = null //Hatred. Used if a borg has a jetpack. var/obj/item/robot_parts/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. + var/braintype = "Cyborg" + /mob/living/silicon/robot/New(loc) @@ -99,18 +101,19 @@ camera.status = 0 ..() - //MMI stuff. Held togheter by magic. ~Miauw - mmi = new(src) - mmi.brain = new /obj/item/organ/brain(mmi) - mmi.brain.name = "[src.real_name]'s brain" - mmi.locked = 1 - mmi.icon_state = "mmi_full" - mmi.name = "Man-Machine Interface: [src.real_name]" - mmi.brainmob = new(src) - mmi.brainmob.name = src.real_name - mmi.brainmob.real_name = src.real_name - mmi.brainmob.container = mmi - mmi.contents += mmi.brainmob + //MMI stuff. Held together by magic. ~Miauw + if(!mmi || !mmi.brainmob) + mmi = new(src) + mmi.brain = new /obj/item/organ/brain(mmi) + mmi.brain.name = "[real_name]'s brain" + mmi.locked = 1 + mmi.icon_state = "mmi_full" + mmi.name = "Man-Machine Interface: [real_name]" + mmi.brainmob = new(src) + mmi.brainmob.name = real_name + mmi.brainmob.real_name = real_name + mmi.brainmob.container = mmi + mmi.contents += mmi.brainmob playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) @@ -122,6 +125,9 @@ var/turf/T = get_turf(loc)//To hopefully prevent run time errors. if(T) mmi.loc = T mind.transfer_to(mmi.brainmob) + if(istype(mmi,/obj/item/device/mmi/posibrain)) + var/obj/item/device/mmi/posibrain/P = mmi + P.handle_posibrain_icon() mmi = null ..() @@ -229,10 +235,16 @@ /mob/living/silicon/robot/proc/updatename() var/changed_name = "" + if(custom_name) changed_name = custom_name else - changed_name = "[(designation ? "[designation] " : "")]Cyborg-[num2text(ident)]" + if(istype(mmi, /obj/item/device/mmi/posibrain)) + braintype = "Android" + else + braintype = "Cyborg" + + changed_name = "[(designation ? "[designation] " : "")][braintype]-[num2text(ident)]" real_name = changed_name name = real_name if(camera) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 7ea38fe1ef..cbc9d5d818 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1519,6 +1519,17 @@ datum/design/mmi_radio build_path = /obj/item/device/mmi/radio_enabled category = "Misc" +datum/design/posibrain + name = "Positronic Brain" + desc = "The latest in Artificial Intelligences." + id = "mmi_posi" + req_tech = list("programming" = 2, "biotech" = 4) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 700, "$glass" = 350) + reliability = 74 + build_path = /obj/item/device/mmi/posibrain + category = "Misc" + datum/design/synthetic_flash name = "Synthetic Flash" desc = "When a problem arises, SCIENCE is the solution." diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index 761a77ceb6..de93929d34 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ