diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 43daf35b32..204b94cc3d 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -71,6 +71,10 @@
dat += "
"
dat += {"[A.control_disabled ? "Enable" : "Disable"] Wireless Activity"}
dat += "
"
+ dat += "Subspace Transceiver is: [A.aiRadio.disabledAi ? "Disabled" : "Enabled"]"
+ dat += "
"
+ dat += {"[A.aiRadio.disabledAi ? "Enable" : "Disable"] Subspace Transceiver"}
+ dat += "
"
dat += {" Close"}
user << browse(dat, "window=aicard")
onclose(user, "aicard")
@@ -92,6 +96,12 @@
U.unset_machine()
return
+ if ("Radio")
+ for(var/mob/living/silicon/ai/A in src)
+ A.aiRadio.disabledAi = !A.aiRadio.disabledAi
+ A << "Your Subspace Transceiver has been: [A.aiRadio.disabledAi ? "disabled" : "enabled"]"
+ U << "You [A.aiRadio.disabledAi ? "Disable" : "Enable"] the AI's Subspace Transceiver"
+
if ("Wipe")
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
if(confirm == "Yes")
diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm
index d2d5417d6c..287e827249 100644
--- a/code/game/objects/items/devices/radio/encryptionkey.dm
+++ b/code/game/objects/items/devices/radio/encryptionkey.dm
@@ -74,6 +74,12 @@
icon_state = "cap_cypherkey"
channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0)
+/obj/item/device/encryptionkey/heads/ai_integrated
+ name = "AI Integrated Encryption Key"
+ desc = "Integrated encryption key"
+ icon_state = "cap_cypherkey"
+ channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1)
+
/obj/item/device/encryptionkey/heads/rd
name = "Research Director's Encryption Key"
desc = "An encyption key for a radio headset. Contains cypherkeys."
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index ed59e43989..ab376e4825 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -19,7 +19,9 @@
keyslot1 = new /obj/item/device/encryptionkey/
recalculateChannels()
-/obj/item/device/radio/headset/receive_range(freq, level)
+/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0)
+ if (aiOverride)
+ return ..(freq, level)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.l_ear == src || H.r_ear == src)
@@ -99,6 +101,20 @@
item_state = "headset"
keyslot2 = new /obj/item/device/encryptionkey/heads/captain
+/obj/item/device/radio/headset/heads/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway.
+ name = "AI Subspace Transceiver"
+ desc = "Integrated AI radio transceiver."
+ icon_state = "ai_radio"
+ item_state = "headset"
+ keyslot2 = new /obj/item/device/encryptionkey/heads/ai_integrated
+ var/myAi = null // Atlantis: Reference back to the AI which has this radio.
+ var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu.
+
+/obj/item/device/radio/headset/heads/ai_integrated/receive_range(freq, level)
+ if (disabledAi)
+ return -1 //Transciever Disabled.
+ return ..(freq, level, 1)
+
/obj/item/device/radio/headset/heads/rd
name = "Research Director's headset"
desc = "Headset of the researching God. To access the science channel, use :n. For command, use :c."
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index b439c0d475..2e81992826 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -84,28 +84,29 @@ var/list/department_radio_keys = list(
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list(), var/sound/speech_sound, var/sound_vol)
var/turf/T = get_turf(src)
-
+
//handle nonverbal and sign languages here
if (speaking)
if (speaking.flags & NONVERBAL)
if (prob(30))
src.custom_emote(1, "[pick(speaking.signlang_verb)].")
-
+
if (speaking.flags & SIGNLANG)
say_signlang(message, pick(speaking.signlang_verb), speaking)
return
-
+
//speaking into radios
if(used_radios.len)
italics = 1
message_range = 1
-
- for(var/mob/living/M in hearers(5, src))
- if(M != src)
- M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "the radio."]")
- if (speech_sound)
- src.playsound_local(get_turf(src), speech_sound, sound_vol * 0.5, 1)
-
+
+ if (!istype(src, /mob/living/silicon/ai)) // Atlantis: Prevents nearby people from hearing the AI when it talks using it's integrated radio.
+ for(var/mob/living/M in hearers(5, src))
+ if(M != src)
+ M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "the radio."]")
+ if (speech_sound)
+ src.playsound_local(get_turf(src), speech_sound, sound_vol * 0.5, 1)
+
speech_sound = null //so we don't play it twice.
//make sure the air can transmit speech
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index b34f7aa641..44da5d74af 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -30,6 +30,7 @@ var/list/ai_list = list()
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/item/device/pda/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
+ var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null
var/custom_sprite = 0 //For our custom sprites
//Hud stuff
@@ -87,12 +88,14 @@ var/list/ai_list = list()
aiPDA.name = name + " (" + aiPDA.ownjob + ")"
aiMulti = new(src)
+ aiRadio = new(src)
+ aiRadio.myAi = src
if (istype(loc, /turf))
verbs.Add(/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
/mob/living/silicon/ai/proc/ai_statuschange, /mob/living/silicon/ai/proc/ai_hologram_change, \
- /mob/living/silicon/ai/proc/toggle_camera_light)
+ /mob/living/silicon/ai/proc/toggle_camera_light, /mob/living/silicon/ai/proc/control_integrateed_radio)
//Languages
add_language("Sol Common", 0)
@@ -738,3 +741,12 @@ var/list/ai_list = list()
return
else
return ..()
+
+/mob/living/silicon/ai/proc/control_integrateed_radio()
+ set name = "Radio Settings"
+ set desc = "Allows you to change settings of your radio."
+ set category = "AI Commands"
+
+ src << "Accessing Subspace Transceiver control..."
+ if (src.aiRadio)
+ src.aiRadio.interact(src)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 0811a52cd8..67ca178e89 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -109,7 +109,11 @@
if("general")
switch(bot_type)
if(IS_AI)
- src << "Yeah, not yet, sorry"
+ if (AI.aiRadio.disabledAi)
+ src << "\red System Error - Transceiver Disabled"
+ else
+ log_say("[key_name(src)] : [message]")
+ AI.aiRadio.talk_into(src,message,null,verb,speaking)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,null,verb,speaking)
@@ -122,8 +126,11 @@
if(message_mode && message_mode in radiochannels)
switch(bot_type)
if(IS_AI)
- src << "You don't have this function yet, I'm working on it"
- return
+ if (AI.aiRadio.disabledAi)
+ src << "\red System Error - Transceiver Disabled"
+ else
+ log_say("[key_name(src)] : [message]")
+ AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
if(IS_ROBOT)
log_say("[key_name(src)] : [message]")
R.radio.talk_into(src,message,message_mode,verb,speaking)
diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi
index 9c4830d273..b0b250a18b 100644
Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ