mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-26 05:27:39 +01:00
Headsets now generate a description of available radio channels based on the installed encryption key(s). Currently only updates on creation, not when changing encryption keys, to ensure that less than legal keys are not detected by a mere casual glance.
682 lines
22 KiB
Plaintext
682 lines
22 KiB
Plaintext
|
|
|
|
/obj/item/device/radio
|
|
icon = 'icons/obj/radio.dmi'
|
|
name = "station bounced radio"
|
|
suffix = "\[3\]"
|
|
icon_state = "walkietalkie"
|
|
item_state = "walkietalkie"
|
|
var/on = 1 // 0 for off
|
|
var/last_transmission
|
|
var/frequency = PUB_FREQ //common chat
|
|
var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies
|
|
var/canhear_range = 3 // the range which mobs can hear this radio from
|
|
var/obj/item/device/radio/patch_link = null
|
|
var/wires = WIRE_SIGNAL | WIRE_RECEIVE | WIRE_TRANSMIT
|
|
var/b_stat = 0
|
|
var/broadcasting = 0
|
|
var/listening = 1
|
|
var/freerange = 0 // 0 - Sanitize frequencies, 1 - Full range
|
|
var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
|
|
var/subspace_transmission = 0
|
|
var/syndie = 0//Holder to see if it's a syndicate encrpyed radio
|
|
var/maxf = 1499
|
|
// "Example" = FREQ_LISTENING|FREQ_BROADCASTING
|
|
flags = FPRINT | CONDUCT | TABLEPASS
|
|
slot_flags = SLOT_BELT
|
|
throw_speed = 2
|
|
throw_range = 9
|
|
w_class = 2
|
|
|
|
matter = list("glass" = 25,"metal" = 75)
|
|
|
|
var/const/WIRE_SIGNAL = 1 //sends a signal, like to set off a bomb or electrocute someone
|
|
var/const/WIRE_RECEIVE = 2
|
|
var/const/WIRE_TRANSMIT = 4
|
|
var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio
|
|
var/const/FREQ_LISTENING = 1
|
|
//FREQ_BROADCASTING = 2
|
|
|
|
/obj/item/device/radio
|
|
var/datum/radio_frequency/radio_connection
|
|
var/list/datum/radio_frequency/secure_radio_connections = new
|
|
|
|
proc/set_frequency(new_frequency)
|
|
radio_controller.remove_object(src, frequency)
|
|
frequency = new_frequency
|
|
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
|
|
|
|
/obj/item/device/radio/New()
|
|
..()
|
|
if(radio_controller)
|
|
initialize()
|
|
|
|
|
|
/obj/item/device/radio/initialize()
|
|
|
|
if(freerange)
|
|
if(frequency < 1200 || frequency > 1600)
|
|
frequency = sanitize_frequency(frequency, maxf)
|
|
// The max freq is higher than a regular headset to decrease the chance of people listening in, if you use the higher channels.
|
|
else if (frequency < 1441 || frequency > maxf)
|
|
//world.log << "[src] ([type]) has a frequency of [frequency], sanitizing."
|
|
frequency = sanitize_frequency(frequency, maxf)
|
|
|
|
set_frequency(frequency)
|
|
|
|
for (var/ch_name in channels)
|
|
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
|
|
|
|
|
/obj/item/device/radio/attack_self(mob/user as mob)
|
|
user.set_machine(src)
|
|
interact(user)
|
|
|
|
/obj/item/device/radio/interact(mob/user as mob)
|
|
if(!on)
|
|
return
|
|
|
|
if(active_uplink_check(user))
|
|
return
|
|
|
|
var/dat = "<html><head><title>[src]</title></head><body><TT>"
|
|
|
|
if(!istype(src, /obj/item/device/radio/headset)) //Headsets dont get a mic button
|
|
dat += "Microphone: [broadcasting ? "<A href='byond://?src=\ref[src];talk=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];talk=1'>Disengaged</A>"]<BR>"
|
|
|
|
dat += {"
|
|
Speaker: [listening ? "<A href='byond://?src=\ref[src];listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];listen=1'>Disengaged</A>"]<BR>
|
|
Frequency:
|
|
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
|
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
|
[format_frequency(frequency)]
|
|
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
|
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
|
"}
|
|
|
|
for (var/ch_name in channels)
|
|
dat+=text_sec_channel(ch_name, channels[ch_name])
|
|
dat+={"[text_wires()]</TT></body></html>"}
|
|
user << browse(dat, "window=radio")
|
|
onclose(user, "radio")
|
|
return
|
|
|
|
/obj/item/device/radio/proc/text_wires()
|
|
if (!b_stat)
|
|
return ""
|
|
return {"
|
|
<hr>
|
|
Green Wire: <A href='byond://?src=\ref[src];wires=4'>[(wires & 4) ? "Cut" : "Mend"] Wire</A><BR>
|
|
Red Wire: <A href='byond://?src=\ref[src];wires=2'>[(wires & 2) ? "Cut" : "Mend"] Wire</A><BR>
|
|
Blue Wire: <A href='byond://?src=\ref[src];wires=1'>[(wires & 1) ? "Cut" : "Mend"] Wire</A><BR>
|
|
"}
|
|
|
|
|
|
/obj/item/device/radio/proc/text_sec_channel(var/chan_name, var/chan_stat)
|
|
var/list = !!(chan_stat&FREQ_LISTENING)!=0
|
|
return {"
|
|
<B>[chan_name]</B><br>
|
|
Speaker: <A href='byond://?src=\ref[src];ch_name=[chan_name];listen=[!list]'>[list ? "Engaged" : "Disengaged"]</A><BR>
|
|
"}
|
|
|
|
/obj/item/device/radio/Topic(href, href_list)
|
|
//..()
|
|
if (usr.stat || !on)
|
|
return
|
|
|
|
if (!(issilicon(usr) || (usr.contents.Find(src) || ( in_range(src, usr) && istype(loc, /turf) ))))
|
|
usr << browse(null, "window=radio")
|
|
return
|
|
usr.set_machine(src)
|
|
if (href_list["track"])
|
|
var/mob/target = locate(href_list["track"])
|
|
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
|
if(A && target)
|
|
A.ai_actual_track(target)
|
|
return
|
|
|
|
else if (href_list["faketrack"])
|
|
var/mob/target = locate(href_list["track"])
|
|
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
|
if(A && target)
|
|
|
|
A:cameraFollow = target
|
|
A << text("Now tracking [] on camera.", target.name)
|
|
if (usr.machine == null)
|
|
usr.machine = usr
|
|
|
|
while (usr:cameraFollow == target)
|
|
usr << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
|
|
sleep(40)
|
|
continue
|
|
|
|
return
|
|
|
|
else if (href_list["freq"])
|
|
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
|
if (!freerange || (frequency < 1200 || frequency > 1600))
|
|
new_frequency = sanitize_frequency(new_frequency, maxf)
|
|
set_frequency(new_frequency)
|
|
if(hidden_uplink)
|
|
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
|
|
usr << browse(null, "window=radio")
|
|
return
|
|
|
|
else if (href_list["talk"])
|
|
broadcasting = text2num(href_list["talk"])
|
|
else if (href_list["listen"])
|
|
var/chan_name = href_list["ch_name"]
|
|
if (!chan_name)
|
|
listening = text2num(href_list["listen"])
|
|
else
|
|
if (channels[chan_name] & FREQ_LISTENING)
|
|
channels[chan_name] &= ~FREQ_LISTENING
|
|
else
|
|
channels[chan_name] |= FREQ_LISTENING
|
|
else if (href_list["wires"])
|
|
var/t1 = text2num(href_list["wires"])
|
|
if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
|
|
return
|
|
if (wires & t1)
|
|
wires &= ~t1
|
|
else
|
|
wires |= t1
|
|
if (!( master ))
|
|
if (istype(loc, /mob))
|
|
interact(loc)
|
|
else
|
|
updateDialog()
|
|
else
|
|
if (istype(master.loc, /mob))
|
|
interact(master.loc)
|
|
else
|
|
updateDialog()
|
|
add_fingerprint(usr)
|
|
|
|
/obj/item/device/radio/proc/autosay(var/message, var/from, var/channel) //BS12 EDIT
|
|
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
|
|
if (!connection)
|
|
return
|
|
|
|
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1)
|
|
Broadcast_Message(connection, A,
|
|
0, "*garbled automated announcement*", src,
|
|
message, from, "Automated Announcement", from, "synthesized voice",
|
|
4, 0, list(1), PUB_FREQ)
|
|
del(A)
|
|
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)
|
|
if(!on) return 0 // the device has to be on
|
|
// Fix for permacell radios, but kinda eh about actually fixing them.
|
|
if(!M || !message) return 0
|
|
|
|
// Uncommenting this. To the above comment:
|
|
// The permacell radios aren't suppose to be able to transmit, this isn't a bug and this "fix" is just making radio wires useless. -Giacom
|
|
if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
|
|
return 0
|
|
|
|
M.last_target_click = world.time
|
|
|
|
/* Quick introduction:
|
|
This new radio system uses a very robust FTL signaling technology unoriginally
|
|
dubbed "subspace" which is somewhat similar to 'blue-space' but can't
|
|
actually transmit large mass. Headsets are the only radio devices capable
|
|
of sending subspace transmissions to the Communications Satellite.
|
|
|
|
A headset sends a signal to a subspace listener/reciever elsewhere in space,
|
|
the signal gets processed and logged, and an audible transmission gets sent
|
|
to each individual headset.
|
|
*/
|
|
|
|
//#### Grab the connection datum ####//
|
|
var/datum/radio_frequency/connection = handle_message_mode(M, message, channel)
|
|
if (!istype(connection))
|
|
return 0
|
|
if (!connection)
|
|
return 0
|
|
|
|
var/turf/position = get_turf(src)
|
|
|
|
//#### Tagging the signal with all appropriate identity values ####//
|
|
|
|
// ||-- The mob's name identity --||
|
|
var/displayname = M.name // grab the display name (name you get when you hover over someone's icon)
|
|
var/real_name = M.real_name // mob's real name
|
|
var/mobkey = "none" // player key associated with mob
|
|
var/voicemask = 0 // the speaker is wearing a voice mask
|
|
if(M.client)
|
|
mobkey = M.key // assign the mob's key
|
|
|
|
|
|
var/jobname // the mob's "job"
|
|
|
|
// --- Human: use their actual job ---
|
|
if (ishuman(M))
|
|
var/mob/living/carbon/human/H = M
|
|
jobname = H.get_assignment()
|
|
|
|
// --- Carbon Nonhuman ---
|
|
else if (iscarbon(M)) // Nonhuman carbon mob
|
|
jobname = "No id"
|
|
|
|
// --- AI ---
|
|
else if (isAI(M))
|
|
jobname = "AI"
|
|
|
|
// --- Cyborg ---
|
|
else if (isrobot(M))
|
|
jobname = "Cyborg"
|
|
|
|
// --- Personal AI (pAI) ---
|
|
else if (istype(M, /mob/living/silicon/pai))
|
|
jobname = "Personal AI"
|
|
|
|
// --- Unidentifiable mob ---
|
|
else
|
|
jobname = "Unknown"
|
|
|
|
|
|
// --- Modifications to the mob's identity ---
|
|
|
|
// The mob is disguising their identity:
|
|
if (ishuman(M) && M.GetVoice() != real_name)
|
|
displayname = M.GetVoice()
|
|
jobname = "Unknown"
|
|
voicemask = 1
|
|
|
|
|
|
|
|
/* ###### Radio headsets can only broadcast through subspace ###### */
|
|
|
|
if(subspace_transmission)
|
|
// First, we want to generate a new radio signal
|
|
var/datum/signal/signal = new
|
|
signal.transmission_method = 2 // 2 would be a subspace transmission.
|
|
// transmission_method could probably be enumerated through #define. Would be neater.
|
|
|
|
// --- Finally, tag the actual signal with the appropriate values ---
|
|
signal.data = list(
|
|
// Identity-associated tags:
|
|
"mob" = M, // store a reference to the mob
|
|
"mobtype" = M.type, // the mob's type
|
|
"realname" = real_name, // the mob's real name
|
|
"name" = displayname, // the mob's display name
|
|
"job" = jobname, // the mob's job
|
|
"key" = mobkey, // the mob's key
|
|
"vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood
|
|
"vname" = M.voice_name, // the name to display if the voice wasn't understood
|
|
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
|
|
|
|
// We store things that would otherwise be kept in the actual mob
|
|
// so that they can be logged even AFTER the mob is deleted or something
|
|
|
|
// Other tags:
|
|
"compression" = rand(45,50), // compressed radio signal
|
|
"message" = message, // the actual sent message
|
|
"connection" = connection, // the radio connection to use
|
|
"radio" = src, // stores the radio used for transmission
|
|
"slow" = 0, // how much to sleep() before broadcasting - simulates net lag
|
|
"traffic" = 0, // dictates the total traffic sum that the signal went through
|
|
"type" = 0, // determines what type of radio input it is: normal broadcast
|
|
"server" = null, // the last server to log this signal
|
|
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
|
|
"level" = position.z, // The source's z level
|
|
"language" = speaking,
|
|
"verb" = verb
|
|
)
|
|
signal.frequency = connection.frequency // Quick frequency set
|
|
|
|
//#### Sending the signal to all subspace receivers ####//
|
|
|
|
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
|
|
R.receive_signal(signal)
|
|
|
|
// Allinone can act as receivers.
|
|
for(var/obj/machinery/telecomms/allinone/R in telecomms_list)
|
|
R.receive_signal(signal)
|
|
|
|
// Receiving code can be located in Telecommunications.dm
|
|
return signal.data["done"] && position.z in signal.data["level"]
|
|
|
|
|
|
/* ###### Intercoms and station-bounced radios ###### */
|
|
|
|
var/filter_type = 2
|
|
|
|
/* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */
|
|
if(istype(src, /obj/item/device/radio/intercom))
|
|
filter_type = 1
|
|
|
|
|
|
var/datum/signal/signal = new
|
|
signal.transmission_method = 2
|
|
|
|
|
|
/* --- Try to send a normal subspace broadcast first */
|
|
|
|
signal.data = list(
|
|
|
|
"mob" = M, // store a reference to the mob
|
|
"mobtype" = M.type, // the mob's type
|
|
"realname" = real_name, // the mob's real name
|
|
"name" = displayname, // the mob's display name
|
|
"job" = jobname, // the mob's job
|
|
"key" = mobkey, // the mob's key
|
|
"vmessage" = pick(M.speak_emote), // the message to display if the voice wasn't understood
|
|
"vname" = M.voice_name, // the name to display if the voice wasn't understood
|
|
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
|
|
|
|
"compression" = 0, // uncompressed radio signal
|
|
"message" = message, // the actual sent message
|
|
"connection" = connection, // the radio connection to use
|
|
"radio" = src, // stores the radio used for transmission
|
|
"slow" = 0,
|
|
"traffic" = 0,
|
|
"type" = 0,
|
|
"server" = null,
|
|
"reject" = 0,
|
|
"level" = position.z,
|
|
"language" = speaking,
|
|
"verb" = verb
|
|
)
|
|
signal.frequency = connection.frequency // Quick frequency set
|
|
|
|
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
|
|
R.receive_signal(signal)
|
|
|
|
|
|
sleep(rand(10,25)) // wait a little...
|
|
|
|
if(signal.data["done"] && position.z in signal.data["level"])
|
|
// we're done here.
|
|
return 1
|
|
|
|
// 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:
|
|
|
|
//THIS IS TEMPORARY. YEAH RIGHT
|
|
if(!connection) return 0 //~Carn
|
|
|
|
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
|
|
src, message, displayname, jobname, real_name, M.voice_name,
|
|
filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
|
|
|
|
|
|
/obj/item/device/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
|
|
|
|
if (broadcasting)
|
|
if(get_dist(src, M) <= canhear_range)
|
|
talk_into(M, msg,null,verb,speaking)
|
|
|
|
|
|
/*
|
|
/obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message)
|
|
|
|
if ((R.frequency == frequency && message))
|
|
return 1
|
|
else if
|
|
|
|
else
|
|
return null
|
|
return
|
|
*/
|
|
|
|
|
|
/obj/item/device/radio/proc/receive_range(freq, level)
|
|
// check if this radio can receive on the given frequency, and if so,
|
|
// what the range is in which mobs will hear the radio
|
|
// returns: -1 if can't receive, range otherwise
|
|
|
|
if (!(wires & WIRE_RECEIVE))
|
|
return -1
|
|
if(!listening)
|
|
return -1
|
|
if(!(0 in level))
|
|
var/turf/position = get_turf(src)
|
|
if(!position || !(position.z in level))
|
|
return -1
|
|
if(freq in ANTAG_FREQS)
|
|
if(!(src.syndie))//Checks to see if it's allowed on that frequency, based on the encryption keys
|
|
return -1
|
|
if (!on)
|
|
return -1
|
|
if (!freq) //recieved on main frequency
|
|
if (!listening)
|
|
return -1
|
|
else
|
|
var/accept = (freq==frequency && listening)
|
|
if (!accept)
|
|
for (var/ch_name in channels)
|
|
var/datum/radio_frequency/RF = secure_radio_connections[ch_name]
|
|
if (RF.frequency==freq && (channels[ch_name]&FREQ_LISTENING))
|
|
accept = 1
|
|
break
|
|
if (!accept)
|
|
return -1
|
|
return canhear_range
|
|
|
|
/obj/item/device/radio/proc/send_hear(freq, level)
|
|
|
|
var/range = receive_range(freq, level)
|
|
if(range > -1)
|
|
return get_mobs_in_view(canhear_range, src)
|
|
|
|
|
|
/obj/item/device/radio/examine(mob/user)
|
|
. = ..()
|
|
if ((in_range(src, user) || loc == user))
|
|
if (b_stat)
|
|
user.show_message("\blue \the [src] can be attached and modified!")
|
|
else
|
|
user.show_message("\blue \the [src] can not be modified or attached!")
|
|
return
|
|
|
|
/obj/item/device/radio/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
|
..()
|
|
user.set_machine(src)
|
|
if (!( istype(W, /obj/item/weapon/screwdriver) ))
|
|
return
|
|
b_stat = !( b_stat )
|
|
if(!istype(src, /obj/item/device/radio/beacon))
|
|
if (b_stat)
|
|
user.show_message("\blue The radio can now be attached and modified!")
|
|
else
|
|
user.show_message("\blue The radio can no longer be modified or attached!")
|
|
updateDialog()
|
|
//Foreach goto(83)
|
|
add_fingerprint(user)
|
|
return
|
|
else return
|
|
|
|
/obj/item/device/radio/emp_act(severity)
|
|
broadcasting = 0
|
|
listening = 0
|
|
for (var/ch_name in channels)
|
|
channels[ch_name] = 0
|
|
..()
|
|
|
|
///////////////////////////////
|
|
//////////Borg Radios//////////
|
|
///////////////////////////////
|
|
//Giving borgs their own radio to have some more room to work with -Sieve
|
|
|
|
/obj/item/device/radio/borg
|
|
var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks
|
|
var/obj/item/device/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
|
|
var/shut_up = 0
|
|
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
|
|
icon_state = "radio"
|
|
canhear_range = 3
|
|
|
|
/obj/item/device/radio/borg/talk_into()
|
|
. = ..()
|
|
if (isrobot(src.loc))
|
|
var/mob/living/silicon/robot/R = src.loc
|
|
var/datum/robot_component/C = R.components["radio"]
|
|
R.cell_use_power(C.active_usage)
|
|
|
|
/obj/item/device/radio/borg/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
|
// ..()
|
|
user.set_machine(src)
|
|
if (!( istype(W, /obj/item/weapon/screwdriver) || (istype(W, /obj/item/device/encryptionkey/ ))))
|
|
return
|
|
|
|
if(istype(W, /obj/item/weapon/screwdriver))
|
|
if(keyslot)
|
|
|
|
|
|
for(var/ch_name in channels)
|
|
radio_controller.remove_object(src, radiochannels[ch_name])
|
|
secure_radio_connections[ch_name] = null
|
|
|
|
|
|
if(keyslot)
|
|
var/turf/T = get_turf(user)
|
|
if(T)
|
|
keyslot.loc = T
|
|
keyslot = null
|
|
|
|
recalculateChannels()
|
|
user << "You pop out the encryption key in the radio!"
|
|
|
|
else
|
|
user << "This radio doesn't have any encryption keys!"
|
|
|
|
if(istype(W, /obj/item/device/encryptionkey/))
|
|
if(keyslot)
|
|
user << "The radio can't hold another key!"
|
|
return
|
|
|
|
if(!keyslot)
|
|
user.drop_item()
|
|
W.loc = src
|
|
keyslot = W
|
|
|
|
recalculateChannels()
|
|
|
|
return
|
|
|
|
/obj/item/device/radio/borg/proc/recalculateChannels()
|
|
src.channels = list()
|
|
src.syndie = 0
|
|
|
|
var/mob/living/silicon/robot/D = src.loc
|
|
if(D.module)
|
|
for(var/ch_name in D.module.channels)
|
|
if(ch_name in src.channels)
|
|
continue
|
|
src.channels += ch_name
|
|
src.channels[ch_name] += D.module.channels[ch_name]
|
|
if(keyslot)
|
|
for(var/ch_name in keyslot.channels)
|
|
if(ch_name in src.channels)
|
|
continue
|
|
src.channels += ch_name
|
|
src.channels[ch_name] += keyslot.channels[ch_name]
|
|
|
|
if(keyslot.syndie)
|
|
src.syndie = 1
|
|
|
|
|
|
for (var/ch_name in src.channels)
|
|
if(!radio_controller)
|
|
sleep(30) // Waiting for the radio_controller to be created.
|
|
if(!radio_controller)
|
|
src.name = "broken radio"
|
|
return
|
|
|
|
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
|
|
|
return
|
|
|
|
/obj/item/device/radio/borg/Topic(href, href_list)
|
|
if(usr.stat || !on)
|
|
return
|
|
if (href_list["mode"])
|
|
if(subspace_transmission != 1)
|
|
subspace_transmission = 1
|
|
usr << "Subspace Transmission is disabled"
|
|
else
|
|
subspace_transmission = 0
|
|
usr << "Subspace Transmission is enabled"
|
|
if(subspace_transmission == 1)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
|
|
channels = list()
|
|
else
|
|
recalculateChannels()
|
|
if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
|
|
shut_up = !shut_up
|
|
if(shut_up)
|
|
canhear_range = 0
|
|
else
|
|
canhear_range = 3
|
|
|
|
..()
|
|
|
|
/obj/item/device/radio/borg/interact(mob/user as mob)
|
|
if(!on)
|
|
return
|
|
|
|
var/dat = "<html><head><title>[src]</title></head><body><TT>"
|
|
dat += {"
|
|
Speaker: [listening ? "<A href='byond://?src=\ref[src];listen=0'>Engaged</A>" : "<A href='byond://?src=\ref[src];listen=1'>Disengaged</A>"]<BR>
|
|
Frequency:
|
|
<A href='byond://?src=\ref[src];freq=-10'>-</A>
|
|
<A href='byond://?src=\ref[src];freq=-2'>-</A>
|
|
[format_frequency(frequency)]
|
|
<A href='byond://?src=\ref[src];freq=2'>+</A>
|
|
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
|
|
<A href='byond://?src=\ref[src];mode=1'>Toggle Broadcast Mode</A><BR>
|
|
<A href='byond://?src=\ref[src];shutup=1'>Toggle Loudspeaker</A><BR>
|
|
"}
|
|
|
|
if(!subspace_transmission)//Don't even bother if subspace isn't turned on
|
|
for (var/ch_name in channels)
|
|
dat+=text_sec_channel(ch_name, channels[ch_name])
|
|
dat+={"[text_wires()]</TT></body></html>"}
|
|
user << browse(dat, "window=radio")
|
|
onclose(user, "radio")
|
|
return
|
|
|
|
|
|
/obj/item/device/radio/proc/config(op)
|
|
if(radio_controller)
|
|
for (var/ch_name in channels)
|
|
radio_controller.remove_object(src, radiochannels[ch_name])
|
|
secure_radio_connections = new
|
|
channels = op
|
|
if(radio_controller)
|
|
for (var/ch_name in op)
|
|
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
|
return
|
|
|
|
/obj/item/device/radio/off
|
|
listening = 0
|