From 9e50fd8e962e0b9d4d32fb08eaa1565215e45902 Mon Sep 17 00:00:00 2001 From: "n3ophyt3@gmail.com" Date: Wed, 30 Mar 2011 02:42:54 +0000 Subject: [PATCH] MMI update the third and fourth. Barring some big huge bug that didn't turn up in my testing to make sure shit works, the MMI is ready for showtime. If you're wondering why updates third and fourth happened together, in update the third I redid how brains work, and I was halfway to committing it when I realized "wait, if I upload this now, everything that uses the brain will cause fuckups". Notable changes: When your brain is cut out, instead of your client hanging around inside your now brainless and more or less useless body, it it shunted into the brain object, similar to an AI in an intellicard. While not in an MMI, your brain is "dead", deathchat and all. When stuck into an MMI, you spring to 'life', allowing you to talk to whoever stuck your brain into the thing. It occurs to me while I'm typing this up that it would be very easy to abuse this communication between life and death by slapping brains in and out of MMIs. DO NOT DO THIS OR THE ADMINS WILL HATE YOU AND DO MEAN THINGS TO YOU. Life in an MMI is pretty boring, so you should yell at people until they stick you into an AI core or robot frame to give you something to do. I know the MMI was originally thought up as a mecha interface, but I haven't gotten around to looking at the mecha code to figure out how to hook it in yet. I suspect there's going to be howls of "WHY DO YOU HATE ROBOTICISTS" over this next part, but the MMI itself is an R&D-researched object, with a biotech level of 3. That said, the station starts with two of them in the operating room (to get the research level up if nothing else), and they are producible at the protolathe AND the mecha fabricator (since they will eventually get to plug into a mecha.) Known issues: The MMI is SUPPOSED to pop out of a cyborg with the player attached when the cyborg goes pop, but it didn't in my initial testing, simply ghosting the borg as they already do. Will work on this as I have time, but what with having to go to work these days, I have somewhat less of that. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1311 316c924e-a436-60f5-8080-3fe189b3f50e --- code/defines/mob/living/silicon/robot.dm | 2 + code/defines/obj.dm | 20 +++++++++ code/game/gamemodes/objective.dm | 4 +- code/game/machinery/computer/AIcore.dm | 10 ++++- code/game/machinery/microwave.dm | 2 + code/game/objects/items.dm | 20 +++++---- code/game/objects/items/robot_parts.dm | 21 ++++++---- code/game/research/designs.dm | 10 +++++ code/modules/admin/admin_verbs.dm | 4 +- code/modules/mob/dead/observer/observer.dm | 5 ++- code/modules/mob/living/carbon/brain/MMI.dm | 41 ++++++++++++------- code/modules/mob/living/carbon/brain/brain.dm | 6 +++ code/modules/mob/living/carbon/brain/death.dm | 9 ++-- code/modules/mob/living/carbon/brain/say.dm | 3 ++ code/modules/mob/living/carbon/human/say.dm | 2 + code/modules/mob/living/silicon/ai/ai.dm | 6 +-- .../modules/mob/living/silicon/robot/robot.dm | 7 ++++ maps/tgstation.2.0.5.dmm | 2 +- tgstation.dme | 1 + 19 files changed, 129 insertions(+), 46 deletions(-) create mode 100644 code/modules/mob/living/carbon/brain/say.dm diff --git a/code/defines/mob/living/silicon/robot.dm b/code/defines/mob/living/silicon/robot.dm index 9cc8ebbfc73..ad8e2375494 100644 --- a/code/defines/mob/living/silicon/robot.dm +++ b/code/defines/mob/living/silicon/robot.dm @@ -27,6 +27,8 @@ var/obj/item/weapon/cell/cell = null var/obj/machinery/camera/camera = null + var/obj/item/device/mmi/brain = null + var/opened = 0 var/emagged = 0 var/wiresexposed = 0 diff --git a/code/defines/obj.dm b/code/defines/obj.dm index c5d2b88a22e..5425a8ad5b2 100644 --- a/code/defines/obj.dm +++ b/code/defines/obj.dm @@ -794,6 +794,7 @@ origin_tech = "biotech=3" var/mob/living/carbon/human/owner = null + var/mob/living/carbon/brain/brainmob = null /obj/item/brain/New() @@ -801,6 +802,25 @@ spawn(5) if(src.owner) src.name = "[src.owner]'s brain" + //Shifting the brain "mob" over to the brain object so it's easier to keep track of. --NEO + brainmob = new /mob/living/carbon/brain + brainmob.loc = src + brainmob.name = owner.real_name + brainmob.real_name = owner.real_name + src.owner.mind.transfer_to(brainmob) + brainmob.death() //the brain is dead until stuffed into an MMI. In which case it might still be dead if it's been beat up. + brainmob.client.screen.len = null //clear the hud + brainmob << "\blue You might feel slightly disoriented. That's normal when your brain gets cut out." + +/obj/item/brain/Del() + if(src.brainmob) + if(src.brainmob.client) + var/mob/dead/observer/newmob + newmob = new/mob/dead/observer + newmob.loc = get_turf(src) + src.brainmob:client:mob = newmob + newmob:client:eye = newmob + ..() /obj/noticeboard name = "Notice Board" diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 5bf956e0a9a..587089ac7fc 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -46,7 +46,7 @@ datum check_completion() if(target && target.current) - if(target.current.stat == 2 || istype(target.current.loc.loc, /area/tdome) || istype(target.current,/mob/living/silicon)) //Assuming this works, people in the thunderdome and borgs now count as dead for traitor objectives. --NeoFite + if(target.current.stat == 2 || istype(target.current.loc.loc, /area/tdome) || istype(target.current,/mob/living/silicon) || istype(target.current,/mob/living/carbon/brain)) //Assuming this works, people in the thunderdome and borgs now count as dead for traitor objectives. --NeoFite return 1 else return 0 @@ -81,6 +81,8 @@ datum check_completion() if(istype(owner.current, /mob/living/silicon)) return 0 + if(istype(owner.current, /mob/living/carbon/brain)) + return 0 if(emergency_shuttle.location<2) return 0 diff --git a/code/game/machinery/computer/AIcore.dm b/code/game/machinery/computer/AIcore.dm index 950b46c9226..51ed8058f2b 100644 --- a/code/game/machinery/computer/AIcore.dm +++ b/code/game/machinery/computer/AIcore.dm @@ -7,7 +7,7 @@ var/state = 0 var/datum/ai_laws/laws = new /datum/ai_laws/asimov var/obj/item/weapon/circuitboard/circuit = null - var/obj/item/brain/brain = null + var/obj/item/device/mmi/brain = null /obj/AIcore/attackby(obj/item/P as obj, mob/user as mob) @@ -105,7 +105,13 @@ src.laws.add_inherent_law(M.newFreeFormLaw) usr << "Added a freeform law." - if(istype(P, /obj/item/brain)) + if(istype(P, /obj/item/device/mmi)) + if(!P:brain) + user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose." + return + if(P:brain.brainmob.stat == 2) + user << "\red Sticking a dead brain into the frame would sort of defeat the purpose." + return user.drop_item() P.loc = src src.brain = P diff --git a/code/game/machinery/microwave.dm b/code/game/machinery/microwave.dm index 70cc4ebd467..fcdda58aa7f 100644 --- a/code/game/machinery/microwave.dm +++ b/code/game/machinery/microwave.dm @@ -571,6 +571,8 @@ Please clean it before use!
src.extra_item = null else //Otherwise it was empty, so just turn it on then off again with nothing happening + for(var/obj/O in src.contents) + del(O) //with how brains work now, need to make sure they get deleted so the poor player inside it gets ghosted. --NEO src.operating = 1 src.icon_state = "mw1" src.updateUsrDialog() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index e9467f70d3e..b8fbeebc9f1 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -341,21 +341,23 @@ if(M.client) M.client.mob = new/mob/dead/observer(M) //a mob can't have two clients so get rid of one - - if(src.owner) + //this might actually be outdated since barring badminnery, a debrain'd body will have any client sucked out to the brain's internal mob. Leaving it anyway to be safe. --NEO + src.brainmob.mind.transfer_to(M) + src.brainmob = null +// if(src.owner) //if the brain has an owner corpse - if(src.owner.client) +// if(src.owner.client) //if the player hasn't ghosted - src.owner.client.mob = M +// src.owner.client.mob = M //then put them in M - else +// else //if the player HAS ghosted - for(var/mob/dead/observer/O in world) - if(O.corpse == src.owner && O.client) +// for(var/mob/dead/observer/O in world) +// if(O.corpse == src.owner && O.client) //find their ghost - O.client.mob = M +// O.client.mob = M //put their mob in M - del(O) +// del(O) //delete thier ghost M:brain_op_stage = 3.0 diff --git a/code/game/objects/items/robot_parts.dm b/code/game/objects/items/robot_parts.dm index d8c87bc60eb..d7ffd56e4d6 100644 --- a/code/game/objects/items/robot_parts.dm +++ b/code/game/objects/items/robot_parts.dm @@ -127,27 +127,31 @@ else user << "\blue You need to attach a flash to it first!" - if(istype(W, /obj/item/brain)) + if(istype(W, /obj/item/device/mmi)) if(src.check_completion()) if(!istype(src.loc,/turf)) - user << "\red You can't put the brain in, it has to be standing on the ground to be perfectly precise." + user << "\red You can't put the MMI in, the frame has to be standing on the ground to be perfectly precise." + return + if(!W:brain) + user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose." + return + if(W:brain.brainmob.stat == 2) + user << "\red Sticking a dead brain into the frame would sort of defeat the purpose." return user.drop_item() W.loc = src src.brain = W var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(src.loc)) - if (src.brain.owner) - O.gender = src.brain.owner.gender //O.start = 1 O.invisibility = 0 O.name = src.created_name O.real_name = src.created_name - if (src.brain.owner.client) - src.brain.owner.mind.transfer_to(O) + if (W:brain.brainmob) + W:brain.brainmob.mind.transfer_to(O) else for(var/mob/dead/observer/G in world) - if(G.corpse == src.brain.owner && G.client) + if(G.corpse == W:brain.brainmob && G.client) G.corpse.mind.transfer_to(O) del(G) break @@ -165,10 +169,11 @@ O.cell = src.chest.cell O.cell.loc = O + O.brain = W del(src) else - user << "\blue The brain must go in after everything else!" + user << "\blue The MMI must go in after everything else!" if (istype(W, /obj/item/weapon/pen)) var/t = input(user, "Enter new robot name", src.name, src.created_name) as text diff --git a/code/game/research/designs.dm b/code/game/research/designs.dm index 0d800c827c4..3748a569622 100644 --- a/code/game/research/designs.dm +++ b/code/game/research/designs.dm @@ -853,6 +853,16 @@ datum reliability_base = 74 build_path = "/obj/item/device/mass_spectrometer/adv" + mmi + name = "Man-Machine Interface" + desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity." + id = "mmi" + req_tech = list("biotech" = 3) + build_type = PROTOLATHE | MECHFAB + materials = list("$metal" = 1000, "$glass" = 500) + reliability_base = 76 + build_path = "/obj/item/device/mmi" + ///////////////////////////////////////// /////////////////Weapons///////////////// ///////////////////////////////////////// diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 757cf043e32..e8c289bf4ee 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1121,7 +1121,7 @@ src.verbs -= /obj/admins/proc/unprison src.verbs -= /proc/togglebuildmode src.verbs -= /client/proc/cmd_mass_modify_object_variables - + src.verbs -= /client/proc/triple_ai src.verbs -= /client/proc/only_one // Unnecessary commands @@ -1172,7 +1172,7 @@ src.holder.state = 2 update_admins(rank) if(!istype(src.mob, /mob/dead/observer)) - src.mob.ghostize() + src.mob.ghostize(1) src << "\blue You are now observing" /client/proc/admin_play() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index bda1865c8c3..335737b6d08 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -12,10 +12,13 @@ src.name = corpse.real_name src.verbs += /mob/dead/observer/proc/reenter_corpse -/mob/proc/ghostize() +/mob/proc/ghostize(var/adminoverride = 0) set category = "Special Verbs" set name = "Ghost" set desc = "You cannot be revived as a ghost" + if(src.stat != 2 && !adminoverride) + src << "Only dead people and admins get to ghost, and admins don't use this verb to ghost while alive." + return if(src.client) src.client.mob = new/mob/dead/observer(src) return diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm index 0501b18bb3d..317f7b7777a 100644 --- a/code/modules/mob/living/carbon/brain/MMI.dm +++ b/code/modules/mob/living/carbon/brain/MMI.dm @@ -4,9 +4,9 @@ icon = 'assemblies.dmi' icon_state = "mmi_empty" w_class = 3 + origin_tech = "biotech=3" var/obj/item/brain/brain = null - var/mob/living/carbon/brain/brainmob = null var/mob/living/silicon/robot = null var/obj/mecha = null var/locked = 0 @@ -14,26 +14,21 @@ attackby(var/obj/item/O as obj, var/mob/user as mob) if(istype(O,/obj/item/brain) && !brain) //Time to stick a brain in it --NEO - + if(!O:owner) + user << "\red You aren't sure where this brain came from, but you're pretty sure it's a useless brain." + return for(var/mob/V in viewers(src, null)) V.show_message(text("\blue [user] sticks \a [O] into \the [src].")) brain = O user.drop_item() O.loc = src - - //Adding the actual mob the brain's player gets moved to. --NEO - brainmob = new /mob/living/carbon/brain - brainmob.loc = src - brainmob.name = brain.owner.real_name - brainmob.real_name = brain.owner.real_name - brainmob.container = src - brain.owner.mind.transfer_to(brainmob) - brainmob.client.screen.len = null - - name = "Man-Machine Interface:[brainmob.real_name]" - icon_state = "mmi_full" + brain.brainmob.container = src + brain.brainmob.stat = 0 locked = 1 + name = "Man-Machine Interface:[brain.brainmob.real_name]" + icon_state = "mmi_full" return + if((istype(O,/obj/item/weapon/card/id)||istype(O,/obj/item/device/pda)) && brain) if(allowed(user)) locked = !locked @@ -42,8 +37,24 @@ user << "\red Access denied." return if(brain) - O.attack(brainmob, user) + O.attack(brain.brainmob, user) return ..() + attack_self(mob/user as mob) + if(!brain) + user << "\red You upend the MMI, but there's nothing in it." + else if(locked) + user << "\red You upend the MMI, but the brain is clamped into place." + else + user << "\blue You upend the MMI, spilling the brain onto the floor." + brain.loc = user.loc + brain.brainmob.container = null + brain.brainmob.death() + brain = null + icon_state = "mmi_empty" + name = "Man-Machine Interface" + + + diff --git a/code/modules/mob/living/carbon/brain/brain.dm b/code/modules/mob/living/carbon/brain/brain.dm index 3ead33ac25e..aee453863bb 100644 --- a/code/modules/mob/living/carbon/brain/brain.dm +++ b/code/modules/mob/living/carbon/brain/brain.dm @@ -18,6 +18,12 @@ return 1 return ..() +// verb +// body_jump() +// set category = "Special Verbs" +// set name = "Check on Original Body" + + /obj/hud/proc/brain_hud(var/ui_style='screen1_old.dmi') src.station_explosion = new src.h_type( src ) src.station_explosion.icon = 'station_explosion.dmi' diff --git a/code/modules/mob/living/carbon/brain/death.dm b/code/modules/mob/living/carbon/brain/death.dm index eeede342a22..8986d162aec 100644 --- a/code/modules/mob/living/carbon/brain/death.dm +++ b/code/modules/mob/living/carbon/brain/death.dm @@ -1,9 +1,10 @@ /mob/living/carbon/brain/death(gibbed) var/cancel - if (!gibbed) - for(var/mob/O in viewers(src.container, null)) - O.show_message(text("\red []'s MMI flatlines!", src), 1, "\red You hear something flatline.", 2) - src.container.icon_state = "mmi_dead" + if(src.container) + if (!gibbed) + for(var/mob/O in viewers(src.container, null)) + O.show_message(text("\red []'s MMI flatlines!", src), 1, "\red You hear something flatline.", 2) + src.container.icon_state = "mmi_dead" src.stat = 2 if(src.blind) diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm new file mode 100644 index 00000000000..da7ac7c2da1 --- /dev/null +++ b/code/modules/mob/living/carbon/brain/say.dm @@ -0,0 +1,3 @@ +/mob/living/carbon/brain/say(var/message) + if(!container && stat != 2) return //In case of some mysterious happenings where a "living" brain is not in an MMI, don't let it speak. --NEO + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index d31d6958a54..3faacd1b5cd 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -33,4 +33,6 @@ return 1 if (istype(other, /mob/living/silicon/robot)) return 1 + if (istype(other, /mob/living/carbon/brain)) + return 1 return ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index f3518b009c7..aba5464415c 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -1,4 +1,4 @@ -/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/brain/B) +/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B) src.anchored = 1 src.canmove = 0 src.loc = loc @@ -24,8 +24,8 @@ src.real_name = "Inactive AI" src.icon_state = "ai-empty" else - if (B.owner.mind) - B.owner.mind.transfer_to(src) + if (B.brain.brainmob.mind) + B.brain.brainmob.mind.transfer_to(src) src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." src << "To look at other parts of the station, double-click yourself to get a camera menu." diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index ffcb9b30eb0..bb4f00e8037 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -35,6 +35,13 @@ src.cell = C ..() +/mob/living/silicon/robot/Del() + if(brain) + brain.loc = loc + mind.transfer_to(brain.brain.brainmob) + ..() + //If there's an MMI in the robot, have it ejected when the mob goes away. --NEO + /mob/living/silicon/robot/proc/pick_module() if(src.module) return diff --git a/maps/tgstation.2.0.5.dmm b/maps/tgstation.2.0.5.dmm index 3e802d2d604..417bc08a672 100644 --- a/maps/tgstation.2.0.5.dmm +++ b/maps/tgstation.2.0.5.dmm @@ -3323,7 +3323,7 @@ "blU" = (/obj/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = "Streight"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "blV" = (/obj/cable{d1 = 4; d2 = 8; icon_state = "4-8"; tag = "Streight"},/obj/machinery/atmospherics/pipe/simple{color = "blue"; icon_state = "intact-b-f"; level = 1; name = "pipe"},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/medical{name = "Operating Theatre"; req_access_txt = "45"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "blW" = (/obj/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = "90Curve"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) -"blX" = (/obj/table{dir = 10; icon_state = "tabledir"},/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) +"blX" = (/obj/table{dir = 10; icon_state = "tabledir"},/obj/item/device/mmi,/obj/item/device/mmi,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery) "blY" = (/obj/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = "Streight"},/turf/simulated/floor{icon_state = "dark"},/area/medical/surgery) "blZ" = (/obj/closet/firecloset,/turf/simulated/floor/plating,/area/maintenance/starboard) "bma" = (/obj/grille,/obj/window/reinforced,/obj/window/reinforced{dir = 4},/obj/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/storage) diff --git a/tgstation.dme b/tgstation.dme index 52d5a110cfe..d1f7e5779c9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -655,6 +655,7 @@ #include "code\modules\mob\living\carbon\brain\death.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\say.dm" #include "code\modules\mob\living\carbon\human\death.dm" #include "code\modules\mob\living\carbon\human\emote.dm" #include "code\modules\mob\living\carbon\human\examine.dm"