mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 02:24:11 +01:00
Adds a radio MMI upgrade module, printable in the mech fab
Can be uninstalled with a screwdriver
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user