mirror of
https://github.com/goonstation/goonstation-2020.git
synced 2026-07-12 15:42:21 +01:00
1057 lines
36 KiB
Plaintext
1057 lines
36 KiB
Plaintext
/obj/item/device/radio
|
|
name = "station bounced radio"
|
|
desc = "A portable, non-wearable radio for communicating over a specified frequency. Has a microphone and a speaker which can be independently toggled."
|
|
suffix = "\[3\]"
|
|
icon_state = "walkietalkie"
|
|
item_state = "walkietalkie"
|
|
var/device_color = RADIOC_STANDARD
|
|
var/last_transmission
|
|
var/frequency = R_FREQ_DEFAULT
|
|
var/locked_frequency = 0 // can't change the frequency from default: enables radios to be outside the default range as well
|
|
var/list/secure_frequencies = null
|
|
var/list/secure_colors = list("#E00000")
|
|
var/protected_radio = 0 // Cannot be picked up by radio_brain bioeffect.
|
|
var/traitor_frequency = 0.0
|
|
var/obj/item/device/radio/patch_link = null
|
|
var/obj/item/uplink/integrated/radio/traitorradio = null
|
|
var/wires = WIRE_SIGNAL | WIRE_RECEIVE | WIRE_TRANSMIT
|
|
var/b_stat = 0.0
|
|
var/broadcasting = null
|
|
var/listening = 1.0
|
|
var/list/secure_connections = null
|
|
var/datum/radio_frequency/radio_connection
|
|
var/speaker_range = 2
|
|
var/static/image/speech_bubble = image('icons/mob/mob.dmi', "speech")
|
|
flags = FPRINT | TABLEPASS | ONBELT | CONDUCT
|
|
throw_speed = 2
|
|
throw_range = 9
|
|
w_class = 2.0
|
|
mats = 3
|
|
|
|
var/bicon_override = 0
|
|
|
|
var/const
|
|
WIRE_SIGNAL = 1 //sends a signal, like to set off a bomb or electrocute someone
|
|
WIRE_RECEIVE = 2
|
|
WIRE_TRANSMIT = 4
|
|
TRANSMISSION_DELAY = 5 // only 2/second/radio
|
|
WINDOW_OPTIONS = "window=radio;size=280x350"
|
|
|
|
|
|
// Moved initializaiton to world/New
|
|
var/list/headset_channel_lookup
|
|
|
|
/obj/item/device/radio/New()
|
|
..()
|
|
if(radio_controller)
|
|
initialize()
|
|
|
|
/obj/item/device/radio/initialize()
|
|
if ((src.frequency < R_FREQ_MINIMUM || src.frequency > R_FREQ_MAXIMUM) && !src.locked_frequency)
|
|
// if the frequency is somehow set outside of the normal range, put it back in range
|
|
world.log << "[src] ([src.type]) has a frequency of [src.frequency], sanitizing."
|
|
src.frequency = sanitize_frequency(src.frequency)
|
|
|
|
set_frequency(frequency)
|
|
if(src.secure_frequencies)
|
|
set_secure_frequencies()
|
|
|
|
/obj/item/device/radio/disposing()
|
|
radio_controller.remove_object(src, "[frequency]")
|
|
|
|
if(istype(src.secure_frequencies))
|
|
for (var/sayToken in src.secure_frequencies)
|
|
var/frequency_id = src.secure_frequencies["[sayToken]"]
|
|
if (frequency_id)
|
|
radio_controller.remove_object(src, "[frequency_id]")
|
|
|
|
src.secure_connections = null
|
|
src.secure_frequencies = null
|
|
|
|
..()
|
|
|
|
/obj/item/device/radio/proc/set_frequency(new_frequency)
|
|
radio_controller.remove_object(src, "[frequency]")
|
|
frequency = new_frequency
|
|
radio_connection = radio_controller.add_object(src, "[frequency]")
|
|
|
|
/obj/item/device/radio/proc/set_secure_frequencies()
|
|
if(istype(src.secure_frequencies))
|
|
for (var/sayToken in src.secure_frequencies)
|
|
var/frequency_id = src.secure_frequencies["[sayToken]"]
|
|
if (frequency_id)
|
|
if (!istype(src.secure_connections))
|
|
src.secure_connections = list()
|
|
src.secure_connections["[sayToken]"] = radio_controller.add_object(src, "[frequency_id]")
|
|
else
|
|
src.secure_frequencies -= "[sayToken]"
|
|
|
|
/obj/item/device/radio/proc/set_secure_frequency(frequencyToken, newFrequency)
|
|
if (!frequencyToken || !newFrequency)
|
|
return
|
|
|
|
if(!istype(src.secure_frequencies))
|
|
secure_frequencies = list()
|
|
|
|
if(!istype(src.secure_connections))
|
|
secure_connections = list()
|
|
|
|
var/oldFrequency = src.secure_frequencies["[frequencyToken]"]
|
|
if (oldFrequency)
|
|
radio_controller.remove_object(src, "[oldFrequency]")
|
|
|
|
src.secure_connections["[frequencyToken]"] = radio_controller.add_object(src, "[newFrequency]")
|
|
src.secure_frequencies["[frequencyToken]"] = newFrequency
|
|
return
|
|
|
|
/obj/item/device/radio/attack_self(mob/user as mob)
|
|
user.machine = src
|
|
|
|
var/dat = {"
|
|
Microphone: [src.broadcasting ? "<a href='?src=\ref[src];talk=0'>Engaged</a>" : "<a href='?src=\ref[src];talk=1'>Disengaged</a>"]
|
|
<br>Speaker: [src.listening ? "<a href='?src=\ref[src];listen=0'>Engaged</a>" : "<a href='?src=\ref[src];listen=1'>Disengaged</a>"]
|
|
<br>Frequency:
|
|
[!src.locked_frequency ? "<a href='?src=\ref[src];freq=-10'>-</a> <a href='?src=\ref[src];freq=-2'>-</a> <a href='?src=\ref[src];freq=set'><strong>[format_frequency(src.frequency)]</strong></a> <a href='?src=\ref[src];freq=2'>+</a> <a href='?src=\ref[src];freq=10'>+</a>" : "</strong>[format_frequency(src.frequency)]</strong>"]
|
|
"}
|
|
|
|
if (istype(src.secure_frequencies) && src.secure_frequencies.len)
|
|
dat += "<hr>Supplementary Channels:<table style='border-collapse: collapse;' cellpadding='2'><tr><th>Channel</th><th>Freq</th><th>Prefix</th></tr>"
|
|
for (var/sayToken in src.secure_frequencies)
|
|
dat += {"<tr><td>[ headset_channel_lookup["[src.secure_frequencies["[sayToken]"]]"] ? headset_channel_lookup["[src.secure_frequencies["[sayToken]"]]"] : "???" ]</td><td> <strong>[format_frequency(src.secure_frequencies["[sayToken]"])]</strong></td><td><code>[sayToken]</code></td></tr>
|
|
"}
|
|
|
|
dat += "</table>"
|
|
|
|
if (src.b_stat)
|
|
dat += {"
|
|
<hr>
|
|
Green Wire: <a href='?src=\ref[src];wires=[WIRE_TRANSMIT]'>[src.wires & WIRE_TRANSMIT ? "Cut" : "Mend"] Wire</a>
|
|
<br>Red Wire: <a href='?src=\ref[src];wires=[WIRE_RECEIVE]'>[src.wires & WIRE_RECEIVE ? "Cut" : "Mend"] Wire</a>
|
|
<br>Blue Wire: <a href='?src=\ref[src];wires=[WIRE_SIGNAL]'>[src.wires & WIRE_SIGNAL ? "Cut" : "Mend"] Wire</a>
|
|
"}
|
|
|
|
user.Browse(dat, WINDOW_OPTIONS)
|
|
onclose(user, "radio")
|
|
return
|
|
|
|
/obj/item/device/radio/Topic(href, href_list)
|
|
//..()
|
|
if (usr.stat)
|
|
return
|
|
|
|
// Band-aid fix for intercoms, RE 'bounds_dist' check in the 'in_range' proc. Feel free to improve the implementation (Convair880).
|
|
var/special_cases =((istype(src, /obj/item/device/radio/intercom) && (get_dist(src, usr) <= 1) && (istype(src.loc, /turf))) || (istype(src, /obj/item/device/radio/spy) && (get_dist(src, usr) <= 1)))
|
|
if ((issilicon(usr) || isAI(usr)) || (src in usr) || (special_cases) || (usr.loc == src.loc))
|
|
usr.machine = src
|
|
|
|
if (href_list["track"])
|
|
// wait is tracking here? really? what? ???? ????????????
|
|
var/mob/target = locate(href_list["track"])
|
|
var/mob/living/silicon/A = locate(href_list["track2"])
|
|
A.ai_actual_track(target)
|
|
return
|
|
|
|
if (href_list["freq"])
|
|
var/new_frequency = null
|
|
|
|
if (href_list["freq"] == "set")
|
|
new_frequency = input(usr, "New frequency ([R_FREQ_MINIMUM] - [R_FREQ_MAXIMUM]):", "Enter new frequency", frequency) as null|num
|
|
if (!new_frequency)
|
|
return
|
|
else
|
|
new_frequency = frequency + text2num(href_list["freq"])
|
|
|
|
set_frequency(sanitize_frequency(new_frequency))
|
|
|
|
if (!isnull(src.traitorradio) && src.traitor_frequency && src.frequency == src.traitor_frequency)
|
|
usr.machine = null
|
|
usr.Browse(null, WINDOW_OPTIONS)
|
|
onclose(usr, "radio")
|
|
// now transform the regular radio, into a (disguised)syndicate uplink!
|
|
var/obj/item/uplink/integrated/radio/T = src.traitorradio
|
|
var/obj/item/device/radio/R = src
|
|
R.set_loc(T)
|
|
usr.u_equip(R)
|
|
usr.put_in_hand_or_drop(T)
|
|
R.set_loc(T)
|
|
T.attack_self(usr)
|
|
return
|
|
|
|
else if (href_list["talk"])
|
|
src.broadcasting = text2num(href_list["talk"])
|
|
|
|
else if (href_list["listen"])
|
|
src.listening = text2num(href_list["listen"])
|
|
|
|
else if (href_list["wires"])
|
|
if (!(usr.find_tool_in_hand(TOOL_SNIPPING)))
|
|
return
|
|
|
|
var/wireflip = text2num(href_list["wires"]) & (WIRE_SIGNAL | WIRE_RECEIVE | WIRE_TRANSMIT)
|
|
if (wireflip)
|
|
src.wires ^= wireflip
|
|
|
|
if (istype(src, /obj/item/device/radio/spy))
|
|
src.updateSelfDialogFromTurf() //radio is inside of another object, use turf
|
|
|
|
if (!( src.master ))
|
|
if (ismob(src.loc))
|
|
attack_self(src.loc)
|
|
if (istype(src.loc, /mob/living/silicon/ai)) // eyecam handling
|
|
src.updateSelfDialog()
|
|
else if (istype(src.loc, /obj))
|
|
for(var/mob/M in src.loc)
|
|
attack_self(M)
|
|
else
|
|
src.updateDialog()
|
|
else
|
|
if (ismob(src.master.loc))
|
|
src.attack_self(src.master.loc)
|
|
else
|
|
src.updateDialog()
|
|
|
|
src.add_fingerprint(usr)
|
|
else
|
|
usr.Browse(null, WINDOW_OPTIONS)
|
|
|
|
//pass to talk_into instead of a mob if you don't have a mob handy
|
|
//please don't read this i'm so ashamed
|
|
/datum/generic_radio_source
|
|
var/name = "Unknown"
|
|
var/real_name = "Unknown"
|
|
var/voice_name = "Unknown"
|
|
var/voice_message = "broadcasts"
|
|
var/say_language = "english"
|
|
|
|
proc/say_quote(var/text)
|
|
return "[src.voice_message], \"[text]\""
|
|
|
|
proc/set_name(var/new_name)
|
|
name = new_name
|
|
real_name = new_name
|
|
voice_name = new_name
|
|
|
|
/obj/item/device/radio/proc/radio_bicon(var/mob/user)
|
|
.= 0
|
|
if (isAI(user))
|
|
.= bicon(aiIcon)
|
|
else if (isrobot(user))
|
|
.= bicon(roboIcon)
|
|
else if (bicon_override)
|
|
if (bicon_override == "head")
|
|
.= bicon(headIcon)
|
|
else if (bicon_override == "sci")
|
|
.= bicon(sciIcon)
|
|
else if (bicon_override == "med")
|
|
.= bicon(medIcon)
|
|
else if (bicon_override == "eng")
|
|
.= bicon(engIcon)
|
|
else if (bicon_override == "sec")
|
|
.= bicon(secIcon)
|
|
else if (bicon_override == "qm")
|
|
.= bicon(qmIcon)
|
|
else if (bicon_override == "ai")
|
|
.= bicon(aiIcon)
|
|
else if (bicon_override == "syndie")
|
|
.= bicon(syndieIcon)
|
|
else if (bicon_override == "syndieboss")
|
|
.= bicon(syndiebossIcon)
|
|
else
|
|
.= bicon(civIcon)
|
|
else
|
|
.= bicon(src)
|
|
|
|
/obj/item/device/radio/talk_into(mob/M as mob, messages, secure, real_name, lang_id)
|
|
// According to a pair of DEBUG calls set up for testing, no radio jammer check for the src radio was performed.
|
|
// As improbable as this sounds, there are bug reports too to back up the findings. So uhm...
|
|
if (src.radio_connection.check_for_jammer(src) != 0)
|
|
return
|
|
if (!(src.wires & WIRE_TRANSMIT))
|
|
return
|
|
// if (last_transmission && world.time < (last_transmission + TRANSMISSION_DELAY))
|
|
// return
|
|
|
|
var/eqjobname
|
|
|
|
if (iscarbon(M))
|
|
if (hasvar(M, "wear_id"))
|
|
if (M:wear_id)
|
|
eqjobname = M:wear_id:assignment
|
|
else
|
|
eqjobname = "No ID"
|
|
else if (isAI(M))
|
|
eqjobname = "AI"
|
|
else if (isrobot(M))
|
|
eqjobname = "Cyborg"
|
|
else if (istype(M, /obj/machinery/computer)) // :v
|
|
eqjobname = "Computer"
|
|
else
|
|
eqjobname = "Unknown"
|
|
|
|
var/list/receive = list()
|
|
|
|
var/display_freq = src.frequency //Frequency to display on radio broadcast messages
|
|
|
|
var/datum/radio_frequency/connection = null
|
|
if (secure && src.secure_connections && istype(src.secure_connections["[secure]"], /datum/radio_frequency))
|
|
connection = src.secure_connections["[secure]"]
|
|
display_freq = src.secure_frequencies["[secure]"]
|
|
else
|
|
connection = src.radio_connection
|
|
secure = 0
|
|
|
|
for (var/obj/item/device/radio/R in connection.devices)
|
|
|
|
//MBC : Do checks here and call check_for_jammer_bare instead. reduces proc calls.
|
|
if (can_check_jammer)
|
|
if (connection.check_for_jammer_bare(R))
|
|
continue
|
|
|
|
if (R.accept_rad(src, messages, connection))
|
|
R.speech_bubble()
|
|
for (var/i in R.send_hear())
|
|
if (!(i in receive))
|
|
receive += i
|
|
|
|
var/list/heard_flock = list() // heard by flockdrones/flockmind
|
|
|
|
// Don't let them monitor Syndie headsets. You can get the radio_brain bioeffect at the start of the round, basically.
|
|
if (src.protected_radio != 1 && isnull(src.traitorradio))
|
|
for (var/mob/living/L in radio_brains)
|
|
receive += L
|
|
// hi it's me cirr here to shoehorn in another thing
|
|
// flockdrones and flockmind should hear all channels, but with terrible corruption
|
|
if(flocks && flocks.len)
|
|
for(var/F in flocks)
|
|
var/datum/flock/flock = flocks[F]
|
|
if(flock)
|
|
if(flock.flockmind)
|
|
heard_flock |= flock.flockmind
|
|
if(flock.units && flock.units.len > 0)
|
|
for(var/mob/living/D in flock.units)
|
|
if(D)
|
|
heard_flock |= D
|
|
|
|
for (var/mob/dead/D in mobs)
|
|
if (D.client && (istype(D, /mob/dead/observer) || (iswraith(D) && !D.density)) || ((!isturf(src.loc) && src.loc == D.loc) && !istype(D, /mob/dead/target_observer)))
|
|
if (!(D in receive))
|
|
receive += D
|
|
|
|
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
|
|
|
|
|
|
// Receiving mobs
|
|
for (var/mob/R in receive)
|
|
if (R.say_understands(M, lang_id))
|
|
if (!isghostdrone(R) && (!ishuman(M) || (ishuman(M) && M.wear_mask && M.wear_mask.vchange))) //istype(M.wear_mask, /obj/item/clothing/mask/gas/voice))
|
|
heard_masked += R
|
|
else if (isghostdrone(R))
|
|
heard_voice += R
|
|
else if(!isflock(R)) // a special exemption for flockdrones/flockminds who never get to hear normal radio
|
|
heard_normal += R
|
|
else
|
|
if (M.voice_message)
|
|
heard_voice += R
|
|
else
|
|
heard_garbled += R
|
|
|
|
//DEBUG_MESSAGE("Message transmitted. Frequency: [display_freq]. Source: [src] at [log_loc(src)]. Receiver: [R] at [log_loc(R)].")
|
|
|
|
var/rendered
|
|
|
|
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled) || length(heard_flock))
|
|
var/textColor = null
|
|
if (secure)
|
|
textColor = secure_colors["[secure]"]
|
|
if (!textColor)
|
|
if (secure_colors.len)
|
|
textColor = secure_colors[1]
|
|
else
|
|
textColor = "#E00000"
|
|
|
|
var/part_a
|
|
if (ismob(M) && M.mind)
|
|
part_a = "[radio_bicon(M)] <span class='radio' style='color: [secure ? textColor : src.device_color]'><span class='name' data-ctx='\ref[M.mind]'>"
|
|
else
|
|
part_a = "[radio_bicon(M)]<span class='radio' style='color: [secure ? textColor : src.device_color]'><span class='name'>"
|
|
var/part_b = "</span><b> \[[format_frequency(display_freq)]\]</b> <span class='message'>"
|
|
var/part_c = "</span></span>"
|
|
|
|
|
|
if (length(heard_masked))
|
|
if (ishuman(M))
|
|
if (M:wear_id)
|
|
rendered = "[part_a][M:wear_id:registered][part_b][M.say_quote(messages[1])][part_c]"
|
|
else
|
|
rendered = "[part_a]Unknown[part_b][M.say_quote(messages[1])][part_c]"
|
|
else
|
|
rendered = "[part_a][M.name][part_b][M.say_quote(messages[1])][part_c]"
|
|
|
|
for (var/mob/R in heard_masked)
|
|
var/thisR = rendered
|
|
if (R.isAIControlled())
|
|
thisR = "[part_a]<a href='?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.name] ([eqjobname]) </a>[part_b][M.say_quote(messages[1])][part_c]"
|
|
|
|
if (R.client && R.client.holder && ismob(M) && M.mind)
|
|
thisR = "<span class='adminHearing' data-ctx='[R.client.chatOutput.getContextFlags()]'>[thisR]</span>"
|
|
R.show_message(thisR, 2)
|
|
|
|
if (length(heard_normal))
|
|
rendered = "[part_a][real_name ? real_name : M.real_name][part_b][M.say_quote(messages[1])][part_c]"
|
|
for (var/mob/R in heard_normal)
|
|
var/thisR = rendered
|
|
if (R.isAIControlled())
|
|
thisR = "[part_a]<a href='?src=\ref[src];track2=\ref[R];track=\ref[M]'>[real_name ? real_name : M.real_name] ([eqjobname]) </a>[part_b][M.say_quote(messages[1])][part_c]"
|
|
|
|
if (R.client && R.client.holder && ismob(M) && M.mind)
|
|
thisR = "<span class='adminHearing' data-ctx='[R.client.chatOutput.getContextFlags()]'>[thisR]</span>"
|
|
R.show_message(thisR, 2)
|
|
|
|
if (length(heard_voice))
|
|
rendered = "[part_a][M.voice_name][part_b][M.voice_message][part_c]"
|
|
for (var/mob/R in heard_voice)
|
|
var/thisR = rendered
|
|
if (R.isAIControlled())
|
|
thisR = "[part_a]<a href='?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name] ([eqjobname]) </a>[part_b][M.voice_message][part_c]"
|
|
else if (isghostdrone(R))
|
|
thisR = "[part_a][M.voice_name][part_b][M.say_quote(messages[1])][part_c]"
|
|
|
|
if (R.client && R.client.holder && ismob(M) && M.mind)
|
|
thisR = "<span class='adminHearing' data-ctx='[R.client.chatOutput.getContextFlags()]'>[thisR]</span>"
|
|
R.show_message(thisR, 2)
|
|
|
|
if (length(heard_garbled))
|
|
rendered = "[part_a][M.voice_name][part_b][M.say_quote(messages[2])][part_c]"
|
|
for (var/mob/R in heard_garbled)
|
|
var/thisR = rendered
|
|
if (R.isAIControlled())
|
|
thisR = "[part_a]<a href='?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name]</a>[part_b][M.say_quote(messages[2])][part_c]"
|
|
|
|
if (R.client && R.client.holder && ismob(M) && M.mind)
|
|
thisR = "<span class='adminHearing' data-ctx='[R.client.chatOutput.getContextFlags()]'>[thisR]</span>"
|
|
R.show_message(thisR, 2)
|
|
|
|
// sure why NOT copy paste - cirr
|
|
// TODO: datumise this to cut down on all the damn copy paste - cirr
|
|
if (length(heard_flock))
|
|
rendered = "[part_a][radioGarbleText(real_name ? real_name : M.real_name, 10)][part_b][M.say_quote(radioGarbleText(messages[1], 40))][part_c]"
|
|
for (var/mob/R in heard_flock)
|
|
var/thisR = rendered
|
|
// there will NEVER be an AI controlled member of this, SO HELP ME IF THERE IS
|
|
if (R.client && R.client.holder && ismob(M) && M.mind)
|
|
thisR = "<span class='adminHearing' data-ctx='[R.client.chatOutput.getContextFlags()]'>[thisR]</span>"
|
|
R.show_message(thisR, 2)
|
|
|
|
|
|
/obj/item/device/radio/hear_talk(mob/M as mob, msgs, real_name, lang_id)
|
|
if (src.broadcasting)
|
|
talk_into(M, msgs, null, real_name, lang_id)
|
|
|
|
// Hope I didn't butcher this, but I couldn't help but notice some odd stuff going on when I tried to debug radio jammers (Convair880).
|
|
/obj/item/device/radio/proc/accept_rad(obj/item/device/radio/R as obj, message, var/datum/radio_frequency/freq)
|
|
if (message)
|
|
// Simple frequency match. The only check that used to be here.
|
|
if (src.frequency == R.frequency)
|
|
//DEBUG_MESSAGE("Match found for transmission from [R] at [log_loc(R)] (simple frequency match)")
|
|
return 1
|
|
|
|
// Secure channel lookup when R.frequency != src.frequency. According to DEBUG calls set up for testing,
|
|
// this meant the receiving radio would decline the message even though both share a secure channel.
|
|
else if (src.secure_connections && istype(src.secure_connections) && src.secure_connections.len && freq && istype(freq))
|
|
var/list/datum/radio_frequency/RF = list()
|
|
|
|
for (var/key in src.secure_connections)
|
|
if (!RF.Find(src.secure_connections["[key]"]) && istype(src.secure_connections["[key]"], /datum/radio_frequency))
|
|
RF.Add(src.secure_connections["[key]"])
|
|
|
|
// Secure channel match. Easy.
|
|
if (RF.Find(freq) && freq.devices.Find(src))
|
|
//DEBUG_MESSAGE("Match found for transmission from [R] at [log_loc(R)] (list/devices match)")
|
|
return 1
|
|
|
|
// Sender didn't use a secure channel prefix, giving us the 145.9 radio frequency datum.
|
|
// The devices list is useless here, but we can still receive the message if one of our
|
|
// secure channels happens to have the same frequency as the sender's radio.
|
|
if (src.secure_frequencies && istype(src.secure_frequencies) && src.secure_frequencies.len)
|
|
for (var/freq2 in src.secure_frequencies)
|
|
if (isnum(src.secure_frequencies["[freq2]"]) && src.secure_frequencies["[freq2]"] == R.frequency)
|
|
//DEBUG_MESSAGE("Match found for transmission from [R] at [log_loc(R)] (frequency compare)")
|
|
return 1
|
|
|
|
return 0
|
|
|
|
/obj/item/device/radio/proc/send_hear()
|
|
|
|
last_transmission = world.time
|
|
if ((src.listening && src.wires & WIRE_RECEIVE))
|
|
var/list/hear = hearers(src.speaker_range, src.loc) // changed so station bounce radios will be loud and headsets will only be heard on their tile
|
|
|
|
// modified so that a mob holding the radio is always a hearer of it
|
|
// this fixes radio problems when inside something (e.g. mulebot)
|
|
|
|
if(ismob(loc))
|
|
if(! hear.Find(loc) )
|
|
hear += loc
|
|
//modified so people in the same object as it can hear it
|
|
if(istype(loc, /obj))
|
|
for(var/mob/M in loc)
|
|
if(! hear.Find(M) )
|
|
hear += M
|
|
return hear
|
|
return
|
|
|
|
/obj/item/device/radio/proc/speech_bubble()
|
|
if ((src.listening && src.wires & WIRE_RECEIVE))
|
|
if (istype(src, /obj/item/device/radio/intercom))
|
|
UpdateOverlays(speech_bubble, "speech_bubble")
|
|
SPAWN_DBG(1.5 SECONDS)
|
|
UpdateOverlays(null, "speech_bubble")
|
|
|
|
/obj/item/device/radio/examine()
|
|
set src in view()
|
|
set category = "Local"
|
|
|
|
..()
|
|
if ((in_range(src, usr) || src.loc == usr))
|
|
if (src.b_stat)
|
|
usr.show_message("<span style=\"color:blue\">\the [src] can be attached and modified!</span>")
|
|
else
|
|
usr.show_message("<span style=\"color:blue\">\the [src] can not be modified or attached!</span>")
|
|
if (istype(src.secure_frequencies) && src.secure_frequencies.len)
|
|
var/o = "Supplementary Channels:"
|
|
for (var/sayToken in src.secure_frequencies) //Most convoluted string of the year award 2013
|
|
o += "<br>[ headset_channel_lookup["[src.secure_frequencies["[sayToken]"]]"] ? headset_channel_lookup["[src.secure_frequencies["[sayToken]"]]"] : "???" ]: \[[format_frequency(src.secure_frequencies["[sayToken]"])]] (Activator: <b>[sayToken]</b>)"
|
|
boutput(usr, o)
|
|
return
|
|
|
|
/obj/item/device/radio/attackby(obj/item/W as obj, mob/user as mob)
|
|
user.machine = src
|
|
if (!isscrewingtool(W))
|
|
return
|
|
src.b_stat = !( src.b_stat )
|
|
if (src.b_stat)
|
|
user.show_message("<span style=\"color:blue\">The radio can now be attached and modified!</span>")
|
|
else
|
|
user.show_message("<span style=\"color:blue\">The radio can no longer be modified or attached!</span>")
|
|
if (isliving(src.loc))
|
|
var/mob/living/M = src.loc
|
|
src.attack_self(M)
|
|
//Foreach goto(83)
|
|
src.add_fingerprint(user)
|
|
return
|
|
|
|
/obj/item/device/radio/emp_act()
|
|
broadcasting = 0
|
|
listening = 0
|
|
return
|
|
|
|
/obj/item/radiojammer
|
|
name = "signal jammer"
|
|
desc = "An illegal device used to jam radio signals, preventing broadcast or transmission."
|
|
icon = 'icons/obj/objects.dmi'
|
|
icon_state = "shieldoff"
|
|
w_class = 1
|
|
var/active = 0
|
|
is_syndicate = 1
|
|
mats = 10
|
|
|
|
attack_self(var/mob/user as mob)
|
|
if (!(radio_controller && istype(radio_controller)))
|
|
return
|
|
|
|
src.active = !src.active
|
|
if (src.active)
|
|
boutput(user, "You activate [src].")
|
|
src.icon_state = "shieldon"
|
|
if (!radio_controller.active_jammers.Find(src))
|
|
radio_controller.active_jammers.Add(src)
|
|
else
|
|
boutput(user, "You shut off [src].")
|
|
icon_state = "shieldoff"
|
|
if (radio_controller.active_jammers.Find(src))
|
|
radio_controller.active_jammers.Remove(src)
|
|
|
|
disposing()
|
|
if (radio_controller && istype(radio_controller) && radio_controller.active_jammers.Find(src))
|
|
radio_controller.active_jammers.Remove(src)
|
|
..()
|
|
|
|
var/global/list/tracking_beacons = list() // things were looping through world to find these so let's just stop doing that and have this shit add itself to a global list instead maybe
|
|
|
|
/obj/item/device/radio/beacon
|
|
name = "tracking beacon"
|
|
icon_state = "beacon"
|
|
item_state = "signaler"
|
|
desc = "A small beacon that is tracked by the Teleporter Computer, allowing things to be sent to its general location."
|
|
burn_possible = 0
|
|
|
|
/obj/item/device/radio/beacon/New()
|
|
..()
|
|
SPAWN_DBG(0)
|
|
if (!islist(tracking_beacons))
|
|
tracking_beacons = list()
|
|
tracking_beacons.Add(src)
|
|
|
|
/obj/item/device/radio/beacon/disposing()
|
|
if (islist(tracking_beacons))
|
|
tracking_beacons.Remove(src)
|
|
..()
|
|
|
|
/obj/item/device/radio/beacon/hear_talk()
|
|
return
|
|
|
|
/obj/item/device/radio/beacon/send_hear()
|
|
return null
|
|
|
|
/obj/item/device/radio/electropack
|
|
name = "\improper Electropack"
|
|
icon_state = "electropack0"
|
|
var/code = 2.0
|
|
var/on = 0.0
|
|
// var/e_pads = 0.0
|
|
frequency = 1451
|
|
w_class = 5.0
|
|
flags = FPRINT | TABLEPASS | ONBACK | CONDUCT
|
|
item_state = "electropack"
|
|
desc = "A device that, when signaled on the correct frequency, causes a disabling electric shock to be sent to the animal (or human) wearing it."
|
|
cant_self_remove = 1
|
|
|
|
/*
|
|
/obj/item/device/radio/electropack/examine()
|
|
set src in view()
|
|
set category = "Local"
|
|
|
|
..()
|
|
if ((in_range(src, usr) || src.loc == usr))
|
|
if (src.e_pads)
|
|
boutput(usr, "<span style=\"color:blue\">The electric pads are exposed!</span>")
|
|
return*/
|
|
|
|
/obj/item/device/radio/electropack/attackby(obj/item/W as obj, mob/user as mob)
|
|
if (istype(W, /obj/item/clothing/head/helmet))
|
|
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user )
|
|
W.set_loc(A)
|
|
A.part1 = W
|
|
W.layer = initial(W.layer)
|
|
user.u_equip(W)
|
|
user.put_in_hand_or_drop(A)
|
|
W.master = A
|
|
src.master = A
|
|
src.layer = initial(src.layer)
|
|
user.u_equip(src)
|
|
src.set_loc(A)
|
|
A.part2 = src
|
|
src.add_fingerprint(user)
|
|
return
|
|
|
|
/obj/item/device/radio/electropack/Topic(href, href_list)
|
|
//..()
|
|
if (usr.stat || usr.restrained())
|
|
return
|
|
if (src in usr || (src.master && src.master in usr) || (in_range(src, usr) && istype(src.loc, /turf)))
|
|
usr.machine = src
|
|
if (href_list["freq"])
|
|
var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
|
|
set_frequency(new_frequency)
|
|
else
|
|
if (href_list["code"])
|
|
src.code += text2num(href_list["code"])
|
|
src.code = round(src.code)
|
|
src.code = min(100, src.code)
|
|
src.code = max(1, src.code)
|
|
else
|
|
if (href_list["power"])
|
|
src.on = !( src.on )
|
|
src.icon_state = text("electropack[]", src.on)
|
|
if (!( src.master ))
|
|
if (ismob(src.loc))
|
|
attack_self(src.loc)
|
|
else
|
|
for(var/mob/M in viewers(1, src))
|
|
if (M.client)
|
|
src.attack_self(M)
|
|
else
|
|
if (ismob(src.master.loc))
|
|
src.attack_self(src.master.loc)
|
|
else
|
|
for(var/mob/M in viewers(1, src.master))
|
|
if (M.client)
|
|
src.attack_self(M)
|
|
else
|
|
usr.Browse(null, WINDOW_OPTIONS)
|
|
return
|
|
return
|
|
/*
|
|
/obj/item/device/radio/electropack/accept_rad(obj/item/device/radio/signaler/R as obj, message)
|
|
|
|
if ((istype(R, /obj/item/device/radio/signaler) && R.frequency == src.frequency && R.code == src.code))
|
|
return 1
|
|
else
|
|
return null
|
|
return
|
|
*/
|
|
/obj/item/device/radio/electropack/receive_signal(datum/signal/signal)
|
|
if (!signal || !signal.data || ("[signal.data["code"]]" != "[code]"))//(signal.encryption != code))
|
|
return
|
|
|
|
if (ismob(src.loc) && src.on)
|
|
var/mob/M = src.loc
|
|
if (src == M.back)
|
|
M.show_message("<span style=\"color:red\"><B>You feel a sharp shock!</B></span>")
|
|
logTheThing("signalers", usr, M, "signalled an electropack worn by %target% at [log_loc(M)].") // Added (Convair880).
|
|
if(ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/revolution))
|
|
if(M.mind in ticker.mode:revolutionaries && !M.mind in ticker.mode:head_revolutionaries && prob(20))
|
|
ticker.mode:remove_revolutionary(M.mind)
|
|
|
|
#ifdef USE_STAMINA_DISORIENT
|
|
M.do_disorient(200, weakened = 100, disorient = 60, remove_stamina_below_zero = 0)
|
|
#else
|
|
M.changeStatus("weakened", 10 SECONDS)
|
|
#endif
|
|
|
|
if ((src.master && src.wires & WIRE_SIGNAL))
|
|
src.master.receive_signal()
|
|
|
|
return
|
|
|
|
/obj/item/device/radio/electropack/attack_self(mob/user as mob, flag1)
|
|
|
|
if (!( ishuman(user) ))
|
|
return
|
|
user.machine = src
|
|
var/dat = {"<TT>
|
|
<a href='?src=\ref[src];power=1'>Turn [src.on ? "Off" : "On"]</a><br>
|
|
<B>Frequency/Code</B> for electropack:<br>
|
|
Frequency:
|
|
<a href='?src=\ref[src];freq=-10'>-</a>
|
|
<a href='?src=\ref[src];freq=-2'>-</a> [format_frequency(src.frequency)]
|
|
<a href='?src=\ref[src];freq=2'>+</a>
|
|
<a href='?src=\ref[src];freq=10'>+</a><br>
|
|
|
|
Code:
|
|
<a href='?src=\ref[src];code=-5'>-</a>
|
|
<a href='?src=\ref[src];code=-1'>-</a> [src.code]
|
|
<a href='?src=\ref[src];code=1'>+</a>
|
|
<a href='?src=\ref[src];code=5'>+</a><br>
|
|
</TT>"}
|
|
user.Browse(dat, WINDOW_OPTIONS)
|
|
onclose(user, "radio")
|
|
return
|
|
|
|
|
|
|
|
// ****************************************************
|
|
|
|
|
|
|
|
|
|
/obj/item/device/radio/signaler
|
|
name = "\improper Remote Signaling Device"
|
|
icon_state = "signaller"
|
|
item_state = "signaler"
|
|
var/code = 30.0
|
|
w_class = 1.0
|
|
frequency = 1457
|
|
var/delay = 0
|
|
var/airlock_wire = null
|
|
desc = "A device used to send a coded signal over a specified frequency, with the effect depending on the device that recieves the signal."
|
|
|
|
/*
|
|
/obj/item/device/radio/signaler/examine()
|
|
set src in view()
|
|
set category = "Local"
|
|
..()
|
|
if ((in_range(src, usr) || src.loc == usr))
|
|
if (src.b_stat)
|
|
usr.show_message("<span style=\"color:blue\">The signaler can be attached and modified!</span>")
|
|
else
|
|
usr.show_message("<span style=\"color:blue\">The signaler can not be modified or attached!</span>")
|
|
return
|
|
*/
|
|
|
|
/obj/item/device/radio/signaler/attack_self(mob/user as mob, flag1)
|
|
user.machine = src
|
|
var/t1
|
|
if ((src.b_stat && !( flag1 )))
|
|
t1 = text("-------<br><br>Green Wire: []<br><br>Red Wire: []<br><br>Blue Wire: []<br><br>", (src.wires & WIRE_TRANSMIT ? text("<a href='?src=\ref[];wires=[WIRE_TRANSMIT]'>Cut Wire</a>", src) : text("<a href='?src=\ref[];wires=[WIRE_TRANSMIT]'>Mend Wire</a>", src)), (src.wires & WIRE_RECEIVE ? text("<a href='?src=\ref[];wires=[WIRE_RECEIVE]'>Cut Wire</a>", src) : text("<a href='?src=\ref[];wires=[WIRE_RECEIVE]'>Mend Wire</a>", src)), (src.wires & WIRE_SIGNAL ? text("<a href='?src=\ref[];wires=[WIRE_SIGNAL]'>Cut Wire</a>", src) : text("<a href='?src=\ref[];wires=[WIRE_SIGNAL]'>Mend Wire</a>", src)))
|
|
else
|
|
t1 = "-------"
|
|
var/dat = {"
|
|
<TT>
|
|
Speaker: [src.listening ? "<a href='?src=\ref[src];listen=0'>Engaged</a>" : "<a href='?src=\ref[src];listen=1'>Disengaged</a>"]<br>
|
|
<a href='?src=\ref[src];send=1'>Send Signal</a><br>
|
|
<B>Frequency/Code</B> for signaler:<br>
|
|
Frequency:
|
|
<a href='?src=\ref[src];freq=-10'>-</a>
|
|
<a href='?src=\ref[src];freq=-2'>-</a>
|
|
[format_frequency(src.frequency)]
|
|
<a href='?src=\ref[src];freq=2'>+</a>
|
|
<a href='?src=\ref[src];freq=10'>+</a><br>
|
|
|
|
Code:
|
|
<a href='?src=\ref[src];code=-5'>-</a>
|
|
<a href='?src=\ref[src];code=-1'>-</a>
|
|
[src.code]
|
|
<a href='?src=\ref[src];code=1'>+</a>
|
|
<a href='?src=\ref[src];code=5'>+</a><br>
|
|
[t1]
|
|
</TT>"}
|
|
user.Browse(dat, WINDOW_OPTIONS)
|
|
onclose(user, "radio")
|
|
return
|
|
|
|
obj/item/device/radio/signaler/attackby(obj/item/W as obj, mob/user as mob)
|
|
if (istype(W, /obj/item/instrument/bikehorn))
|
|
var/obj/item/assembly/radio_horn/A = new /obj/item/assembly/radio_horn( user )
|
|
W.set_loc(A)
|
|
A.part2 = W
|
|
W.layer = initial(W.layer)
|
|
user.u_equip(W)
|
|
user.put_in_hand_or_drop(A)
|
|
W.master = A
|
|
src.master = A
|
|
src.layer = initial(src.layer)
|
|
user.u_equip(src)
|
|
src.set_loc(A)
|
|
A.part1 = src
|
|
src.add_fingerprint(user)
|
|
boutput(user, "You open the signaler and cram the [W.name] in there!")
|
|
else
|
|
..()
|
|
return
|
|
|
|
/obj/item/device/radio/signaler/hear_talk()
|
|
return
|
|
|
|
/obj/item/device/radio/signaler/send_hear()
|
|
return
|
|
|
|
|
|
/obj/item/device/radio/signaler/receive_signal(datum/signal/signal)
|
|
if(!signal || !signal.data || "[signal.data["code"]]" != "[code]")//(signal.encryption != code))
|
|
return
|
|
|
|
if (!( src.wires & WIRE_RECEIVE ))
|
|
return
|
|
if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires & WIRE_SIGNAL)
|
|
// boutput(world, "/obj/.../signaler/r_signal([signal]) has master = [src.master] and type [(src.master?src.master.type : "none")]")
|
|
// boutput(world, "[src.airlock_wire] - [src] - [usr] - [signal]")
|
|
var/obj/machinery/door/airlock/A = src.loc
|
|
A.pulse(src.airlock_wire)
|
|
// src.master:r_signal(signal)
|
|
if(src.master && (src.wires & WIRE_SIGNAL))
|
|
var/turf/T = get_turf(src.master)
|
|
if (src.master && istype(src.master, /obj/item/device/transfer_valve))
|
|
logTheThing("bombing", usr, null, "signalled a radio on a transfer valve at [T ? "[log_loc(T)]" : "horrible no-loc nowhere void"].")
|
|
message_admins("[key_name(usr)] signalled a radio on a transfer valve at [T ? "[log_loc(T)]" : "horrible no-loc nowhere void"].")
|
|
|
|
else if (src.master && istype(src.master, /obj/item/assembly/rad_ignite)) //Radio-detonated beaker assemblies
|
|
var/obj/item/assembly/rad_ignite/RI = src.master
|
|
logTheThing("bombing", usr, null, "signalled a radio on a radio-igniter assembly at [T ? "[log_loc(T)]" : "horrible no-loc nowhere void"]. Contents: [log_reagents(RI.part3)]")
|
|
|
|
else if(src.master && istype(src.master, /obj/item/assembly/radio_bomb)) //Radio-detonated single-tank bombs
|
|
logTheThing("bombing", usr, null, "signalled a radio on a single-tank bomb at [T ? "[log_loc(T)]" : "horrible no-loc nowhere void"].")
|
|
message_admins("[key_name(usr)] signalled a radio on a single-tank bomb at [T ? "[log_loc(T)]" : "horrible no-loc nowhere void"].")
|
|
SPAWN_DBG(0)
|
|
src.master.receive_signal(signal)
|
|
for(var/mob/O in hearers(1, src.loc))
|
|
O.show_message("[bicon(src)] *beep* *beep*", 3, "*beep* *beep*", 2)
|
|
|
|
return
|
|
|
|
/obj/item/device/radio/signaler/proc/send_signal(message="ACTIVATE")
|
|
|
|
if(last_transmission && world.time <= (last_transmission + TRANSMISSION_DELAY * 2))
|
|
return
|
|
last_transmission = world.time
|
|
|
|
if (!( src.wires & WIRE_TRANSMIT ))
|
|
return
|
|
|
|
logTheThing("signalers", !usr && src.master ? src.master.fingerprintslast : usr, null, "used remote signaller[src.master ? " (connected to [src.master.name])" : ""] at [src.master ? "[log_loc(src.master)]" : "[log_loc(src)]"]. Frequency: [format_frequency(frequency)]/[code].")
|
|
|
|
var/datum/signal/signal = get_free_signal()
|
|
signal.source = src
|
|
//signal.encryption = code
|
|
signal.data["code"] = code
|
|
signal.data["message"] = message
|
|
|
|
radio_connection.post_signal(src, signal)
|
|
|
|
return
|
|
|
|
/obj/item/device/radio/signaler/Topic(href, href_list)
|
|
//..()
|
|
if (usr.stat)
|
|
return
|
|
var/is_detonator_trigger = 0
|
|
if (src.master)
|
|
if (istype(src.master, /obj/item/assembly/detonator/) && src.master.master)
|
|
if (istype(src.master.master, /obj/machinery/portable_atmospherics/canister/) && in_range(src.master.master, usr))
|
|
is_detonator_trigger = 1
|
|
if (is_detonator_trigger || (src in usr) || (src.master && (src.master in usr)) || (in_range(src, usr) && istype(src.loc, /turf)))
|
|
usr.machine = src
|
|
if (href_list["freq"])
|
|
var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
|
|
set_frequency(new_frequency)
|
|
else if (href_list["code"])
|
|
src.code += text2num(href_list["code"])
|
|
src.code = round(src.code)
|
|
src.code = min(100, src.code)
|
|
src.code = max(1, src.code)
|
|
else if (href_list["send"])
|
|
src.send_signal("ACTIVATE")
|
|
return
|
|
else if (href_list["listen"])
|
|
src.listening = text2num(href_list["listen"])
|
|
else if (href_list["wires"])
|
|
//var/t1 = text2num(href_list["wires"])
|
|
if (!(usr.find_tool_in_hand(TOOL_SNIPPING)))
|
|
return
|
|
if ((!( src.b_stat ) && !( src.master )))
|
|
return
|
|
|
|
..()
|
|
// bet this breaks everything oops oh well
|
|
/*
|
|
if (t1 & 1)
|
|
if (src.wires & 1)
|
|
src.wires &= 65534
|
|
else
|
|
src.wires |= 1
|
|
else
|
|
if (t1 & 2)
|
|
if (src.wires & 2)
|
|
src.wires &= 65533
|
|
else
|
|
src.wires |= 2
|
|
else
|
|
if (t1 & 4)
|
|
if (src.wires & 4)
|
|
src.wires &= 65531
|
|
else
|
|
src.wires |= 4
|
|
*/
|
|
src.add_fingerprint(usr)
|
|
if (!src.master)
|
|
if (ismob(src.loc))
|
|
attack_self(src.loc)
|
|
else
|
|
for(var/mob/M in viewers(1, src))
|
|
if (M.client)
|
|
src.attack_self(M)
|
|
else
|
|
if (is_detonator_trigger)
|
|
src.attack_self(usr)
|
|
if (ismob(src.master.loc))
|
|
src.attack_self(src.master.loc)
|
|
else
|
|
for(var/mob/M in viewers(1, src.master))
|
|
if (M.client)
|
|
src.attack_self(M)
|
|
else
|
|
usr.Browse(null, WINDOW_OPTIONS)
|
|
return
|
|
return
|
|
|
|
//////////////////////////////////////////////////
|
|
/obj/item/device/radio/intercom/loudspeaker
|
|
name = "Loudspeaker Transmitter"
|
|
icon = 'icons/obj/loudspeakers.dmi'
|
|
icon_state = "transmitter"
|
|
anchored = 1.0
|
|
speaker_range = 0
|
|
mats = 0
|
|
device_color = RADIOC_INTERCOM
|
|
//Best I can figure, you need broadcasting and listening to both be TRUE for it to make a signal and send the words spoken next to it. Why? Fuck whoever named these, that's why.
|
|
broadcasting = 0
|
|
listening = 0 //maybe this doesn't need to be on. It shouldn't be relaying signals.
|
|
density = 1
|
|
rand_pos = 0
|
|
desc = "A HAM radio transmitter...Basically...It only transmits to loudspeakers on a secure frequency."
|
|
frequency = R_FREQ_LOUDSPEAKERS
|
|
var/image/active_light = null
|
|
|
|
New()
|
|
// active_light = new ()
|
|
|
|
//Must be standing next to it to talk into it
|
|
/obj/item/device/radio/intercom/loudspeaker/hear_talk(mob/M as mob, msgs, real_name, lang_id)
|
|
if (src.broadcasting)
|
|
if (get_dist(src, M) <= 1)
|
|
talk_into(M, msgs, null, real_name, lang_id)
|
|
|
|
/obj/item/device/radio/intercom/loudspeaker/examine()
|
|
set src in view()
|
|
set category = "Local"
|
|
|
|
..()
|
|
boutput(usr, "[src] is[src.broadcasting ? " " : " not "]active!")
|
|
boutput(usr, "It is tuned to [format_frequency(src.frequency)]Hz.")
|
|
|
|
return
|
|
|
|
/obj/item/device/radio/intercom/loudspeaker/attack_self(mob/user as mob)
|
|
if (!broadcasting)
|
|
broadcasting = 1
|
|
src.icon_state = "transmitter-on"
|
|
boutput(user, "Now transmitting.")
|
|
else
|
|
broadcasting = 0
|
|
src.icon_state = "transmitter"
|
|
boutput(user, "No longer transmitting.")
|
|
|
|
/obj/item/device/radio/intercom/loudspeaker/initialize()
|
|
|
|
set_frequency(frequency)
|
|
if(src.secure_frequencies)
|
|
set_secure_frequencies()
|
|
|
|
//This is the main parent, also is the actual speakers that will be attached to the walls.
|
|
/obj/item/device/radio/intercom/loudspeaker/speaker
|
|
name = "Loudspeaker"
|
|
icon_state = "loudspeaker"
|
|
anchored = 1.0
|
|
speaker_range = 7
|
|
mats = 0
|
|
broadcasting = 1
|
|
listening = 1
|
|
device_color = RADIOC_INTERCOM
|
|
frequency = R_FREQ_LOUDSPEAKERS
|
|
rand_pos = 0
|
|
density = 0
|
|
desc = "A Loudspeaker."
|
|
|
|
north
|
|
dir = NORTH
|
|
south
|
|
dir = SOUTH
|
|
east
|
|
dir = EAST
|
|
west
|
|
dir = WEST
|
|
|
|
//You can't talk into it to send a message
|
|
/obj/item/device/radio/intercom/loudspeaker/speaker/hear_talk()
|
|
return
|
|
|
|
//listening seems to refer to the device listening to the signals, not listening to voice
|
|
|
|
/obj/item/device/radio/intercom/loudspeaker/speaker/send_hear()
|
|
var/list/hear = ..()
|
|
|
|
for (var/mob/M in hear)
|
|
|
|
flick("loudspeaker-transmitting",src)
|
|
playsound(src.loc, 'sound/misc/talk/speak_1.ogg', 50, 1)
|
|
return hear
|
|
|
|
return ..()
|
|
|
|
|
|
/obj/item/device/radio/intercom/loudspeaker/speaker/attack_hand(mob/user as mob)
|
|
return
|