mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-14 04:02:31 +00:00
Merge pull request #6789 from mwerezak/binary-talk
Allows properly keyed radios to broadcast in robot talk and/or hivemind + some cleanup
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
icon = 'icons/obj/radio.dmi'
|
icon = 'icons/obj/radio.dmi'
|
||||||
icon_state = "cypherkey"
|
icon_state = "cypherkey"
|
||||||
item_state = ""
|
item_state = ""
|
||||||
|
w_class = 1
|
||||||
var/translate_binary = 0
|
var/translate_binary = 0
|
||||||
var/translate_hive = 0
|
var/translate_hive = 0
|
||||||
var/syndie = 0
|
var/syndie = 0
|
||||||
|
|||||||
@@ -19,6 +19,18 @@
|
|||||||
keyslot1 = new /obj/item/device/encryptionkey/
|
keyslot1 = new /obj/item/device/encryptionkey/
|
||||||
recalculateChannels()
|
recalculateChannels()
|
||||||
|
|
||||||
|
/obj/item/device/radio/headset/handle_message_mode(mob/living/M as mob, message, channel)
|
||||||
|
if (channel == "special")
|
||||||
|
if (translate_binary)
|
||||||
|
var/datum/language/binary = all_languages["Robot Talk"]
|
||||||
|
binary.broadcast(M, message)
|
||||||
|
if (translate_hive)
|
||||||
|
var/datum/language/hivemind = all_languages["Hivemind"]
|
||||||
|
hivemind.broadcast(M, message)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return ..()
|
||||||
|
|
||||||
/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0)
|
/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0)
|
||||||
if (aiOverride)
|
if (aiOverride)
|
||||||
return ..(freq, level)
|
return ..(freq, level)
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
|
||||||
// 0 = old radios
|
|
||||||
// 1 = new radios (subspace technology)
|
|
||||||
|
|
||||||
|
|
||||||
/obj/item/device/radio
|
/obj/item/device/radio
|
||||||
@@ -219,6 +216,23 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
|||||||
del(A)
|
del(A)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
// Interprets the message mode when talking into a radio, possibly returning a connection datum
|
||||||
|
/obj/item/device/radio/proc/handle_message_mode(mob/living/M as mob, message, message_mode)
|
||||||
|
// If a channel isn't specified, send to common.
|
||||||
|
if(!message_mode || message_mode == "headset")
|
||||||
|
return radio_connection
|
||||||
|
|
||||||
|
// Otherwise, if a channel is specified, look for it.
|
||||||
|
if(channels)
|
||||||
|
if (message_mode == "department") // Department radio shortcut
|
||||||
|
message_mode = channels[1]
|
||||||
|
|
||||||
|
if (channels[message_mode]) // only broadcast if the channel is set on
|
||||||
|
return secure_radio_connections[message_mode]
|
||||||
|
|
||||||
|
// If we were to send to a channel we don't have, drop it.
|
||||||
|
return null
|
||||||
|
|
||||||
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
|
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
|
||||||
if(!on) return // the device has to be on
|
if(!on) return // the device has to be on
|
||||||
// Fix for permacell radios, but kinda eh about actually fixing them.
|
// Fix for permacell radios, but kinda eh about actually fixing them.
|
||||||
@@ -231,8 +245,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
|||||||
|
|
||||||
M.last_target_click = world.time
|
M.last_target_click = world.time
|
||||||
|
|
||||||
if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl
|
|
||||||
|
|
||||||
/* Quick introduction:
|
/* Quick introduction:
|
||||||
This new radio system uses a very robust FTL signaling technology unoriginally
|
This new radio system uses a very robust FTL signaling technology unoriginally
|
||||||
dubbed "subspace" which is somewhat similar to 'blue-space' but can't
|
dubbed "subspace" which is somewhat similar to 'blue-space' but can't
|
||||||
@@ -245,22 +257,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//#### Grab the connection datum ####//
|
//#### Grab the connection datum ####//
|
||||||
var/datum/radio_frequency/connection = null
|
var/datum/radio_frequency/connection = handle_message_mode(M, message, channel)
|
||||||
if(channel == "headset")
|
|
||||||
channel = null
|
|
||||||
if(channel) // If a channel is specified, look for it.
|
|
||||||
if(channels && channels.len > 0)
|
|
||||||
if (channel == "department")
|
|
||||||
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
|
|
||||||
channel = channels[1]
|
|
||||||
connection = secure_radio_connections[channel]
|
|
||||||
if (!channels[channel]) // if the channel is turned off, don't broadcast
|
|
||||||
return
|
|
||||||
else
|
|
||||||
// If we were to send to a channel we don't have, drop it.
|
|
||||||
else // If a channel isn't specified, send to common.
|
|
||||||
connection = radio_connection
|
|
||||||
channel = null
|
|
||||||
if (!istype(connection))
|
if (!istype(connection))
|
||||||
return
|
return
|
||||||
if (!connection)
|
if (!connection)
|
||||||
@@ -424,7 +421,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
|||||||
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level.
|
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet in our level.
|
||||||
// Send a mundane broadcast with limited targets:
|
// Send a mundane broadcast with limited targets:
|
||||||
|
|
||||||
//THIS IS TEMPORARY.
|
//THIS IS TEMPORARY. YEAH RIGHT
|
||||||
if(!connection) return //~Carn
|
if(!connection) return //~Carn
|
||||||
|
|
||||||
Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
|
Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
|
||||||
@@ -432,155 +429,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
|
|||||||
filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
|
filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
else // OLD RADIO SYSTEMS: By Goons?
|
|
||||||
|
|
||||||
var/datum/radio_frequency/connection = null
|
|
||||||
if(channel && channels && channels.len > 0)
|
|
||||||
if (channel == "department")
|
|
||||||
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
|
|
||||||
channel = channels[1]
|
|
||||||
connection = secure_radio_connections[channel]
|
|
||||||
else
|
|
||||||
connection = radio_connection
|
|
||||||
channel = null
|
|
||||||
if (!istype(connection))
|
|
||||||
return
|
|
||||||
var/display_freq = connection.frequency
|
|
||||||
|
|
||||||
//world << "DEBUG: used channel=\"[channel]\" frequency= \"[display_freq]\" connection.devices.len = [connection.devices.len]"
|
|
||||||
|
|
||||||
var/eqjobname
|
|
||||||
|
|
||||||
if (ishuman(M))
|
|
||||||
eqjobname = M:get_assignment()
|
|
||||||
else if (iscarbon(M))
|
|
||||||
eqjobname = "No id" //only humans can wear ID
|
|
||||||
else if (isAI(M))
|
|
||||||
eqjobname = "AI"
|
|
||||||
else if (isrobot(M))
|
|
||||||
eqjobname = "Cyborg"//Androids don't really describe these too well, in my opinion.
|
|
||||||
else if (istype(M, /mob/living/silicon/pai))
|
|
||||||
eqjobname = "Personal AI"
|
|
||||||
else
|
|
||||||
eqjobname = "Unknown"
|
|
||||||
|
|
||||||
if (!(wires & WIRE_TRANSMIT))
|
|
||||||
return
|
|
||||||
|
|
||||||
var/list/receive = list()
|
|
||||||
|
|
||||||
//for (var/obj/item/device/radio/R in radio_connection.devices)
|
|
||||||
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"]) // Modified for security headset code -- TLE
|
|
||||||
//if(R.accept_rad(src, message))
|
|
||||||
receive |= R.send_hear(display_freq, 0)
|
|
||||||
|
|
||||||
//world << "DEBUG: receive.len=[receive.len]"
|
|
||||||
var/list/heard_masked = list() // masked name or no real name
|
|
||||||
var/list/heard_normal = list() // normal message
|
|
||||||
var/list/heard_voice = list() // voice message
|
|
||||||
var/list/heard_garbled = list() // garbled message
|
|
||||||
|
|
||||||
for (var/mob/R in receive)
|
|
||||||
if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
|
|
||||||
continue
|
|
||||||
if (R.say_understands(M))
|
|
||||||
if (ishuman(M) && M.GetVoice() != M.real_name)
|
|
||||||
heard_masked += R
|
|
||||||
else
|
|
||||||
heard_normal += R
|
|
||||||
else
|
|
||||||
heard_voice += R
|
|
||||||
|
|
||||||
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled))
|
|
||||||
var/part_a = "<span class='radio'><span class='name'>"
|
|
||||||
//var/part_b = "</span><b> \icon[src]\[[format_frequency(frequency)]\]</b> <span class='message'>"
|
|
||||||
var/freq_text= get_frequency_name(display_freq)
|
|
||||||
|
|
||||||
var/part_b = "</span><b> \icon[src]\[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
|
|
||||||
var/part_c = "</span></span>"
|
|
||||||
|
|
||||||
if (display_freq in ANTAG_FREQS)
|
|
||||||
part_a = "<span class='syndradio'><span class='name'>"
|
|
||||||
else if (display_freq==COMM_FREQ)
|
|
||||||
part_a = "<span class='comradio'><span class='name'>"
|
|
||||||
else if (display_freq in DEPT_FREQS)
|
|
||||||
part_a = "<span class='deptradio'><span class='name'>"
|
|
||||||
|
|
||||||
var/quotedmsg = M.say_quote(message)
|
|
||||||
|
|
||||||
//This following recording is intended for research and feedback in the use of department radio channels.
|
|
||||||
|
|
||||||
var/part_blackbox_b = "</span><b> \[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
|
|
||||||
var/blackbox_msg = "[part_a][M.name][part_blackbox_b][quotedmsg][part_c]"
|
|
||||||
//var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]"
|
|
||||||
if(istype(blackbox))
|
|
||||||
//BR.messages_admin += blackbox_admin_msg
|
|
||||||
switch(display_freq)
|
|
||||||
if(PUB_FREQ)
|
|
||||||
blackbox.msg_common += blackbox_msg
|
|
||||||
if(SCI_FREQ)
|
|
||||||
blackbox.msg_science += blackbox_msg
|
|
||||||
if(COMM_FREQ)
|
|
||||||
blackbox.msg_command += blackbox_msg
|
|
||||||
if(MED_FREQ)
|
|
||||||
blackbox.msg_medical += blackbox_msg
|
|
||||||
if(ENG_FREQ)
|
|
||||||
blackbox.msg_engineering += blackbox_msg
|
|
||||||
if(SEC_FREQ)
|
|
||||||
blackbox.msg_security += blackbox_msg
|
|
||||||
if(DTH_FREQ)
|
|
||||||
blackbox.msg_deathsquad += blackbox_msg
|
|
||||||
if(SYND_FREQ)
|
|
||||||
blackbox.msg_syndicate += blackbox_msg
|
|
||||||
if(SUP_FREQ)
|
|
||||||
blackbox.msg_cargo += blackbox_msg
|
|
||||||
else
|
|
||||||
blackbox.messages += blackbox_msg
|
|
||||||
|
|
||||||
//End of research and feedback code.
|
|
||||||
|
|
||||||
if (length(heard_masked))
|
|
||||||
var/N = M.name
|
|
||||||
var/J = eqjobname
|
|
||||||
if(ishuman(M) && M.GetVoice() != M.real_name)
|
|
||||||
N = M.GetVoice()
|
|
||||||
J = "Unknown"
|
|
||||||
var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
|
|
||||||
for (var/mob/R in heard_masked)
|
|
||||||
if(istype(R, /mob/living/silicon/ai))
|
|
||||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[N] ([J]) </a>[part_b][quotedmsg][part_c]", 2)
|
|
||||||
else
|
|
||||||
R.show_message(rendered, 2)
|
|
||||||
|
|
||||||
if (length(heard_normal))
|
|
||||||
var/rendered = "[part_a][M.real_name][part_b][quotedmsg][part_c]"
|
|
||||||
|
|
||||||
for (var/mob/R in heard_normal)
|
|
||||||
if(istype(R, /mob/living/silicon/ai))
|
|
||||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.real_name] ([eqjobname]) </a>[part_b][quotedmsg][part_c]", 2)
|
|
||||||
else
|
|
||||||
R.show_message(rendered, 2)
|
|
||||||
|
|
||||||
if (length(heard_voice))
|
|
||||||
var/rendered = "[part_a][M.voice_name][part_b][pick(M.speak_emote)][part_c]"
|
|
||||||
|
|
||||||
for (var/mob/R in heard_voice)
|
|
||||||
if(istype(R, /mob/living/silicon/ai))
|
|
||||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name] ([eqjobname]) </a>[part_b][pick(M.speak_emote)][part_c]", 2)
|
|
||||||
else
|
|
||||||
R.show_message(rendered, 2)
|
|
||||||
|
|
||||||
if (length(heard_garbled))
|
|
||||||
quotedmsg = M.say_quote(stars(message))
|
|
||||||
var/rendered = "[part_a][M.voice_name][part_b][quotedmsg][part_c]"
|
|
||||||
|
|
||||||
for (var/mob/R in heard_voice)
|
|
||||||
if(istype(R, /mob/living/silicon/ai))
|
|
||||||
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name]</a>[part_b][quotedmsg][part_c]", 2)
|
|
||||||
else
|
|
||||||
R.show_message(rendered, 2)
|
|
||||||
|
|
||||||
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
|
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
|
||||||
|
|
||||||
if (broadcasting)
|
if (broadcasting)
|
||||||
|
|||||||
@@ -426,15 +426,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/client/proc/cmd_switch_radio()
|
|
||||||
set category = "Debug"
|
|
||||||
set name = "Switch Radio Mode"
|
|
||||||
set desc = "Toggle between normal radios and experimental radios. Have a coder present if you do this."
|
|
||||||
|
|
||||||
GLOBAL_RADIO_TYPE = !GLOBAL_RADIO_TYPE // toggle
|
|
||||||
log_admin("[key_name(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].")
|
|
||||||
message_admins("[key_name_admin(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].", 0)
|
|
||||||
feedback_add_details("admin_verb","SRM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
||||||
|
|
||||||
/client/proc/cmd_admin_areatest()
|
/client/proc/cmd_admin_areatest()
|
||||||
set category = "Mapping"
|
set category = "Mapping"
|
||||||
|
|||||||
@@ -115,7 +115,6 @@
|
|||||||
return
|
return
|
||||||
else
|
else
|
||||||
if(message_mode)
|
if(message_mode)
|
||||||
if(message_mode in (radiochannels | "department"))
|
|
||||||
if(l_ear && istype(l_ear,/obj/item/device/radio))
|
if(l_ear && istype(l_ear,/obj/item/device/radio))
|
||||||
l_ear.talk_into(src,message, message_mode, verb, speaking)
|
l_ear.talk_into(src,message, message_mode, verb, speaking)
|
||||||
used_radios += l_ear
|
used_radios += l_ear
|
||||||
@@ -129,7 +128,18 @@
|
|||||||
speech_sound = sound(pick(species.speech_sounds))
|
speech_sound = sound(pick(species.speech_sounds))
|
||||||
sound_vol = 50
|
sound_vol = 50
|
||||||
|
|
||||||
..(message, speaking, verb, alt_name, italics, message_range, used_radios, speech_sound, sound_vol) //ohgod we should really be passing a datum here.
|
//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("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "the radio."]</span>")
|
||||||
|
if (speech_sound)
|
||||||
|
sound_vol *= 0.5
|
||||||
|
|
||||||
|
..(message, speaking, verb, alt_name, italics, message_range, speech_sound, sound_vol) //ohgod we should really be passing a datum here.
|
||||||
|
|
||||||
/mob/living/carbon/human/proc/forcesay(list/append)
|
/mob/living/carbon/human/proc/forcesay(list/append)
|
||||||
if(stat == CONSCIOUS)
|
if(stat == CONSCIOUS)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var/list/department_radio_keys = list(
|
|||||||
":l" = "left ear", "#l" = "left ear", ".l" = "left ear",
|
":l" = "left ear", "#l" = "left ear", ".l" = "left ear",
|
||||||
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
|
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
|
||||||
":h" = "department", "#h" = "department", ".h" = "department",
|
":h" = "department", "#h" = "department", ".h" = "department",
|
||||||
|
":0" = "special", "#0" = "special", ".0" = "special", //activate radio-specific special functions
|
||||||
":c" = "Command", "#c" = "Command", ".c" = "Command",
|
":c" = "Command", "#c" = "Command", ".c" = "Command",
|
||||||
":n" = "Science", "#n" = "Science", ".n" = "Science",
|
":n" = "Science", "#n" = "Science", ".n" = "Science",
|
||||||
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
|
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
|
||||||
@@ -59,7 +60,7 @@ var/list/department_radio_keys = list(
|
|||||||
if(!istype(dongle)) return
|
if(!istype(dongle)) return
|
||||||
if(dongle.translate_binary) return 1
|
if(dongle.translate_binary) return 1
|
||||||
|
|
||||||
/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)
|
/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/sound/speech_sound, var/sound_vol)
|
||||||
|
|
||||||
var/turf/T = get_turf(src)
|
var/turf/T = get_turf(src)
|
||||||
|
|
||||||
@@ -73,20 +74,6 @@ var/list/department_radio_keys = list(
|
|||||||
say_signlang(message, pick(speaking.signlang_verb), speaking)
|
say_signlang(message, pick(speaking.signlang_verb), speaking)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
//speaking into radios
|
|
||||||
if(used_radios.len)
|
|
||||||
italics = 1
|
|
||||||
message_range = 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("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "the radio."]</span>")
|
|
||||||
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
|
//make sure the air can transmit speech
|
||||||
var/datum/gas_mixture/environment = T.return_air()
|
var/datum/gas_mixture/environment = T.return_air()
|
||||||
if(environment)
|
if(environment)
|
||||||
|
|||||||
@@ -130,7 +130,7 @@
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
else
|
else
|
||||||
if(message_mode && message_mode in radiochannels)
|
if(message_mode)
|
||||||
switch(bot_type)
|
switch(bot_type)
|
||||||
if(IS_AI)
|
if(IS_AI)
|
||||||
if (AI.aiRadio.disabledAi)
|
if (AI.aiRadio.disabledAi)
|
||||||
|
|||||||
Reference in New Issue
Block a user