Adds a radio MMI upgrade module, printable in the mech fab

Can be uninstalled with a screwdriver
This commit is contained in:
Crazylemon64
2018-06-24 12:56:39 -07:00
parent 4fec0d6b0a
commit be4a1e426d
8 changed files with 200 additions and 71 deletions
+136 -44
View File
@@ -16,6 +16,9 @@
var/obj/mecha/mecha = null//This does not appear to be used outside of reference in mecha.dm.
// I'm using this for mechs giving MMIs HUDs now
var/obj/item/radio/radio = null // For use with the radio MMI upgrade
var/datum/action/generic/configure_mmi_radio/radio_action = null
/obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/organ/internal/brain/crystal ))
to_chat(user, "<span class='warning'> This brain is too malformed to be able to use with the [src].</span>")
@@ -29,34 +32,70 @@
to_chat(user, "<span class='userdanger'>Somehow, this MMI still has a brain in it. Report this to the bug tracker.</span>")
log_runtime(EXCEPTION("[user] tried to stick a [O] into [src] in [get_area(src)], but the held brain variable wasn't cleared"), src)
return
for(var/mob/V in viewers(src, null))
V.show_message("<span class='notice'>[user] sticks \a [O] into \the [src].</span>")
brainmob = B.brainmob
B.brainmob = null
brainmob.loc = src
brainmob.container = src
brainmob.stat = CONSCIOUS
respawnable_list -= brainmob
dead_mob_list -= brainmob//Update dem lists
living_mob_list += brainmob
if(user.drop_item())
B.forceMove(src)
visible_message("<span class='notice'>[user] sticks \a [O] into \the [src].</span>")
brainmob = B.brainmob
B.brainmob = null
brainmob.loc = src
brainmob.container = src
brainmob.stat = CONSCIOUS
respawnable_list -= brainmob
dead_mob_list -= brainmob//Update dem lists
living_mob_list += brainmob
user.drop_item()
B.forceMove(src)
held_brain = B
if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
name = "Man-Machine Interface: Alien - [brainmob.real_name]"
icon = 'icons/mob/alien.dmi'
icon_state = "AlienMMI"
alien = 1
held_brain = B
if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
name = "Man-Machine Interface: Alien - [brainmob.real_name]"
icon = 'icons/mob/alien.dmi'
become_occupied("AlienMMI")
alien = 1
else
name = "Man-Machine Interface: [brainmob.real_name]"
icon = B.mmi_icon
become_occupied("[B.mmi_icon_state]")
alien = 0
if(radio_action)
radio_action.UpdateButtonIcon()
feedback_inc("cyborg_mmis_filled",1)
else
name = "Man-Machine Interface: [brainmob.real_name]"
icon = B.mmi_icon
icon_state = "[B.mmi_icon_state]"
alien = 0
feedback_inc("cyborg_mmis_filled",1)
to_chat(user, "<span class='warning'>You can't drop [B]!</span>")
return
if(istype(O, /obj/item/mmi_radio_upgrade))
if(radio)
to_chat(user, "<span class='warning'>[src] already has a radio installed.</span>")
else
user.visible_message("<span class='notice'>[user] begins to install the [O] into [src]...</span>", \
"<span class='notice'>You start to install the [O] into [src]...</span>")
if(do_after(user, 20, target=src))
if(user.drop_item())
user.visible_message("<span class='notice'>[user] installs [O] in [src].</span>", \
"<span class='notice'>You install [O] in [src].</span>")
if(brainmob)
to_chat(brainmob, "<span class='notice'>MMI radio capability installed.</span>")
install_radio()
qdel(O)
else
to_chat(user, "<span class='warning'>You can't drop [O]!</span>")
return
// Maybe later add encryption key support, but that's a pain in the neck atm
if(isscrewdriver(O))
if(radio)
user.visible_message("<span class='warning'>[user] begins to uninstall the radio from [src]...</span>", \
"<span class='notice'>You start to uninstall the radio from [src]...</span>")
if(do_after(user, 40 * O.toolspeed, target = src))
uninstall_radio()
new /obj/item/mmi_radio_upgrade(get_turf(src))
user.visible_message("<span class='warning'>[user] uninstalls the radio from [src].</span>", \
"<span class='notice'>You uninstall the radio from [src].</span>")
else
to_chat(user, "<span class='warning'>There is no radio in [src]!</span>")
return
if(brainmob)
O.attack(brainmob, user)//Oh noooeeeee
// Brainmobs can take damage, but they can't actually die. Maybe should fix.
@@ -93,8 +132,7 @@
held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]"
name = "Man-Machine Interface: [brainmob.real_name]"
icon_state = "mmi_full"
return
become_occupied("mmi_full")
//I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the
//problem i was having with alien/nonalien brain drops.
@@ -116,31 +154,54 @@
held_brain.forceMove(dropspot)
held_brain = null
/obj/item/mmi/proc/become_occupied(var/new_icon)
icon_state = new_icon
if(radio)
radio_action.ApplyIcon()
/obj/item/mmi/radio_enabled
name = "Radio-enabled Man-Machine Interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio."
origin_tech = "biotech=2;programming=3;engineering=2;magnets=2"
/obj/item/mmi/examine(mob/user)
. = ..()
if(radio)
to_chat(user, "<span class='notice'>A radio is installed on [src].</span>")
var/obj/item/radio/radio = null//Let's give it a radio.
/obj/item/mmi/proc/install_radio()
radio = new(src)
radio.broadcasting = TRUE
radio_action = new(radio, src)
if(brainmob && brainmob.loc == src)
radio_action.Grant(brainmob)
/obj/item/mmi/radio_enabled/New()
..()
radio = new(src)//Spawns a radio inside the MMI.
radio.broadcasting = 1//So it's broadcasting from the start.
/obj/item/mmi/proc/uninstall_radio()
QDEL_NULL(radio)
QDEL_NULL(radio_action)
/obj/item/mmi/radio_enabled/verb/Toggle_Listening()
set name = "Toggle Listening"
set desc = "Toggle listening channel on or off."
set category = "MMI"
set src = usr.loc
set popup_menu = 0
/datum/action/generic/configure_mmi_radio
name = "Configure MMI Radio"
desc = "Configure the radio installed in your MMI."
check_flags = AB_CHECK_CONSCIOUS
procname = "ui_interact"
var/obj/item/mmi = null
if(brainmob.stat)
to_chat(brainmob, "Can't do that while incapacitated or dead.")
/datum/action/generic/configure_mmi_radio/New(var/Target, var/obj/item/mmi/M)
. = ..()
mmi = M
radio.listening = radio.listening==1 ? 0 : 1
to_chat(brainmob, "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>")
/datum/action/generic/configure_mmi_radio/Destroy()
mmi = null
return ..()
/datum/action/generic/configure_mmi_radio/ApplyIcon(obj/screen/movable/action_button/current_button)
// A copy/paste of the item action icon code
current_button.overlays.Cut()
if(target)
var/obj/item/I = mmi
var/old_layer = I.layer
var/old_plane = I.plane
I.layer = 21
I.plane = HUD_PLANE
current_button.overlays += I
I.layer = old_layer
I.plane = old_plane
/obj/item/mmi/emp_act(severity)
if(!brainmob)
@@ -168,8 +229,22 @@
borg.mmi = null
QDEL_NULL(brainmob)
QDEL_NULL(held_brain)
QDEL_NULL(radio)
QDEL_NULL(radio_action)
return ..()
// These two procs are important for when an MMI pilots a mech
// (Brainmob "enters/leaves" the MMI when piloting)
// Also neatly handles basically every case where a brain
// is inserted or removed from an MMI
/obj/item/mmi/Entered(atom/movable/A)
if(radio && istype(A, /mob/living/carbon/brain))
radio_action.Grant(A)
/obj/item/mmi/Exited(atom/movable/A)
if(radio && istype(A, /mob/living/carbon/brain))
radio_action.Remove(A)
/obj/item/mmi/syndie
name = "Syndicate Man-Machine Interface"
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
@@ -197,3 +272,20 @@
holder.insert(H)
return 1
// As a synthetic, the only limit on visibility is view range
/obj/item/mmi/contents_nano_distance(var/src_object, var/mob/living/user)
if((src_object in view(src)) && get_dist(src_object, src) <= user.client.view)
return STATUS_INTERACTIVE // interactive (green visibility)
return user.shared_living_nano_distance(src_object)
// For now the only thing that is helped by this is radio access
// Later a more intricate system for MMI UI interaction can be established
/obj/item/mmi/contents_nano_interact(var/src_object, var/mob/living/user)
if(!istype(user, /mob/living/carbon/brain))
log_runtime(EXCEPTION("Somehow a non-brain mob is inside an MMI!"), user)
return ..()
var/mob/living/carbon/brain/BM = user
if(BM.container == src && src_object == radio)
return STATUS_INTERACTIVE
return ..()
@@ -0,0 +1,5 @@
/obj/item/mmi_radio_upgrade
name = "MMI radio upgrade"
desc = "Enables radio capability on MMIs when either installed directly on the MMI, or through a cyborg's chassis."
icon = 'icons/obj/module.dmi'
icon_state = "cyborg_upgrade1"
@@ -81,7 +81,9 @@
if(H.mind)
H.mind.transfer_to(brainmob)
to_chat(brainmob, "<span class='notice'>You feel slightly disoriented. That's normal when you're just a metal cube.</span>")
icon_state = "posibrain-occupied"
become_occupied("posibrain-occupied")
if(radio)
radio_action.ApplyIcon()
return
/obj/item/mmi/posibrain/proc/transfer_personality(var/mob/candidate)
@@ -97,7 +99,8 @@
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='notice'>The positronic brain chimes quietly.</span>")
icon_state = "posibrain-occupied"
become_occupied("posibrain-occupied")
/obj/item/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(src.brainmob && src.brainmob.key) return
@@ -142,22 +145,23 @@
/obj/item/mmi/posibrain/examine(mob/user)
to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].")
to_chat(user, "<span class='info'>*---------*</span>")
if(!..(user))
. = ..()
if(!.)
to_chat(user, "<span class='info'>*---------*</span>")
return
var/list/msg = "<span class='info'>"
var/list/msg = list("<span class='info'>")
if(brainmob && brainmob.key)
switch(brainmob.stat)
if(CONSCIOUS)
if(!brainmob.client) msg += "It appears to be in stand-by mode." //afk
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responsive.</span>"
if(DEAD) msg += "<span class='deadsay'>It appears to be completely inactive.</span>"
if(!brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responsive.</span>\n"
if(DEAD) msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
else
msg += "<span class='deadsay'>It appears to be completely inactive.</span>"
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
msg += "*---------*</span>"
to_chat(user, msg.Join("\n"))
to_chat(user, msg.Join(""))
/obj/item/mmi/posibrain/emp_act(severity)
if(!src.brainmob)
+6 -8
View File
@@ -2,7 +2,7 @@
/mob/living/carbon/brain/say(var/message, var/datum/language/speaking = null)
if(!can_speak(warning = TRUE))
return
if(prob(emp_damage * 4))
if(prob(10)) //10% chance to drop the message entirely
return
@@ -10,13 +10,13 @@
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
..(message)
/mob/living/carbon/brain/whisper(message as text)
if(!can_speak(warning = TRUE))
return
..()
/mob/living/carbon/brain/can_speak(var/warning = FALSE)
. = ..()
@@ -41,12 +41,10 @@
if(metalgear.radio)
radio_worked = metalgear.radio.talk_into(src, message, message_mode, verb, speaking)
else if(!radio_worked && istype(c, /obj/item/mmi/radio_enabled))
var/obj/item/mmi/radio_enabled/R = c
if(R.radio)
radio_worked = R.radio.talk_into(src, message, message_mode, verb, speaking)
else if(!radio_worked && c.radio)
radio_worked = c.radio.talk_into(src, message, message_mode, verb, speaking)
return radio_worked
if("whisper")
whisper_say(message, speaking, alt_name)
return 1
else return 0
else return 0
+17 -2
View File
@@ -738,7 +738,7 @@ var/list/robot_verbs_default = list(
else if(istype(W, /obj/item/borg/upgrade/))
var/obj/item/borg/upgrade/U = W
if(!opened)
to_chat(user, "<span class='warning'>You must access the borgs internals!</span>")
to_chat(user, "<span class='warning'>You must access the borg's internals!</span>")
else if(!src.module && U.require_module)
to_chat(user, "<span class='warning'>The borg must choose a module before it can be upgraded!</span>")
else if(U.locked)
@@ -752,6 +752,21 @@ var/list/robot_verbs_default = list(
else
to_chat(user, "<span class='danger'>Upgrade error.</span>")
else if(istype(W, /obj/item/mmi_radio_upgrade))
if(!opened)
to_chat(user, "<span class='warning'>You must access the borg's internals!</span>")
return
else if(!mmi)
to_chat(user, "<span class='warning'>This cyborg does not have an MMI to augment!</span>")
return
else if(mmi.radio)
to_chat(user, "<span class='warning'>A radio upgrade is already installed in the MMI!</span>")
return
else if(user.drop_item())
to_chat(user, "<span class='notice'>You apply the upgrade to [src].</span>")
to_chat(src, "<span class='notice'>MMI radio capability installed.</span>")
mmi.install_radio()
qdel(W)
else
return ..()
@@ -1442,4 +1457,4 @@ var/list/robot_verbs_default = list(
return eye_protection
/mob/living/silicon/robot/check_ear_prot()
return ear_protection
return ear_protection
+15 -1
View File
@@ -59,10 +59,14 @@
return STATUS_CLOSE
//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI.
//Some atoms such as vehicles might have special limitations for how mobs inside them interact with NanoUI.
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
return user.shared_living_nano_distance(src_object)
//Some atoms such as vehicles might have special benefits for how mobs inside them interact with NanoUI.
/atom/proc/contents_nano_interact(var/src_object, var/mob/living/user)
return STATUS_CLOSE // No help at all by default
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
if(!(src_object in view(4, src))) // If the src object is not in visable, disable updates
return STATUS_CLOSE
@@ -84,6 +88,16 @@
if(STATUS_INTERACTIVE)
return STATUS_UPDATE
/mob/living/carbon/brain/default_can_use_topic(var/src_object)
. = shared_nano_interaction(src_object)
if(. <= STATUS_DISABLED)
return
// Maybe add a handler here to call an "interaction state" thing on the MMI,
// later
if(loc)
. = max(., loc.contents_nano_interact(src_object, src)) // This is an "augment" on interaction
. = min(., loc.contents_nano_distance(src_object, src)) // This is a "limit" on interaction
/mob/living/carbon/human/default_can_use_topic(var/src_object)
. = shared_nano_interaction(src_object)
if(. != STATUS_CLOSE)
@@ -114,15 +114,15 @@
build_path = /obj/item/mmi/posibrain
category = list("Misc","Medical")
/datum/design/mmi_radio
name = "Radio-Enabled Man-Machine Interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio."
id = "mmi_radio"
/datum/design/mmi_radio_upgrade
name = "Man-Machine Interface Radio Upgrade"
desc = "Enables radio capability on MMIs when either installed directly on the MMI, or through a cyborg's chassis."
id = "mmi_radio_upgrade"
req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 2)
build_type = PROTOLATHE | MECHFAB
materials = list(MAT_METAL = 1200, MAT_GLASS = 500)
construction_time = 75
build_path = /obj/item/mmi/radio_enabled
materials = list(MAT_METAL = 200)
construction_time = 50
build_path = /obj/item/mmi_radio_upgrade
category = list("Misc","Medical")
/datum/design/nanopaste