mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-20 19:43:13 +01:00
I had a brief discussion about Goto statements, then on a whim checked to see if we had any. We had some Gotos that are legally old enough to apply for a learner's permit in my state. I was bored so I decided to put them out of their misery.
864 lines
26 KiB
Plaintext
864 lines
26 KiB
Plaintext
// Access check is of the type "req_one_access".
|
|
// These have been carefully selected to avoid allowing anyone with generic departmental access to see channels they should not.
|
|
var/global/list/default_internal_channels = list(
|
|
num2text(PUB_FREQ) = list(),
|
|
num2text(ENT_FREQ) = list(),
|
|
num2text(EXP_FREQ) = list(),
|
|
num2text(AI_FREQ) = list(ACCESS_EQUIPMENT),
|
|
num2text(ERT_FREQ) = list(ACCESS_CENT_SPECOPS),
|
|
num2text(COMM_FREQ)= list(ACCESS_HEADS),
|
|
num2text(ENG_FREQ) = list(ACCESS_ENGINE_EQUIP, ACCESS_ATMOSPHERICS),
|
|
num2text(MED_FREQ) = list(ACCESS_MEDICAL_EQUIP),
|
|
num2text(MED_I_FREQ)=list(ACCESS_MEDICAL_EQUIP),
|
|
num2text(SEC_FREQ) = list(ACCESS_SECURITY),
|
|
num2text(SEC_I_FREQ)=list(ACCESS_SECURITY),
|
|
num2text(PEN_FREQ) = list(ACCESS_ARMORY),
|
|
num2text(SCI_FREQ) = list(ACCESS_TOX,ACCESS_ROBOTICS,ACCESS_XENOBIOLOGY,ACCESS_XENOBOTANY),
|
|
num2text(SUP_FREQ) = list(ACCESS_CARGO),
|
|
num2text(SRV_FREQ) = list(ACCESS_JANITOR, ACCESS_HYDROPONICS)
|
|
)
|
|
|
|
var/global/list/default_medbay_channels = list(
|
|
num2text(PUB_FREQ) = list(),
|
|
num2text(MED_FREQ) = list(ACCESS_MEDICAL_EQUIP),
|
|
num2text(MED_I_FREQ) = list(ACCESS_MEDICAL_EQUIP)
|
|
)
|
|
|
|
var/global/list/default_expedition_channels = list(
|
|
num2text(PUB_FREQ) = list(),
|
|
num2text(EXP_FREQ) = list(),
|
|
num2text(HAIL_FREQ) = list()
|
|
)
|
|
|
|
var/global/list/default_interrogation_channels = list(
|
|
num2text(INT_FREQ) = list()
|
|
)
|
|
|
|
//
|
|
// Radios
|
|
//
|
|
|
|
/obj/item/radio
|
|
name = "shortwave radio"
|
|
icon = 'icons/obj/radio.dmi'
|
|
icon_state = "walkietalkie"
|
|
item_state = "radio"
|
|
obj_flags = OBJ_FLAG_CONDUCTABLE
|
|
slot_flags = SLOT_BELT
|
|
throw_speed = 2
|
|
throw_range = 9
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
matter = list(MATERIAL_ALUMINIUM = 75, MATERIAL_GLASS = 25)
|
|
suffix = "\[3\]"
|
|
var/radio_desc = ""
|
|
var/const/FREQ_LISTENING = TRUE
|
|
/// Automatically set on initialize, only update if bypass_default_internal is set to TRUE
|
|
var/list/internal_channels
|
|
/// played sound on usage
|
|
var/clicksound = SFX_BUTTON
|
|
/// volume of clicksound
|
|
var/clickvol = 10
|
|
|
|
var/obj/item/cell/cell = /obj/item/cell/device
|
|
var/last_radio_sound = -INFINITY
|
|
|
|
/// If FALSE, broadcasting and listening don't matter and this radio does nothing
|
|
VAR_PRIVATE/on = TRUE
|
|
|
|
/// Current frequency the radio is set to
|
|
VAR_PRIVATE/frequency = PUB_FREQ
|
|
/// frequency the radio defaults to on reset / startup
|
|
var/default_frequency = PUB_FREQ
|
|
|
|
/// Whether the radio transmits dialogue it hears nearby onto its radio channel
|
|
VAR_PRIVATE/broadcasting = FALSE
|
|
/// Whether the radio is currently receiving radio messages from its frequencies
|
|
VAR_PRIVATE/listening = TRUE
|
|
|
|
//the below vars are used to track listening and broadcasting should they be forced off for whatever reason but "supposed" to be active
|
|
//eg player sets the radio to listening, but an emp or whatever turns it off, its still supposed to be activated but was forced off,
|
|
//when it wears off it sets listening to should_be_listening
|
|
|
|
/// used for tracking what broadcasting should be in the absence of things forcing it off, eg its set to broadcast but gets emp'd temporarily
|
|
var/should_be_broadcasting = FALSE
|
|
/// used for tracking what listening should be in the absence of things forcing it off, eg its set to listen but gets emp'd temporarily
|
|
var/should_be_listening = TRUE
|
|
|
|
/// Both the range around the radio in which mobs can hear what it receives and the range the radio can hear
|
|
var/canhear_range = 3
|
|
|
|
var/last_transmission
|
|
/// tune to frequency to unlock traitor supplies
|
|
var/traitor_frequency = 0
|
|
/// used in autosay, held by the radio for re-use
|
|
var/mob/living/announcer/announcer = null
|
|
var/datum/wires/radio/wires = null
|
|
var/show_modify_on_examine = TRUE
|
|
var/b_stat = 0
|
|
|
|
/// see communications.dm for full list. First non-common, non-entertainment channel is a "default" for :h
|
|
var/list/channels = list()
|
|
var/subspace_transmission = FALSE
|
|
/// Holder to see if it's a syndicate encrypted radio
|
|
var/syndie = FALSE
|
|
/// if TRUE, can say/hear on the Special Channel!!! (TBD)
|
|
var/independent = FALSE
|
|
|
|
var/datum/radio_frequency/radio_connection
|
|
var/list/datum/radio_frequency/secure_radio_connections = list()
|
|
|
|
/obj/item/radio/feedback_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
if(show_modify_on_examine && (distance <= 1))
|
|
if (b_stat)
|
|
. += SPAN_NOTICE("\The [src] can be attached and modified!")
|
|
else
|
|
. += SPAN_NOTICE("\The [src] can not be modified or attached!")
|
|
|
|
if(radio_desc)
|
|
. += radio_desc
|
|
|
|
/obj/item/radio/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "The radio key .i will allow you to speak into a nearby intercom, .r will speak into a radio in your right hand, and .l will speak into your left. The microphone does not need to be enabled for this to work."
|
|
|
|
/obj/item/radio/proc/set_frequency(new_frequency)
|
|
SSradio.remove_object(src, frequency)
|
|
if(new_frequency)
|
|
frequency = new_frequency
|
|
radio_connection = SSradio.add_object(src, new_frequency, RADIO_CHAT)
|
|
|
|
/// By default copies default_internal_channels. Override on child for radios that need snowflake.
|
|
/obj/item/radio/proc/set_internal_channels()
|
|
return default_internal_channels.Copy()
|
|
|
|
/obj/item/radio/Initialize()
|
|
. = ..()
|
|
|
|
wires = new(src)
|
|
internal_channels = set_internal_channels()
|
|
|
|
if(frequency < RADIO_LOW_FREQ || frequency > RADIO_HIGH_FREQ)
|
|
frequency = sanitize_frequency(frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)
|
|
|
|
for (var/ch_name in channels)
|
|
secure_radio_connections[ch_name] = SSradio.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
|
|
|
set_listening(listening)
|
|
set_broadcasting(broadcasting)
|
|
set_frequency(default_frequency)
|
|
set_on(on)
|
|
|
|
/obj/item/radio/Destroy()
|
|
SSradio.remove_object_all(src)
|
|
QDEL_NULL(announcer)
|
|
QDEL_NULL(wires)
|
|
return ..()
|
|
|
|
/obj/item/radio/proc/is_on()
|
|
return on
|
|
|
|
/obj/item/radio/proc/get_frequency()
|
|
return frequency
|
|
|
|
/obj/item/radio/proc/get_broadcasting()
|
|
return broadcasting
|
|
|
|
/obj/item/radio/proc/get_listening()
|
|
return listening
|
|
|
|
/**
|
|
* setter for the listener var, adds or removes this radio from the global radio list if we are also on
|
|
*
|
|
* * new_listening - the new value we want to set listening to
|
|
* * actual_setting - whether or not the radio is supposed to be listening, sets should_be_listening to the new listening value if true, otherwise just changes listening
|
|
*/
|
|
/obj/item/radio/proc/set_listening(new_listening, actual_setting = TRUE)
|
|
|
|
listening = new_listening
|
|
if(actual_setting)
|
|
should_be_listening = listening
|
|
|
|
if(listening && on)
|
|
for(var/channel_name in channels)
|
|
if(channels[channel_name])
|
|
secure_radio_connections[channel_name] = SSradio.add_object(src, radiochannels[channel_name], RADIO_CHAT)
|
|
radio_connection = SSradio.add_object(src, frequency, RADIO_CHAT)
|
|
else if(!listening)
|
|
SSradio.remove_object_all(src)
|
|
radio_connection = null
|
|
|
|
/**
|
|
* setter for broadcasting that makes us not hearing sensitive if not broadcasting and hearing sensitive if broadcasting
|
|
* hearing sensitive in this case only matters for the purposes of listening for words said in nearby tiles, talking into us directly bypasses hearing
|
|
*
|
|
* * new_broadcasting- the new value we want to set broadcasting to
|
|
* * actual_setting - whether or not the radio is supposed to be broadcasting, sets should_be_broadcasting to the new value if true, otherwise just changes broadcasting
|
|
*/
|
|
/obj/item/radio/proc/set_broadcasting(new_broadcasting, actual_setting = TRUE)
|
|
|
|
broadcasting = new_broadcasting
|
|
if(actual_setting)
|
|
should_be_broadcasting = broadcasting
|
|
|
|
if(broadcasting && on) //we dont need hearing sensitivity if we arent broadcasting, because talk_into doesnt care about hearing
|
|
become_hearing_sensitive(INNATE_TRAIT)
|
|
else if(!broadcasting)
|
|
lose_hearing_sensitivity(INNATE_TRAIT)
|
|
|
|
///setter for the on var that sets both broadcasting and listening to off or whatever they were supposed to be
|
|
/obj/item/radio/proc/set_on(new_on)
|
|
|
|
on = new_on
|
|
|
|
if(on)
|
|
set_broadcasting(should_be_broadcasting)//set them to whatever theyre supposed to be
|
|
set_listening(should_be_listening)
|
|
else
|
|
set_broadcasting(FALSE, actual_setting = FALSE)//fake set them to off
|
|
set_listening(FALSE, actual_setting = FALSE)
|
|
|
|
/obj/item/radio/attack_self(mob/user as mob)
|
|
user.set_machine(src)
|
|
interact(user)
|
|
|
|
/obj/item/radio/interact(mob/user)
|
|
if(!user)
|
|
return 0
|
|
|
|
if(b_stat)
|
|
wires.interact(user)
|
|
|
|
return ui_interact(user)
|
|
|
|
/obj/item/radio/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
|
var/data[0]
|
|
|
|
data["mic_status"] = broadcasting
|
|
data["speaker"] = listening
|
|
data["freq"] = format_frequency(frequency)
|
|
data["default_freq"] = format_frequency(default_frequency)
|
|
data["rawfreq"] = num2text(frequency)
|
|
|
|
data["mic_cut"] = (wires.is_cut(WIRE_TRANSMIT) || wires.is_cut(WIRE_SIGNAL))
|
|
data["spk_cut"] = (wires.is_cut(WIRE_RECEIVE) || wires.is_cut(WIRE_SIGNAL))
|
|
|
|
var/list/chanlist = list_channels(user)
|
|
if(islist(chanlist) && chanlist.len)
|
|
data["chan_list"] = chanlist
|
|
data["chan_list_len"] = chanlist.len
|
|
|
|
if(syndie)
|
|
data["useSyndMode"] = 1
|
|
|
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430)
|
|
ui.set_initial_data(data)
|
|
ui.open()
|
|
|
|
/obj/item/radio/proc/setupRadioDescription(var/additional_radio_desc)
|
|
var/radio_text = ""
|
|
var/found_first_department = FALSE
|
|
for(var/i = 1 to channels.len)
|
|
var/channel = channels[i]
|
|
var/key = get_radio_key_from_channel(channel)
|
|
if(!length(key) && !found_first_department && channel != CHANNEL_COMMON && channel != CHANNEL_ENTERTAINMENT)
|
|
// if we don't have a key and it's the 'shortcut' channel, put the department key instead
|
|
key = get_radio_key_from_channel("department")
|
|
found_first_department = TRUE
|
|
|
|
radio_text += "[key] - [channel]"
|
|
if(i != channels.len)
|
|
radio_text += ", "
|
|
|
|
radio_desc = radio_text
|
|
if(additional_radio_desc)
|
|
radio_desc += additional_radio_desc
|
|
|
|
/obj/item/radio/proc/list_channels(var/mob/user)
|
|
return list_internal_channels(user)
|
|
|
|
/obj/item/radio/proc/list_secure_channels(var/mob/user)
|
|
var/dat[0]
|
|
|
|
for(var/ch_name in channels)
|
|
var/chan_stat = channels[ch_name]
|
|
var/listening = !!(chan_stat & FREQ_LISTENING) != 0
|
|
|
|
dat.Add(list(list("chan" = ch_name, "display_name" = ch_name, "secure_channel" = 1, "sec_channel_listen" = !listening, "chan_span" = frequency_span_class(radiochannels[ch_name]))))
|
|
|
|
return dat
|
|
|
|
/obj/item/radio/proc/list_internal_channels(var/mob/user)
|
|
var/dat[0]
|
|
for(var/internal_chan in internal_channels)
|
|
if(has_channel_access(user, internal_chan))
|
|
dat.Add(list(list("chan" = internal_chan, "display_name" = get_frequency_name(text2num(internal_chan)), "chan_span" = frequency_span_class(text2num(internal_chan)))))
|
|
|
|
return dat
|
|
|
|
/obj/item/radio/proc/has_channel_access(var/mob/user, var/freq)
|
|
if(!user)
|
|
return 0
|
|
|
|
if(!(freq in internal_channels))
|
|
return 0
|
|
|
|
return user.has_internal_radio_channel_access(internal_channels[freq])
|
|
|
|
/mob/proc/has_internal_radio_channel_access(var/list/req_one_accesses)
|
|
var/obj/item/card/id/I = GetIdCard()
|
|
return has_access(list(), req_one_accesses, I ? I.GetAccess() : list())
|
|
|
|
/mob/abstract/ghost/observer/has_internal_radio_channel_access(var/list/req_one_accesses)
|
|
return can_admin_interact()
|
|
|
|
/obj/item/radio/proc/text_wires()
|
|
if (b_stat)
|
|
return wires.get_status()
|
|
return
|
|
|
|
|
|
/obj/item/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/radio/CanUseTopic()
|
|
if(!on)
|
|
return STATUS_CLOSE
|
|
return ..()
|
|
|
|
/obj/item/radio/CouldUseTopic(var/mob/user)
|
|
..()
|
|
if(clicksound && iscarbon(user))
|
|
playsound(loc, clicksound, clickvol)
|
|
|
|
/obj/item/radio/Topic(href, href_list)
|
|
if(..())
|
|
return TRUE
|
|
|
|
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)
|
|
. = TRUE
|
|
|
|
else if (href_list["freq"])
|
|
var/new_frequency = (frequency + text2num(href_list["freq"]))
|
|
if ((new_frequency < PUBLIC_LOW_FREQ || new_frequency > PUBLIC_HIGH_FREQ))
|
|
new_frequency = sanitize_frequency(new_frequency)
|
|
set_frequency(new_frequency)
|
|
if(hidden_uplink)
|
|
if(hidden_uplink.check_trigger(usr, frequency, traitor_frequency))
|
|
usr << browse(null, "window=radio")
|
|
. = TRUE
|
|
else if (href_list["talk"])
|
|
set_broadcasting(!broadcasting)
|
|
. = TRUE
|
|
else if (href_list["listen"])
|
|
var/chan_name = href_list["ch_name"]
|
|
if (!chan_name)
|
|
set_listening(!listening)
|
|
else
|
|
if (channels[chan_name] & FREQ_LISTENING)
|
|
channels[chan_name] &= ~FREQ_LISTENING
|
|
else
|
|
channels[chan_name] |= FREQ_LISTENING
|
|
. = TRUE
|
|
else if(href_list["spec_freq"])
|
|
var freq = href_list["spec_freq"]
|
|
if(has_channel_access(usr, freq))
|
|
set_frequency(text2num(freq))
|
|
. = TRUE
|
|
else if(href_list["reset_freq"])
|
|
if(default_frequency)
|
|
set_frequency(default_frequency)
|
|
. = TRUE
|
|
|
|
if(href_list["nowindow"]) // here for pAIs, maybe others will want it, idk
|
|
return TRUE
|
|
|
|
if(.)
|
|
SSnanoui.update_uis(src)
|
|
update_icon()
|
|
|
|
/obj/item/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")
|
|
for(var/freq in channels)
|
|
if(freq == "Common" || freq == "Entertainment" || freq == "Expeditionary")
|
|
continue
|
|
channel = freq
|
|
break
|
|
if(channel == "department") // didn't find one, use first one
|
|
channel = channels[1]
|
|
connection = secure_radio_connections[channel]
|
|
else
|
|
connection = radio_connection
|
|
channel = null
|
|
|
|
if (!istype(connection))
|
|
return
|
|
|
|
if(!istype(announcer))
|
|
announcer = new()
|
|
|
|
announcer.PrepareBroadcast(from)
|
|
var/datum/weakref/speaker_weakref = WEAKREF(announcer)
|
|
var/datum/signal/subspace/vocal/signal = new(src, connection.frequency, speaker_weakref, announcer.default_language, message, "states")
|
|
signal.send_to_receivers()
|
|
announcer.ResetAfterBroadcast()
|
|
|
|
// Interprets the message mode when talking into a radio, possibly returning a connection datum
|
|
/obj/item/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 && channels.len > 0)
|
|
if(message_mode == "department") // Department radio shortcut
|
|
for(var/freq in channels)
|
|
if(freq == "Common" || freq == "Entertainment" || freq == "Expeditionary")
|
|
continue
|
|
message_mode = freq
|
|
break
|
|
if(message_mode == "department") // didn't find one, use first one
|
|
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/radio/talk_into(mob/living/M, message, channel, var/say_verb = "says", var/datum/language/speaking = null, var/ignore_restrained)
|
|
if(!on)
|
|
return FALSE
|
|
if(!M || !message)
|
|
return FALSE
|
|
if(wires.is_cut(WIRE_TRANSMIT)) // The device has to have all its wires and shit intact
|
|
return FALSE
|
|
|
|
if (iscarbon(M))
|
|
var/mob/living/carbon/C = M
|
|
if ((CE_UNDEXTROUS in C.chem_effects) || C.stunned >= 10)
|
|
to_chat(M, SPAN_WARNING("You can't move your arms enough to activate the radio..."))
|
|
return
|
|
if(iszombie(M))
|
|
to_chat(M, SPAN_WARNING("Try as you might, you cannot will your decaying body into operating \the [src]."))
|
|
return FALSE
|
|
|
|
if(istype(M))
|
|
if(M.restrained() && !ignore_restrained)
|
|
to_chat(M, SPAN_WARNING("You can't speak into \the [src.name] while restrained."))
|
|
return FALSE
|
|
M.trigger_aiming(TARGET_CAN_RADIO)
|
|
|
|
if(!radio_connection)
|
|
set_frequency(frequency)
|
|
|
|
if(loc == M)
|
|
playsound(loc, 'sound/effects/walkietalkie.ogg', 5, 0, -1, required_asfx_toggles = ASFX_RADIO)
|
|
|
|
/*
|
|
Roughly speaking, radios attempt to make a subspace transmission (which
|
|
is received, processed, and rebroadcast by the telecomms satellite) and
|
|
if that fails, they send a mundane radio transmission.
|
|
Headsets cannot send/receive mundane transmissions, only subspace.
|
|
Syndicate radios can hear transmissions on all well-known frequencies.
|
|
CentCom radios can hear the CentCom frequency no matter what.
|
|
*/
|
|
|
|
// Get the frequency
|
|
var/datum/radio_frequency/connection = handle_message_mode(M, message, channel)
|
|
if (!istype(connection))
|
|
return FALSE
|
|
|
|
// Determine the identify information attached to the signal
|
|
var/datum/weakref/speaker_weakref = WEAKREF(M)
|
|
var/datum/signal/subspace/vocal/signal = new(src, connection.frequency, speaker_weakref, speaking, message, say_verb)
|
|
|
|
// All radios attempt to use the subspace system
|
|
. = signal.send_to_receivers()
|
|
|
|
// If it's subspace only, that's all we can do
|
|
if(subspace_transmission)
|
|
return
|
|
|
|
// Non-subspace radios will check in a couple of seconds, and if the signal was never received, we send a mundane broadcast
|
|
addtimer(CALLBACK(src, PROC_REF(backup_transmission), signal), 2 SECONDS)
|
|
|
|
/obj/item/radio/proc/backup_transmission(datum/signal/subspace/vocal/signal)
|
|
var/turf/T = get_turf(src)
|
|
if (signal.data["done"] && (T.z in signal.levels))
|
|
return
|
|
|
|
// If we're here, the signal was never processed. Proceed with mundane broadcast:
|
|
signal.data["compression"] = 0
|
|
signal.transmission_method = TRANSMISSION_RADIO
|
|
signal.levels = GetConnectedZlevels(T.z)
|
|
signal.broadcast()
|
|
|
|
/obj/item/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
|
|
if (!broadcasting || get_dist(src, M) > canhear_range)
|
|
return
|
|
|
|
return talk_into(M, msg, null, verb, speaking, ignore_restrained = TRUE)
|
|
|
|
/obj/item/radio/proc/can_receive(input_frequency, list/levels)
|
|
// check if the radio can receive on the given frequency
|
|
if (!listening)
|
|
return
|
|
|
|
if (levels != RADIO_NO_Z_LEVEL_RESTRICTION)
|
|
var/turf/position = get_turf(src)
|
|
if (!position || !(position.z in levels))
|
|
return FALSE
|
|
|
|
if (within_jamming_range(src))
|
|
return FALSE
|
|
|
|
if ((input_frequency in ANTAG_FREQS) && !syndie) //Checks to see if it's allowed on that frequency, based on the encryption keys
|
|
return FALSE
|
|
|
|
for (var/ch_name in channels)
|
|
var/datum/radio_frequency/RF = secure_radio_connections[ch_name]
|
|
if (RF.frequency == input_frequency)
|
|
return channels[ch_name]
|
|
|
|
if (input_frequency == frequency)
|
|
return TRUE
|
|
|
|
return FALSE
|
|
|
|
/obj/item/radio/proc/send_hear(freq, level)
|
|
if(!can_receive(freq, level))
|
|
return
|
|
|
|
return get_hearers_in_view(canhear_range, src)
|
|
|
|
/obj/item/radio/attackby(obj/item/attacking_item, mob/user)
|
|
..()
|
|
user.set_machine(src)
|
|
if (!( attacking_item.tool_behaviour == TOOL_SCREWDRIVER ))
|
|
return
|
|
b_stat = !( b_stat )
|
|
if(!istype(src, /obj/item/radio/beacon))
|
|
if (b_stat)
|
|
user.show_message(SPAN_NOTICE("\The [src] can now be attached and modified!"))
|
|
else
|
|
user.show_message(SPAN_NOTICE("\The [src] can no longer be modified or attached!"))
|
|
updateDialog()
|
|
add_fingerprint(user)
|
|
return
|
|
else return
|
|
|
|
/obj/item/radio/emp_act(severity)
|
|
. = ..()
|
|
|
|
set_broadcasting(FALSE)
|
|
set_listening(FALSE)
|
|
for (var/ch_name in channels)
|
|
channels[ch_name] = 0
|
|
|
|
//
|
|
// Vesselbound Synthetic Radio
|
|
//
|
|
|
|
/obj/item/radio/borg
|
|
var/mob/living/silicon/robot/myborg = null // Cyborg which owns this radio. Used for power checks
|
|
var/obj/item/encryptionkey/keyslot = null//Borg radios can handle a single encryption key
|
|
var/shut_up = 1
|
|
icon = 'icons/obj/robot_component.dmi' // Cyborgs radio icons should look like the component.
|
|
icon_state = "radio"
|
|
canhear_range = 0
|
|
subspace_transmission = 1
|
|
name = "integrated radio"
|
|
var/radio_sound = null
|
|
|
|
/obj/item/radio/borg/Destroy()
|
|
myborg = null
|
|
. = ..()
|
|
GC_TEMPORARY_HARDDEL
|
|
|
|
/obj/item/radio/borg/list_channels(var/mob/user)
|
|
return list_secure_channels(user)
|
|
|
|
/obj/item/radio/borg/talk_into(mob/living/M, message, channel, verb, datum/language/speaking, var/ignore_restrained)
|
|
. = ..()
|
|
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/radio/borg/attackby(obj/item/attacking_item, mob/user)
|
|
// ..()
|
|
user.set_machine(src)
|
|
if (!( attacking_item.tool_behaviour == TOOL_SCREWDRIVER || (istype(attacking_item, /obj/item/encryptionkey/ ))))
|
|
return
|
|
|
|
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER)
|
|
if(keyslot)
|
|
|
|
|
|
for(var/ch_name in channels)
|
|
SSradio.remove_object(src, radiochannels[ch_name])
|
|
secure_radio_connections[ch_name] = null
|
|
|
|
|
|
if(keyslot)
|
|
var/turf/T = get_turf(user)
|
|
if(T)
|
|
keyslot.forceMove(T)
|
|
keyslot = null
|
|
|
|
recalculateChannels()
|
|
to_chat(user, "You pop out the encryption key in the radio!")
|
|
|
|
else
|
|
to_chat(user, "This radio doesn't have any encryption keys!")
|
|
|
|
if(istype(attacking_item, /obj/item/encryptionkey/))
|
|
if(keyslot)
|
|
to_chat(user, "The radio can't hold another key!")
|
|
return
|
|
|
|
if(!keyslot)
|
|
user.drop_from_inventory(attacking_item,src)
|
|
keyslot = attacking_item
|
|
|
|
recalculateChannels()
|
|
|
|
return
|
|
|
|
/obj/item/radio/borg/proc/recalculateChannels()
|
|
channels = list(CHANNEL_COMMON = TRUE, CHANNEL_ENTERTAINMENT = TRUE, CHANNEL_EXPED = TRUE)
|
|
syndie = FALSE
|
|
|
|
if(isrobot(loc))
|
|
var/mob/living/silicon/robot/D = loc
|
|
if(D.module)
|
|
for(var/ch_name in D.module.channels)
|
|
if(ch_name in channels)
|
|
continue
|
|
channels[ch_name] += D.module.channels[ch_name]
|
|
if(keyslot)
|
|
for(var/ch_name in keyslot.channels)
|
|
if(ch_name in channels)
|
|
continue
|
|
channels += ch_name
|
|
channels[ch_name] += keyslot.channels[ch_name]
|
|
|
|
if(keyslot.syndie)
|
|
syndie = TRUE
|
|
|
|
if(keyslot.independent)
|
|
independent = TRUE
|
|
|
|
for(var/ch_name in src.channels)
|
|
if(!SSradio)
|
|
sleep(30) // Waiting for the SSradio to be created.
|
|
if(!SSradio)
|
|
name = "broken radio"
|
|
return
|
|
secure_radio_connections[ch_name] = SSradio.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
|
|
|
setupRadioDescription()
|
|
return
|
|
|
|
/obj/item/radio/borg/Topic(href, href_list)
|
|
if(..())
|
|
return 1
|
|
if (href_list["mode"])
|
|
var/enable_subspace_transmission = text2num(href_list["mode"])
|
|
if(enable_subspace_transmission != subspace_transmission)
|
|
subspace_transmission = !subspace_transmission
|
|
if(subspace_transmission)
|
|
to_chat(usr, SPAN_NOTICE("Subspace Transmission is enabled"))
|
|
else
|
|
to_chat(usr, SPAN_NOTICE("Subspace Transmission is disabled"))
|
|
|
|
if(subspace_transmission == 0)//Simple as fuck, clears the channel list to prevent talking/listening over them if subspace transmission is disabled
|
|
channels = list()
|
|
else
|
|
recalculateChannels()
|
|
. = 1
|
|
if (href_list["shutup"]) // Toggle loudspeaker mode, AKA everyone around you hearing your radio.
|
|
var/do_shut_up = text2num(href_list["shutup"])
|
|
if(do_shut_up != shut_up)
|
|
shut_up = !shut_up
|
|
if(shut_up)
|
|
canhear_range = 0
|
|
to_chat(usr, SPAN_NOTICE("Loadspeaker disabled."))
|
|
else
|
|
canhear_range = 3
|
|
to_chat(usr, SPAN_NOTICE("Loadspeaker enabled."))
|
|
. = 1
|
|
|
|
if(.)
|
|
SSnanoui.update_uis(src)
|
|
|
|
/obj/item/radio/borg/interact(mob/user as mob)
|
|
if(!on)
|
|
return
|
|
|
|
. = ..()
|
|
|
|
/obj/item/radio/borg/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
|
var/data[0]
|
|
|
|
data["mic_status"] = broadcasting
|
|
data["speaker"] = listening
|
|
data["freq"] = format_frequency(frequency)
|
|
data["default_freq"] = format_frequency(default_frequency)
|
|
data["rawfreq"] = num2text(frequency)
|
|
|
|
var/list/chanlist = list_channels(user)
|
|
if(islist(chanlist) && chanlist.len)
|
|
data["chan_list"] = chanlist
|
|
data["chan_list_len"] = chanlist.len
|
|
|
|
if(syndie)
|
|
data["useSyndMode"] = 1
|
|
|
|
data["has_loudspeaker"] = 1
|
|
data["loudspeaker"] = !shut_up
|
|
data["has_subspace"] = 1
|
|
data["subspace"] = subspace_transmission
|
|
|
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "radio_basic.tmpl", "[name]", 400, 430)
|
|
ui.set_initial_data(data)
|
|
ui.open()
|
|
|
|
/obj/item/radio/proc/config(op)
|
|
if(SSradio)
|
|
for (var/ch_name in channels)
|
|
SSradio.remove_object(src, radiochannels[ch_name])
|
|
secure_radio_connections = list()
|
|
channels = op
|
|
if(SSradio)
|
|
for (var/ch_name in op)
|
|
secure_radio_connections[ch_name] = SSradio.add_object(src, radiochannels[ch_name], RADIO_CHAT)
|
|
return
|
|
|
|
//
|
|
// Radio Variants
|
|
//
|
|
|
|
/obj/item/radio/map_preset
|
|
channels = list()
|
|
|
|
/obj/item/radio/map_preset/Initialize()
|
|
if(!SSatlas.current_map.use_overmap)
|
|
return ..()
|
|
|
|
var/turf/T = get_turf(src)
|
|
var/obj/effect/overmap/visitable/V = GLOB.map_sectors["[T.z]"]
|
|
if(istype(V) && V.comms_support)
|
|
var/freq_name = V.name
|
|
if(V.freq_name)
|
|
freq_name = V.freq_name
|
|
frequency = assign_away_freq(freq_name)
|
|
default_frequency = frequency
|
|
channels += list(
|
|
freq_name = TRUE,
|
|
CHANNEL_HAILING = TRUE
|
|
)
|
|
if(V.comms_name)
|
|
name = "[V.comms_name] shortwave radio"
|
|
|
|
return ..()
|
|
|
|
/obj/item/radio/map_preset/set_internal_channels()
|
|
return list(
|
|
num2text(default_frequency) = list(),
|
|
num2text(HAIL_FREQ) = list()
|
|
)
|
|
|
|
/obj/item/radio/hailing
|
|
default_frequency = HAIL_FREQ
|
|
|
|
/obj/item/radio/hailing/set_internal_channels()
|
|
return list(
|
|
num2text(HAIL_FREQ) = list()
|
|
)
|
|
|
|
/obj/item/radio/hailing/Initialize()
|
|
channels = list(
|
|
CHANNEL_HAILING = TRUE
|
|
)
|
|
return ..()
|
|
|
|
// Radio (Off)
|
|
/obj/item/radio/off/Initialize()
|
|
. = ..()
|
|
set_listening(FALSE)
|
|
|
|
// Medical
|
|
/obj/item/radio/med
|
|
icon_state = "walkietalkie-med"
|
|
|
|
// Medical (Off)
|
|
/obj/item/radio/med/off/Initialize()
|
|
. = ..()
|
|
set_listening(FALSE)
|
|
|
|
// Security
|
|
/obj/item/radio/sec
|
|
icon_state = "walkietalkie-sec"
|
|
|
|
// Security (Off)
|
|
/obj/item/radio/sec/off/Initialize()
|
|
. = ..()
|
|
set_listening(FALSE)
|
|
|
|
// Engineering
|
|
/obj/item/radio/eng
|
|
icon_state = "walkietalkie-eng"
|
|
|
|
// Engineering (Off)
|
|
/obj/item/radio/eng/off/Initialize()
|
|
. = ..()
|
|
set_listening(FALSE)
|
|
|
|
// Science
|
|
/obj/item/radio/sci
|
|
icon_state = "walkietalkie-sci"
|
|
|
|
// Science (Off)
|
|
/obj/item/radio/sci/off/Initialize()
|
|
. = ..()
|
|
set_listening(FALSE)
|
|
|
|
// Phone
|
|
/obj/item/radio/phone
|
|
icon = 'icons/obj/radio.dmi'
|
|
icon_state = "red_phone"
|
|
name = "phone"
|
|
var/radio_sound = null
|
|
|
|
/obj/item/radio/phone/Initialize()
|
|
. = ..()
|
|
set_broadcasting(FALSE)
|
|
set_listening(TRUE)
|
|
|
|
// Medical Phone
|
|
/obj/item/radio/phone/medbay/Initialize()
|
|
. = ..()
|
|
set_frequency(MED_I_FREQ)
|
|
internal_channels = default_medbay_channels.Copy()
|
|
|
|
// All-channel Radio
|
|
/obj/item/radio/all_channels/Initialize()
|
|
channels = ALL_RADIO_CHANNELS.Copy()
|
|
. = ..()
|