initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
@@ -0,0 +1,33 @@
/obj/item/device/radio/beacon
name = "tracking beacon"
desc = "A beacon used by a teleporter."
icon_state = "beacon"
item_state = "beacon"
var/code = "electronic"
origin_tech = "bluespace=1"
dog_fashion = null
/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
return
/obj/item/device/radio/beacon/send_hear()
return null
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
set name = "Alter Beacon's Signal"
set category = "Object"
set src in usr
if ((usr.canmove && !( usr.restrained() )))
src.code = t
if (!( src.code ))
src.code = "beacon"
src.add_fingerprint(usr)
return
/*
//Probably a better way of doing this, I'm lazy.
/obj/item/device/radio/beacon/bacon/proc/digest_delay()
spawn(600)
qdel(src)*/ //Bacon beacons are no more rip in peace
@@ -0,0 +1,147 @@
/obj/item/device/electropack
name = "electropack"
desc = "Dance my monkeys! DANCE!!!"
icon = 'icons/obj/radio.dmi'
icon_state = "electropack0"
item_state = "electropack"
flags = CONDUCT
slot_flags = SLOT_BACK
w_class = 5
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
var/on = 1
var/code = 2
var/frequency = 1449
var/shock_cooldown = 0
/obj/item/device/electropack/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] hooks \himself to the electropack and spams the trigger! It looks like \he's trying to commit suicide..</span>")
return (FIRELOSS)
/obj/item/device/electropack/initialize()
if(SSradio)
SSradio.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/electropack/Destroy()
if(SSradio)
SSradio.remove_object(src, frequency)
return ..()
/obj/item/device/electropack/attack_hand(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
if(src == C.back)
user << "<span class='warning'>You need help taking this off!</span>"
return
..()
/obj/item/device/electropack/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/clothing/head/helmet))
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user )
A.icon = 'icons/obj/assemblies.dmi'
if(!user.unEquip(W))
user << "<span class='warning'>\the [W] is stuck to your hand, you cannot attach it to \the [src]!</span>"
return
W.loc = A
W.master = A
A.part1 = W
user.unEquip(src)
loc = A
master = A
A.part2 = src
user.put_in_hands(A)
A.add_fingerprint(user)
if(src.flags & NODROP)
A.flags |= NODROP
else
return ..()
/obj/item/device/electropack/Topic(href, href_list)
//..()
var/mob/living/carbon/C = usr
if(usr.stat || usr.restrained() || C.back == src)
return
if(((istype(usr, /mob/living/carbon/human) && ((!( ticker ) || (ticker && ticker.mode != "monkey")) && usr.contents.Find(src))) || (usr.contents.Find(master) || (in_range(src, usr) && istype(loc, /turf)))))
usr.set_machine(src)
if(href_list["freq"])
SSradio.remove_object(src, frequency)
frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
SSradio.add_object(src, frequency, RADIO_CHAT)
else
if(href_list["code"])
code += text2num(href_list["code"])
code = round(code)
code = min(100, code)
code = max(1, code)
else
if(href_list["power"])
on = !( on )
icon_state = "electropack[on]"
if(!( master ))
if(istype(loc, /mob))
attack_self(loc)
else
for(var/mob/M in viewers(1, src))
if(M.client)
attack_self(M)
else
if(istype(master.loc, /mob))
attack_self(master.loc)
else
for(var/mob/M in viewers(1, master))
if(M.client)
attack_self(M)
else
usr << browse(null, "window=radio")
return
return
/obj/item/device/electropack/receive_signal(datum/signal/signal)
if(!signal || signal.encryption != code)
return
if(ismob(loc) && on)
if(shock_cooldown != 0)
return
shock_cooldown = 1
spawn(100)
shock_cooldown = 0
var/mob/M = loc
step(M, pick(cardinal))
M << "<span class='danger'>You feel a sharp shock!</span>"
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, M)
s.start()
M.Weaken(5)
if(master)
master.receive_signal()
return
/obj/item/device/electropack/attack_self(mob/user)
if(!istype(user, /mob/living/carbon/human))
return
user.set_machine(src)
var/dat = {"<TT>Turned [on ? "On" : "Off"] -
<A href='?src=\ref[src];power=1'>Toggle</A><BR>
<B>Frequency/Code</B> for electropack:<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>
Code:
<A href='byond://?src=\ref[src];code=-5'>-</A>
<A href='byond://?src=\ref[src];code=-1'>-</A> [code]
<A href='byond://?src=\ref[src];code=1'>+</A>
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
return
@@ -0,0 +1,129 @@
/obj/item/device/encryptionkey/
name = "standard encryption key"
desc = "An encryption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN."
icon = 'icons/obj/radio.dmi'
icon_state = "cypherkey"
w_class = 1
origin_tech = "engineering=2;bluespace=1"
var/translate_binary = 0
var/translate_hive = 0
var/syndie = 0
var/centcom = 0
var/list/channels = list()
/obj/item/device/encryptionkey/syndicate
icon_state = "cypherkey"
channels = list("Syndicate" = 1)
origin_tech = "syndicate=1;engineering=3;bluespace=2"
syndie = 1//Signifies that it de-crypts Syndicate transmissions
/obj/item/device/encryptionkey/binary
name = "binary translator key"
desc = "An encryption key for a radio headset. To access the binary channel, use :b."
icon_state = "cypherkey"
translate_binary = 1
origin_tech = "syndicate=3;engineering=4;bluespace=3"
/obj/item/device/encryptionkey/headset_sec
name = "security radio encryption key"
desc = "An encryption key for a radio headset. To access the security channel, use :s."
icon_state = "sec_cypherkey"
channels = list("Security" = 1)
/obj/item/device/encryptionkey/headset_eng
name = "engineering radio encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e."
icon_state = "eng_cypherkey"
channels = list("Engineering" = 1)
/obj/item/device/encryptionkey/headset_rob
name = "robotics radio encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For research, use :n."
icon_state = "rob_cypherkey"
channels = list("Science" = 1, "Engineering" = 1)
/obj/item/device/encryptionkey/headset_med
name = "medical radio encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m."
icon_state = "med_cypherkey"
channels = list("Medical" = 1)
/obj/item/device/encryptionkey/headset_sci
name = "science radio encryption key"
desc = "An encryption key for a radio headset. To access the science channel, use :n."
icon_state = "sci_cypherkey"
channels = list("Science" = 1)
/obj/item/device/encryptionkey/headset_medsci
name = "medical research radio encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m. For science, use :n."
icon_state = "medsci_cypherkey"
channels = list("Science" = 1, "Medical" = 1)
/obj/item/device/encryptionkey/headset_com
name = "command radio encryption key"
desc = "An encryption key for a radio headset. To access the command channel, use :c."
icon_state = "com_cypherkey"
channels = list("Command" = 1)
/obj/item/device/encryptionkey/heads/captain
name = "\proper the captain's encryption key"
desc = "An encryption key for a radio headset. Channels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "cap_cypherkey"
channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0)
/obj/item/device/encryptionkey/heads/rd
name = "\proper the research director's encryption key"
desc = "An encryption key for a radio headset. To access the science channel, use :n. For command, use :c."
icon_state = "rd_cypherkey"
channels = list("Science" = 1, "Command" = 1)
/obj/item/device/encryptionkey/heads/hos
name = "\proper the head of security's encryption key"
desc = "An encryption key for a radio headset. To access the security channel, use :s. For command, use :c."
icon_state = "hos_cypherkey"
channels = list("Security" = 1, "Command" = 1)
/obj/item/device/encryptionkey/heads/ce
name = "\proper the chief engineer's encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For command, use :c."
icon_state = "ce_cypherkey"
channels = list("Engineering" = 1, "Command" = 1)
/obj/item/device/encryptionkey/heads/cmo
name = "\proper the chief medical officer's encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m. For command, use :c."
icon_state = "cmo_cypherkey"
channels = list("Medical" = 1, "Command" = 1)
/obj/item/device/encryptionkey/heads/hop
name = "\proper the head of personnel's encryption key"
desc = "An encryption key for a radio headset. Channels are as follows: :u - supply, :v - service, :c - command."
icon_state = "hop_cypherkey"
channels = list("Supply" = 1, "Service" = 1, "Command" = 1)
/obj/item/device/encryptionkey/headset_cargo
name = "supply radio encryption key"
desc = "An encryption key for a radio headset. To access the supply channel, use :u."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1)
/obj/item/device/encryptionkey/headset_service
name = "service radio encryption key"
desc = "An encryption key for a radio headset. To access the service channel, use :v."
icon_state = "srv_cypherkey"
channels = list("Service" = 1)
/obj/item/device/encryptionkey/headset_cent
name = "centcom radio encryption key"
desc = "An encryption key for a radio headset. To access the centcom channel, use :y."
icon_state = "cent_cypherkey"
centcom = 1
channels = list("Centcom" = 1)
/obj/item/device/encryptionkey/ai //ported from NT, this goes 'inside' the AI.
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1)
/obj/item/device/encryptionkey/secbot
channels = list("AI Private"=1,"Security"=1)
@@ -0,0 +1,290 @@
/obj/item/device/radio/headset
name = "radio headset"
desc = "An updated, modular intercom that fits over the head. Takes encryption keys. \nTo speak on the general radio frequency, use ; before speaking."
icon_state = "headset"
item_state = "headset"
materials = list(MAT_METAL=75)
subspace_transmission = 1
canhear_range = 0 // can't hear headsets from very far away
slot_flags = SLOT_EARS
var/obj/item/device/encryptionkey/keyslot2 = null
dog_fashion = null
/obj/item/device/radio/headset/New()
..()
recalculateChannels()
/obj/item/device/radio/headset/Destroy()
qdel(keyslot)
qdel(keyslot2)
keyslot = null
keyslot2 = null
return ..()
/obj/item/device/radio/headset/talk_into(mob/living/M, message, channel, list/spans)
if (!listening)
return
..()
/obj/item/device/radio/headset/receive_range(freq, level, AIuser)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.ears == src)
return ..(freq, level)
else if(AIuser)
return ..(freq, level)
return -1
/obj/item/device/radio/headset/syndicate //disguised to look like a normal headset for stealth ops
origin_tech = "syndicate=3"
/obj/item/device/radio/headset/syndicate/alt //undisguised bowman with flash protection
name = "syndicate headset"
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking."
flags = EARBANGPROTECT
origin_tech = "syndicate=3"
icon_state = "syndie_headset"
item_state = "syndie_headset"
/obj/item/device/radio/headset/syndicate/alt/leader
name = "team leader headset"
command = TRUE
/obj/item/device/radio/headset/syndicate/New()
..()
make_syndie()
/obj/item/device/radio/headset/binary
origin_tech = "syndicate=3"
/obj/item/device/radio/headset/binary/New()
..()
qdel(keyslot)
keyslot = new /obj/item/device/encryptionkey/binary
recalculateChannels()
/obj/item/device/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force. \nTo access the security channel, use :s."
icon_state = "sec_headset"
keyslot = new /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force. Protects ears from flashbangs. \nTo access the security channel, use :s."
flags = EARBANGPROTECT
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
/obj/item/device/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls. \nTo access the engineering channel, use :e. "
icon_state = "eng_headset"
keyslot = new /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists, who cannot decide between departments. \nTo access the engineering channel, use :e. For research, use :n."
icon_state = "rob_headset"
keyslot = new /obj/item/device/encryptionkey/headset_rob
/obj/item/device/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay. \nTo access the medical channel, use :m."
icon_state = "med_headset"
keyslot = new /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual. \nTo access the science channel, use :n."
icon_state = "sci_headset"
keyslot = new /obj/item/device/encryptionkey/headset_sci
/obj/item/device/radio/headset/headset_medsci
name = "medical research radio headset"
desc = "A headset that is a result of the mating between medical and science. \nTo access the medical channel, use :m. For science, use :n."
icon_state = "medsci_headset"
keyslot = new /obj/item/device/encryptionkey/headset_medsci
/obj/item/device/radio/headset/headset_com
name = "command radio headset"
desc = "A headset with a commanding channel. \nTo access the command channel, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/heads
command = TRUE
/obj/item/device/radio/headset/heads/captain
name = "\proper the captain's headset"
desc = "The headset of the king. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs. \nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/device/radio/headset/heads/rd
name = "\proper the research director's headset"
desc = "Headset of the fellow who keeps society marching towards technological singularity. \nTo access the science channel, use :n. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/hos
name = "\proper the head of security's headset"
desc = "The headset of the man in charge of keeping order and protecting the station. \nTo access the security channel, use :s. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs. \nTo access the security channel, use :s. For command, use :c."
flags = EARBANGPROTECT
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
/obj/item/device/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
desc = "The headset of the guy in charge of keeping the station powered and undamaged. \nTo access the engineering channel, use :e. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/cmo
name = "\proper the chief medical officer's headset"
desc = "The headset of the highly trained medical chief. \nTo access the medical channel, use :m. For command, use :c."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/hop
name = "\proper the head of personnel's headset"
desc = "The headset of the guy who will one day be captain. \nChannels are as follows: :u - supply, :v - service, :c - command."
icon_state = "com_headset"
keyslot = new /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and his slaves. \nTo access the supply channel, use :u."
icon_state = "cargo_headset"
keyslot = new /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners. \nTo access the supply channel, use :u."
icon_state = "mine_headset"
/obj/item/device/radio/headset/headset_srv
name = "service radio headset"
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean. \nTo access the service channel, use :v."
icon_state = "srv_headset"
keyslot = new /obj/item/device/encryptionkey/headset_service
/obj/item/device/radio/headset/headset_cent
name = "\improper Centcom headset"
desc = "A headset used by the upper echelons of Nanotrasen. \nTo access the centcom channel, use :y."
icon_state = "cent_headset"
keyslot = new /obj/item/device/encryptionkey/headset_com
keyslot2 = new /obj/item/device/encryptionkey/headset_cent
/obj/item/device/radio/headset/headset_cent/commander
keyslot = new /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/headset_cent/alt
name = "\improper Centcom bowman headset"
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs. \nTo access the centcom channel, use :y."
flags = EARBANGPROTECT
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
/obj/item/device/radio/headset/ai
name = "\proper Integrated Subspace Transceiver "
keyslot2 = new /obj/item/device/encryptionkey/ai
/obj/item/device/radio/headset/ai/receive_range(freq, level)
return ..(freq, level, 1)
/obj/item/device/radio/headset/attackby(obj/item/weapon/W, mob/user, params)
user.set_machine(src)
if(istype(W, /obj/item/weapon/screwdriver))
if(keyslot || keyslot2)
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.loc = T
keyslot = null
if(keyslot2)
var/turf/T = get_turf(user)
if(T)
keyslot2.loc = T
keyslot2 = null
recalculateChannels()
user << "<span class='notice'>You pop out the encryption keys in the headset.</span>"
else
user << "<span class='warning'>This headset doesn't have any unique encryption keys! How useless...</span>"
else if(istype(W, /obj/item/device/encryptionkey/))
if(keyslot && keyslot2)
user << "<span class='warning'>The headset can't hold another key!</span>"
return
if(!keyslot)
if(!user.unEquip(W))
return
W.loc = src
keyslot = W
else
if(!user.unEquip(W))
return
W.loc = src
keyslot2 = W
recalculateChannels()
else
return ..()
/obj/item/device/radio/headset/recalculateChannels()
..()
if(keyslot2)
for(var/ch_name in keyslot2.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot2.channels[ch_name]
if(keyslot2.translate_binary)
src.translate_binary = 1
if(keyslot2.translate_hive)
src.translate_hive = 1
if(keyslot2.syndie)
src.syndie = 1
if (keyslot2.centcom)
centcom = 1
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, radiochannels[ch_name])
return
@@ -0,0 +1,71 @@
/obj/item/device/radio/intercom
name = "station intercom"
desc = "Talk through this."
icon_state = "intercom"
anchored = 1
w_class = 4
canhear_range = 2
var/number = 0
var/anyai = 1
var/mob/living/silicon/ai/ai = list()
var/last_tick //used to delay the powercheck
dog_fashion = null
/obj/item/device/radio/intercom/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/device/radio/intercom/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/device/radio/intercom/attack_ai(mob/user)
interact(user)
/obj/item/device/radio/intercom/attack_hand(mob/user)
interact(user)
/obj/item/device/radio/intercom/interact(mob/user)
..()
ui_interact(user, state = default_state)
/obj/item/device/radio/intercom/receive_range(freq, level)
if(!on)
return -1
if(wires.is_cut(WIRE_RX))
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if(isnull(position) || !(position.z in level))
return -1
if(!src.listening)
return -1
if(freq == SYND_FREQ)
if(!(src.syndie))
return -1//Prevents broadcast of messages over devices lacking the encryption
return canhear_range
/obj/item/device/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
if(!anyai && !(speaker in ai))
return
..()
/obj/item/device/radio/intercom/process()
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
last_tick = world.timeofday
var/area/A = get_area_master(src)
if(!A || emped)
on = 0
else
on = A.powered(EQUIP) // set "on" to the power status
if(!on)
icon_state = "intercom-p"
else
icon_state = "intercom"
/obj/item/device/radio/intercom/add_blood(list/blood_dna)
return 0
@@ -0,0 +1,591 @@
/obj/item/device/radio
icon = 'icons/obj/radio.dmi'
name = "station bounced radio"
suffix = "\[3\]"
icon_state = "walkietalkie"
item_state = "walkietalkie"
dog_fashion = /datum/dog_fashion/back
var/on = 1 // 0 for off
var/last_transmission
var/frequency = 1459 //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/list/secure_radio_connections
var/prison_radio = 0
var/b_stat = 0
var/broadcasting = 0
var/listening = 1
var/translate_binary = 0
var/translate_hive = 0
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/obj/item/device/encryptionkey/keyslot //To allow the radio to accept encryption keys.
var/subspace_switchable = 0
var/subspace_transmission = 0
var/syndie = 0//Holder to see if it's a syndicate encrpyed radio
var/centcom = 0//Bleh, more dirty booleans
var/freqlock = 0 //Frequency lock to stop the user from untuning specialist radios.
var/emped = 0 //Highjacked to track the number of consecutive EMPs on the radio, allowing consecutive EMP's to stack properly.
// "Example" = FREQ_LISTENING|FREQ_BROADCASTING
flags = CONDUCT | HEAR
slot_flags = SLOT_BELT
languages_spoken = HUMAN | ROBOT
languages_understood = HUMAN | ROBOT
throw_speed = 3
throw_range = 7
w_class = 2
materials = list(MAT_METAL=75, MAT_GLASS=25)
var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio
var/const/FREQ_LISTENING = 1
//FREQ_BROADCASTING = 2
var/command = FALSE //If we are speaking into a command headset, our text can be BOLD
var/use_command = FALSE
/obj/item/device/radio/proc/set_frequency(new_frequency)
remove_radio(src, frequency)
frequency = add_radio(src, new_frequency)
/obj/item/device/radio/New()
wires = new /datum/wires/radio(src)
if(prison_radio)
wires.cut(WIRE_TX) // OH GOD WHY
secure_radio_connections = new
..()
if(SSradio)
initialize()
/obj/item/device/radio/proc/recalculateChannels()
channels = list()
translate_binary = 0
translate_hive = 0
syndie = 0
centcom = 0
if(keyslot)
for(var/ch_name in keyslot.channels)
if(ch_name in src.channels)
continue
channels += ch_name
channels[ch_name] = keyslot.channels[ch_name]
if(keyslot.translate_binary)
translate_binary = 1
if(keyslot.translate_hive)
translate_hive = 1
if(keyslot.syndie)
syndie = 1
if(keyslot.centcom)
centcom = 1
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, radiochannels[ch_name])
/obj/item/device/radio/proc/make_syndie() // Turns normal radios into Syndicate radios!
qdel(keyslot)
keyslot = new /obj/item/device/encryptionkey/syndicate
syndie = 1
recalculateChannels()
/obj/item/device/radio/Destroy()
qdel(wires)
wires = null
remove_radio_all(src) //Just to be sure
patch_link = null
keyslot = null
return ..()
/obj/item/device/radio/initialize()
frequency = sanitize_frequency(frequency, freerange)
set_frequency(frequency)
for(var/ch_name in channels)
secure_radio_connections[ch_name] = add_radio(src, radiochannels[ch_name])
/obj/item/device/radio/interact(mob/user)
if (..())
return
if(b_stat && !istype(user, /mob/living/silicon/ai))
wires.interact(user)
else
ui_interact(user)
/obj/item/device/radio/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = inventory_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio", name, 370, 220 + channels.len * 22, master_ui, state)
ui.open()
/obj/item/device/radio/ui_data(mob/user)
var/list/data = list()
data["broadcasting"] = broadcasting
data["listening"] = listening
data["frequency"] = frequency
data["minFrequency"] = freerange ? MIN_FREE_FREQ : MIN_FREQ
data["maxFrequency"] = freerange ? MAX_FREE_FREQ : MAX_FREQ
data["freqlock"] = freqlock
data["channels"] = list()
for(var/channel in channels)
data["channels"][channel] = channels[channel] & FREQ_LISTENING
data["command"] = command
data["useCommand"] = use_command
data["subspace"] = subspace_transmission
data["subspaceSwitchable"] = subspace_switchable
data["headset"] = istype(src, /obj/item/device/radio/headset)
return data
/obj/item/device/radio/ui_act(action, params, datum/tgui/ui)
if(..())
return
switch(action)
if("frequency")
if(freqlock)
return
var/tune = params["tune"]
var/adjust = text2num(params["adjust"])
if(tune == "input")
var/min = format_frequency(freerange ? MIN_FREE_FREQ : MIN_FREQ)
var/max = format_frequency(freerange ? MAX_FREE_FREQ : MAX_FREQ)
tune = input("Tune frequency ([min]-[max]):", name, format_frequency(frequency)) as null|num
if(!isnull(tune) && !..())
. = TRUE
else if(adjust)
tune = frequency + adjust * 10
. = TRUE
else if(text2num(tune) != null)
tune = tune * 10
. = TRUE
if(.)
frequency = sanitize_frequency(tune, freerange)
set_frequency(frequency)
if(frequency == traitor_frequency && hidden_uplink)
hidden_uplink.interact(usr)
ui.close()
if("listen")
listening = !listening
. = TRUE
if("broadcast")
broadcasting = !broadcasting
. = TRUE
if("channel")
var/channel = params["channel"]
if(!(channel in channels))
return
if(channels[channel] & FREQ_LISTENING)
channels[channel] &= ~FREQ_LISTENING
else
channels[channel] |= FREQ_LISTENING
. = TRUE
if("command")
use_command = !use_command
. = TRUE
if("subspace")
if(subspace_switchable)
subspace_transmission = !subspace_transmission
if(!subspace_transmission)
channels = list()
else
recalculateChannels()
. = TRUE
/obj/item/device/radio/talk_into(atom/movable/M, message, channel, list/spans)
if(!on) return // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
if(!M || !message) return
if(wires.is_cut(WIRE_TX))
return
if(!M.IsVocal())
return
if(use_command)
spans |= SPAN_COMMAND
/* 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.
*/
/*
be prepared to disregard any comments in all of tcomms code. i tried my best to keep them somewhat up-to-date, but eh
*/
//get the frequency you buttface. radios no longer use the SSradio. confusing for future generations, convenient for me.
var/freq
if(channel && channels && channels.len > 0)
if(channel == "department")
channel = channels[1]
freq = secure_radio_connections[channel]
if (!channels[channel]) // if the channel is turned off, don't broadcast
return
else
freq = frequency
channel = null
var/freqnum = text2num(freq) //Why should we call text2num three times when we can just do it here?
var/turf/position = get_turf(src)
//#### Tagging the signal with all appropriate identity values ####//
// ||-- The mob's name identity --||
var/real_name = M.name // mob's real name
var/mobkey = "none" // player key associated with mob
var/voicemask = 0 // the speaker is wearing a voice mask
var/voice = M.GetVoice() // Why reinvent the wheel when there is a proc that does nice things already
if(ismob(M))
var/mob/speaker = M
real_name = speaker.real_name
if(speaker.client)
mobkey = speaker.key // assign the mob's key
var/jobname // the mob's "job"
// --- Human: use their job as seen on the crew manifest - makes it unneeded to carry an ID for an AI to see their job
if(ishuman(M))
var/datum/data/record/findjob = find_record("name", voice, data_core.general)
if(voice != real_name)
voicemask = 1
if(findjob)
jobname = findjob.fields["rank"]
else
jobname = "Unknown"
// --- Carbon Nonhuman ---
else if(iscarbon(M)) // Nonhuman carbon mob
jobname = "No id"
// --- AI ---
else if(isAI(M))
jobname = "AI"
// --- Cyborg ---
else if(isrobot(M))
var/mob/living/silicon/robot/B = M
jobname = "[B.designation] Cyborg"
// --- Personal AI (pAI) ---
else if(istype(M, /mob/living/silicon/pai))
jobname = "Personal AI"
// --- Cold, emotionless machines. ---
else if(isobj(M))
jobname = "Machine"
// --- Unidentifiable mob ---
else
jobname = "Unknown"
/* ###### Centcom channel bypasses all comms relays. ###### */
if (freqnum == CENTCOM_FREQ && centcom)
var/datum/signal/signal = new
signal.transmission_method = 2
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" = voice, // the mob's voice name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
"compression" = 0, // uncompressed radio signal
"message" = message, // the actual sent message
"radio" = src, // stores the radio used for transmission
"slow" = 0,
"traffic" = 0,
"type" = 0,
"server" = null,
"reject" = 0,
"level" = 0,
"languages" = languages_spoken,
"spans" = spans,
"verb_say" = M.verb_say,
"verb_ask" = M.verb_ask,
"verb_exclaim" = M.verb_exclaim,
"verb_yell" = M.verb_yell
)
signal.frequency = freqnum // Quick frequency set
Broadcast_Message(M, voicemask,
src, message, voice, jobname, real_name,
5, signal.data["compression"], list(position.z, 0), freq, spans,
verb_say, verb_ask, verb_exclaim, verb_yell)
return
/* ###### 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" = voice, // the mob's voice name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"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(35,65), // compressed radio signal
"message" = message, // the actual sent message
"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
"languages" = M.languages_spoken, //The languages M is talking in.
"spans" = spans, //the span classes of this message.
"verb_say" = M.verb_say, //the verb used when talking normally
"verb_ask" = M.verb_ask, //the verb used when asking
"verb_exclaim" = M.verb_exclaim, //the verb used when exclaiming
"verb_yell" = M.verb_yell //the verb used when yelling
)
signal.frequency = freq
//#### 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
/* ###### Intercoms and station-bounced radios ###### */
var/filter_type = 2
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" = voice, // the mob's voice name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
"compression" = 0, // uncompressed radio signal
"message" = message, // the actual sent message
"radio" = src, // stores the radio used for transmission
"slow" = 0,
"traffic" = 0,
"type" = 0,
"server" = null,
"reject" = 0,
"level" = position.z,
"languages" = languages_spoken,
"spans" = spans,
"verb_say" = M.verb_say,
"verb_ask" = M.verb_ask,
"verb_exclaim" = M.verb_exclaim,
"verb_yell" = M.verb_yell
)
signal.frequency = freqnum // Quick frequency set
for(var/obj/machinery/telecomms/receiver/R in telecomms_list)
R.receive_signal(signal)
spawn(20) // wait a little...
if(signal.data["done"] && position.z in signal.data["level"])
// we're done here.
return
// 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:
Broadcast_Message(M, voicemask,
src, message, voice, jobname, real_name,
filter_type, signal.data["compression"], list(position.z), freq, spans,
verb_say, verb_ask, verb_exclaim, verb_yell)
/obj/item/device/radio/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
if(radio_freq)
return
if(broadcasting)
if(get_dist(src, speaker) <= canhear_range)
talk_into(speaker, raw_message, , spans)
/*
/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.is_cut(WIRE_RX))
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 == SYND_FREQ)
if(!(src.syndie)) //Checks to see if it's allowed on that frequency, based on the encryption keys
return -1
if(freq == CENTCOM_FREQ)
if (!(src.centcom))
return -1
if (!on)
return -1
if (!freq) //received on main frequency
if (!listening)
return -1
else
var/accept = (freq==frequency && listening)
if (!accept)
for(var/ch_name in channels)
if(channels[ch_name] & FREQ_LISTENING)
if(radiochannels[ch_name] == text2num(freq) || syndie) //the radiochannels list is located in communications.dm
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_hearers_in_view(canhear_range, src)
/obj/item/device/radio/examine(mob/user)
..()
if (b_stat)
user << "<span class='notice'>[name] can be attached and modified.</span>"
else
user << "<span class='notice'>[name] can not be modified or attached.</span>"
/obj/item/device/radio/attackby(obj/item/weapon/W, mob/user, params)
add_fingerprint(user)
if(istype(W, /obj/item/weapon/screwdriver))
b_stat = !b_stat
if(b_stat)
user << "<span class='notice'>The radio can now be attached and modified!</span>"
else
user << "<span class='notice'>The radio can no longer be modified or attached!</span>"
else
return ..()
/obj/item/device/radio/emp_act(severity)
emped++ //There's been an EMP; better count it
var/curremp = emped //Remember which EMP this was
if (listening && ismob(loc)) // if the radio is turned on and on someone's person they notice
loc << "<span class='warning'>\The [src] overloads.</span>"
broadcasting = 0
listening = 0
for (var/ch_name in channels)
channels[ch_name] = 0
on = 0
spawn(200)
if(emped == curremp) //Don't fix it if it's been EMP'd again
emped = 0
if (!istype(src, /obj/item/device/radio/intercom)) // intercoms will turn back on on their own
on = 1
..()
///////////////////////////////
//////////Borg Radios//////////
///////////////////////////////
//Giving borgs their own radio to have some more room to work with -Sieve
/obj/item/device/radio/borg
name = "cyborg radio"
subspace_switchable = 1
dog_fashion = null
/obj/item/device/radio/borg/syndicate
syndie = 1
keyslot = new /obj/item/device/encryptionkey/syndicate
/obj/item/device/radio/borg/syndicate/New()
..()
set_frequency(SYND_FREQ)
/obj/item/device/radio/borg/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/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.loc = T
keyslot = null
recalculateChannels()
user << "<span class='notice'>You pop out the encryption key in the radio.</span>"
else
user << "<span class='warning'>This radio doesn't have any encryption keys!</span>"
else if(istype(W, /obj/item/device/encryptionkey/))
if(keyslot)
user << "<span class='warning'>The radio can't hold another key!</span>"
return
if(!keyslot)
if(!user.unEquip(W))
return
W.loc = src
keyslot = W
recalculateChannels()
/obj/item/device/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
listening = 0 // And it's nice to have a subtype too for future features.
dog_fashion = /datum/dog_fashion/back