Huge fukken commit. Very game-changing new feature has been added but it isn't actually available to players yet.

Spess Networking Technology:

    ▪ The machines are located in Centcom near the cargo shuttle.
    ▪ A new admin debug verb "Change Radio Type". Using this will toggle between old (current) radio code and the new radio code. ADMINS: I recommend only doing this if Doohl (me) is around to take note of anything that happens.
    ▪ The whole thing works, in theory, but hasn't been stress-tested with the usual 60+ players. I will write up a Tgstation Wiki article and/or explain what some of the stuff does in IRC or ingame.


One last thing to point out: this is a PROTOTYPE. I have tested it myself and optimized the code very well. In theory, this new radio system is significantly less laggy AND has many more features. However, because of it's a prototype, it can at any time destroy the server. The reason I am committing this and not updating the changelog is because it's not an actual feature YET. I want to stress test this on the servers to see how it fairs, then add some more stuff to it like the ability to link machines and repair networks.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2807 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
vageyenaman@gmail.com
2011-12-25 07:10:12 +00:00
parent 62ef416afd
commit e7c27d1299
17 changed files with 4438 additions and 3071 deletions

View File

@@ -115,4 +115,58 @@
var/dy = T.y - centerturf.y
if(dx*dx + dy*dy <= rsq)
turfs += T
return turfs
return turfs
/proc/get_mobs_in_view(var/R, var/atom/source)
// Returns a list of mobs in range of R from source. Used in radio and say code.
var/turf/T = get_turf(source)
var/list/hear = hearers(R, T)
var/list/V = view(R, T)
// Search for closets:
for(var/obj/structure/closet/C in V)
for(var/mob/M in C.contents)
if(M.client)
hear += M
// Cryos:
for(var/obj/machinery/atmospherics/unary/cryo_cell/C in V)
if(C.occupant)
if(C.occupant.client)
hear += C.occupant
// Intelicards
for(var/obj/item/device/aicard/C in V)
for(var/mob/living/silicon/ai/M in C)
if(M.client)
hear += M
// Brains/MMIs/pAIs
for(var/mob/living/carbon/brain/C in world)
if(get_turf(C) in V)
hear += C
for(var/mob/living/silicon/pai/C in world)
if(get_turf(C) in V)
hear += C
// Personal AIs
for(var/obj/item/device/paicard/C in V)
if(C.pai)
if(C.pai.client)
hear += C.pai
// Exosuits
for(var/obj/mecha/C in V)
if(C.occupant)
if(C.occupant.client)
hear += C.occupant
// Disposal Machines
for(var/obj/machinery/disposal/C in V)
for(var/mob/M in C.contents)
if(M.client)
hear += M
return hear

View File

@@ -271,6 +271,7 @@ datum/signal
transmission_method = model.transmission_method
data = model.data
encryption = model.encryption
frequency = model.frequency
proc/debug_print()
if (source)

View File

@@ -157,6 +157,14 @@
name = "Circuit board (Outpost Status Display)"
build_path = "/obj/machinery/computer/security/mining"
origin_tech = "programming=2"
/obj/item/weapon/circuitboard/comm_monitor
name = "Circuit board (Telecommunications Monitor)"
build_path = "/obj/machinery/computer/telecomms/monitor"
origin_tech = "programming=3"
/obj/item/weapon/circuitboard/comm_server
name = "Circuit board (Telecommunications Server Monitor)"
build_path = "/obj/machinery/computer/telecomms/server"
origin_tech = "programming=3"
/obj/item/weapon/circuitboard/curefab
name = "Circuit board (Cure fab)"

View File

@@ -0,0 +1,301 @@
/*
The broadcaster sends processed messages to all radio devices in the game. They
do not have to be headsets; intercoms and station-bounced radios suffice.
They receive their message from a server after the message has been logged.
*/
/obj/machinery/telecomms/broadcaster
name = "subspace broadcaster"
icon = 'stationobjs.dmi'
icon_state = "broadcaster"
desc = "A dish-shaped machine used to broadcast processed subspace signals."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 25
machinetype = 5
receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
if(signal.data["message"])
/* ###### Broadcast a message using signal.data ###### */
Broadcast_Message(signal.data["connection"], signal.data["mob"],
signal.data["vmask"], signal.data["vmessage"],
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"])
signal.data["done"] = 1 // mark the signal as being broadcasted
/* --- Do a snazzy animation! --- */
flick("broadcaster_send", src)
/**
Here is the big, bad function that broadcasts a message given the appropriate
parameters.
@param connection:
The datum generated in radio.dm, stored in signal.data["connection"].
@param M:
Reference to the mob/speaker, stored in signal.data["mob"]
@param vmask:
Boolean value if the mob is "hiding" its identity via voice mask, stored in
signal.data["vmask"]
@param vmessage:
If specified, will display this as the message; such as "chimpering"
for monkies if the mob is not understood. Stored in signal.data["vmessage"].
@param radio:
Reference to the radio broadcasting the message, stored in signal.data["radio"]
@param message:
The actual string message to display to mobs who understood mob M. Stored in
signal.data["message"]
@param name:
The name to display when a mob receives the message. signal.data["name"]
@param job:
The name job to display for the AI when it receives the message. signal.data["job"]
@param realname:
The "real" name associated with the mob. signal.data["realname"]
@param vname:
If specified, will use this name when mob M is not understood. signal.data["vname"]
@param filtertype:
If specified:
1 -- Will only broadcast to intercoms
2 -- Will only broadcast to intercoms and station-bounced radios
**/
/proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M,
var/vmask, var/vmessage, var/obj/item/device/radio/radio,
var/message, var/name, var/job, var/realname, var/vname,
var/filtertype)
/* ###### Prepare the radio connection ###### */
var/display_freq = connection.frequency
var/list/receive = list()
// --- Broadcast only to intercom devices ---
if(filtertype == 1)
for (var/obj/item/device/radio/intercom/R in connection.devices["[RADIO_CHAT]"])
receive |= R.send_hear(display_freq)
// --- Broadcast only to intercoms and station-bounced radios ---
else if(filtertype == 2)
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"])
if(istype(R, /obj/item/device/radio/headset))
continue
receive |= R.send_hear(display_freq)
// --- Broadcast to ALL radio devices ---
else
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"])
receive |= R.send_hear(display_freq)
/* ###### Organize the receivers into categories for displaying the message ###### */
// Understood the message:
var/list/heard_masked = list() // masked name or no real name
var/list/heard_normal = list() // normal message
// Did not understand the message:
var/list/heard_voice = list() // voice message (ie "chimpers")
var/list/heard_garbled = list() // garbled message (ie "f*c* **u, **i*er!")
for (var/mob/R in receive)
/* --- Loop through the receivers and categorize them --- */
if (R.client && R.client.STFU_radio) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
continue
// --- Can understand the speech ---
if (R.say_understands(M))
// - Not human or wearing a voice mask -
if (!ishuman(M) || vmask)
heard_masked += R
// - Human and not wearing voice mask -
else
heard_normal += R
// --- Can't understand the speech ---
else
// - The speaker has a prespecified "voice message" to display if not understood -
if (vmessage)
heard_voice += R
// - Just display a garbled message -
else
heard_garbled += R
/* ###### Begin formatting and sending the message ###### */
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled))
/* --- Some miscellaneous variables to format the string output --- */
var/part_a = "<span class='radio'><span class='name'>" // goes in the actual output
var/freq_text // the name of the channel
// --- Set the name of the channel ---
switch(display_freq)
if(SYND_FREQ)
freq_text = "#unkn"
if(COMM_FREQ)
freq_text = "Command"
if(1351)
freq_text = "Science"
if(1355)
freq_text = "Medical"
if(1357)
freq_text = "Engineering"
if(1359)
freq_text = "Security"
if(1349)
freq_text = "Mining"
if(1347)
freq_text = "Cargo"
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
// --- If the frequency has not been assigned a name, just use the frequency as the name ---
if(!freq_text)
freq_text = format_frequency(display_freq)
// --- Some more pre-message formatting ---
var/part_b = "</span><b> \icon[radio]\[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/part_c = "</span></span>"
if (display_freq==SYND_FREQ)
part_a = "<span class='syndradio'><span class='name'>"
else if (display_freq==COMM_FREQ)
part_a = "<span class='comradio'><span class='name'>"
else if (display_freq in DEPT_FREQS)
part_a = "<span class='deptradio'><span class='name'>"
// --- Filter the message; place it in quotes apply a verb ---
var/quotedmsg = M.say_quote(message)
// --- This following recording is intended for research and feedback in the use of department radio channels ---
var/part_blackbox_b = "</span><b> \[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/blackbox_msg = "[part_a][name][part_blackbox_b][quotedmsg][part_c]"
//var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]"
for (var/obj/machinery/blackbox_recorder/BR in world)
//BR.messages_admin += blackbox_admin_msg
switch(display_freq)
if(1459)
BR.msg_common += blackbox_msg
if(1351)
BR.msg_science += blackbox_msg
if(1353)
BR.msg_command += blackbox_msg
if(1355)
BR.msg_medical += blackbox_msg
if(1357)
BR.msg_engineering += blackbox_msg
if(1359)
BR.msg_security += blackbox_msg
if(1441)
BR.msg_deathsquad += blackbox_msg
if(1213)
BR.msg_syndicate += blackbox_msg
if(1349)
BR.msg_mining += blackbox_msg
if(1347)
BR.msg_cargo += blackbox_msg
else
BR.messages += blackbox_msg
//End of research and feedback code.
/* ###### Send the message ###### */
/* --- Process all the mobs that heard a masked voice (understood) --- */
if (length(heard_masked))
var/N = name
var/J = job
var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_masked)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[radio];track2=\ref[R];track=\ref[M]'>[N] ([J]) </a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
/* --- Process all the mobs that heard the voice normally (understood) --- */
if (length(heard_normal))
var/rendered = "[part_a][M.real_name][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_normal)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[radio];track2=\ref[R];track=\ref[M]'>[realname] ([job]) </a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
/* --- Process all the mobs that heard the voice normally (did not understand) --- */
// Does not display message; displayes the mob's voice_message (ie "chimpers")
if (length(heard_voice))
var/rendered = "[part_a][vname][part_b][M.voice_message][part_c]"
for (var/mob/R in heard_voice)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[radio];track2=\ref[R];track=\ref[M]'>[vname] ([job]) </a>[part_b][vmessage]][part_c]", 2)
else
R.show_message(rendered, 2)
/* --- Process all the mobs that heard a garbled voice (did not understand) --- */
// Displays garbled message (ie "f*c* **u, **i*er!")
if (length(heard_garbled))
quotedmsg = M.say_quote(stars(message))
var/rendered = "[part_a][vname][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_voice)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[radio];track2=\ref[R];track=\ref[M]'>[vname]</a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
// If the signal doesn't need to be used by intercoms or anything:

View File

@@ -0,0 +1,211 @@
/obj/machinery/computer/telecomms/server
name = "Telecommunications Server Monitor"
icon_state = "comm_logs"
var
screen = 0 // the screen number:
list/servers = list() // the servers located by the computer
var/obj/machinery/telecomms/server/SelectedServer
network = "NULL" // the network to probe
temp = "" // temporary feedback messages
universal_translate = 0 // set to 1 if it can translate nonhuman speech
req_access = list(access_engine)
attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
user.machine = src
var/dat = "<TITLE>Telecommunication Server Monitor</TITLE><center><b>Telecommunications Server Monitor</b></center>"
switch(screen)
// --- Main Menu ---
if(0)
dat += "<br>[temp]<br>"
dat += "<br>Current Network: <a href='?src=\ref[src];input=network'>[network]</a><br>"
if(servers.len)
dat += "<br>Detected Telecommunication Servers:<ul>"
for(var/obj/machinery/telecomms/T in servers)
dat += "<li><a href='?src=\ref[src];viewserver=[T.id]'>\ref[T] [T.name]</a> ([T.id])</li>"
dat += "</ul>"
dat += "<br><a href='?src=\ref[src];operation=release'>\[Flush Buffer\]</a>"
else
dat += "<br>No servers detected. Scan for servers: <a href='?src=\ref[src];operation=scan'>\[Scan\]</a>"
// --- Viewing Server ---
if(1)
dat += "<br>[temp]<br>"
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a> <a href='?src=\ref[src];operation=refresh'>\[Refresh\]</a></center>"
dat += "<br>Current Network: [network]"
dat += "<br>Selected Server: [SelectedServer.id]<br><br>"
dat += "Stored Logs: <ol>"
var/i = 0
for(var/datum/comm_log_entry/C in SelectedServer.log_entries)
i++
dat += "<li><font color = #008F00>[C.name]</font color> <font color = #FF0000><a href='?src=\ref[src];delete=[i]'>\[X\]</a></font color><br>"
// -- Determine race of orator --
var/race // The actual race of the mob
var/language = "Human" // MMIs, pAIs, Cyborgs and humans all speak Human
var/mobtype = "[C.parameters["mobtype"]]"
switch(mobtype)
if("/mob/living/carbon/human")
race = "Human"
if("/mob/living/carbon/monkey")
race = "Monkey"
language = race
if("/mob/living/carbon/metroid")
race = "Metroid"
language = race
if("/mob/living/carbon/alien")
race = "Alien"
language = race
if(findtext("C.parameters["mobtype"]", "/mob/living/silicon"))
race = "Artificial Life"
// -- If the orator is a human, or universal translate is active, OR mob has universal speech on --
if(language == "Human" || universal_translate || C.parameters["uspeech"])
dat += "<u><font color = #18743E>Data type</font color></u>: [C.input_type]<br>"
dat += "<u><font color = #18743E>Orator</font color></u>: [C.parameters["name"]] (Job: [C.parameters["job"]])<br>"
dat += "<u><font color = #18743E>Race</font color></u>: [race]<br>"
dat += "<u><font color = #18743E>Contents</font color></u>: \"[C.parameters["message"]]\"<br>"
// -- Orator is not human and universal translate not active --
else
dat += "<u><font color = #18743E>Data type</font color></u>: Audio File<br>"
dat += "<u><font color = #18743E>Source</font color></u>: <i>Unidentifiable</i><br>"
dat += "<u><font color = #18743E>Race</font color></u>: [race]<br>"
dat += "<u><font color = #18743E>Contents</font color></u>: <i>Unintelligble</i><br>"
dat += "</li><br>"
dat += "</ol>"
user << browse(dat, "window=comm_monitor;size=575x400")
onclose(user, "server_control")
temp = ""
return
Topic(href, href_list)
if(..())
return
add_fingerprint(usr)
usr.machine = src
if(!src.allowed(usr) && !emagged)
usr << "\red ACCESS DENIED."
return
if(href_list["viewserver"])
screen = 1
for(var/obj/machinery/telecomms/T in servers)
if(T.id == href_list["viewserver"])
SelectedServer = T
break
if(href_list["operation"])
switch(href_list["operation"])
if("release")
servers = list()
screen = 0
if("mainmenu")
screen = 0
if("scan")
if(servers.len > 0)
temp = "- FAILED: CANNOT PROBE WHEN BUFFER FULL -"
else
for(var/obj/machinery/telecomms/server/T in range(25, src))
if(T.network == network)
servers.Add(T)
if(!servers.len)
temp = "- FAILED: UNABLE TO LOCATE SERVERS IN \[[network]\] -"
else
temp = "- [servers.len] SERVERS PROBED & BUFFERED -"
screen = 0
if(href_list["delete"])
if(SelectedServer)
var/datum/comm_log_entry/D = SelectedServer.log_entries[text2num(href_list["delete"])]
temp = "- DELETED ENTRY: [D.name] -"
SelectedServer.log_entries.Remove(D)
del(D)
if(href_list["input"])
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
if(newnet && usr in range(1, src))
network = newnet
screen = 0
machines = list()
temp = "- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -"
updateUsrDialog()
return
attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
if(istype(D, /obj/item/weapon/screwdriver))
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
if (src.stat & BROKEN)
user << "\blue The broken glass falls out."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard( src.loc )
var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.state = 3
A.icon_state = "3"
A.anchored = 1
del(src)
else
user << "\blue You disconnect the monitor."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
var/obj/item/weapon/circuitboard/comm_server/M = new /obj/item/weapon/circuitboard/comm_server( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.state = 4
A.icon_state = "4"
A.anchored = 1
del(src)
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
playsound(src.loc, 'sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You you disable the security protocols"
src.updateUsrDialog()
return

View File

@@ -0,0 +1,359 @@
/*
Hello, friends, this is Doohl from sexylands. You may be wondering what this
monstrous code file is. Sit down, boys and girls, while I tell you the tale.
The machines defined in this file were designed to be compatible with any radio
signals, provided they use subspace transmission. Currently they are only used for
headsets, but they can eventually be outfitted for real COMPUTER networks. This
is just a skeleton, ladies and gentlemen.
Look at radio.dm for the prequel to this code.
*/
/obj/machinery/telecomms
var
list/links = list() // list of machines this machine is linked to
traffic = 0 // value increases as traffic increases
list/autolinkers = list() // list of text/number values to link with
id = "" // identification string
network = "NULL" // the network of the machinery
machinetype = 0 // just a hacky way of preventing alike machines from pairing
proc/relay_information(datum/signal/signal, filter, amount)
// relay signal to all linked machinery that are of type [filter]. If signal has been sent [amount] times, stop sending
var/send_count = 0
for(var/obj/machinery/telecomms/machine in links)
if(filter && !istype( machine, text2path(filter) ))
continue
if(amount && send_count >= amount)
break
send_count++
spawn()
machine.receive_information(signal, src)
return send_count
proc/relay_direct_information(datum/signal/signal, obj/machinery/telecomms/machine)
// send signal directly to a machine
machine.receive_information(signal, src)
proc/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
// receive information from linked machinery
..()
New()
..()
if(autolinkers.len)
spawn(10)
// Links nearby machines
for(var/obj/machinery/telecomms/T in orange(15, src))
for(var/x in autolinkers)
if(T.autolinkers.Find(x))
if(!(T in links) && machinetype != T.machinetype)
links.Add(T)
/*
The receiver idles and receives messages from subspace-compatible radio equipment;
primarily headsets. They then just relay this information to all linked devices,
which can would probably be network buses.
*/
/obj/machinery/telecomms/receiver
name = "subspace receiver"
icon = 'stationobjs.dmi'
icon_state = "broadcast receiver"
desc = "This machine has a dish-like shape and green lights. It is designed to detect and process subspace radio activity."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 30
machinetype = 1
var
list/freq_listening = list() // list of frequencies that are being tuned into
// you can use "ALL" on any machine using this var
receive_signal(datum/signal/signal)
if(signal.transmission_method == 2)
if( (signal.frequency in freq_listening) || ("ALL" in freq_listening) ) // detect subspace signals
var/datum/signal/copy = new
copy.copy_from(signal) // copy information to new signal
relay_information(copy) // ideally relay the information to bus units
/*
The bus mainframe idles and waits for receivers to relay them signals. They act
as the main network hub, transferring data packets from and to other machines.
They transfer uncompressed subspace packets to processor units, and then take
the processed packet to a server for logging.
*/
/obj/machinery/telecomms/bus
name = "bus mainframe"
icon = 'stationobjs.dmi'
icon_state = "bus1"
desc = "A mighty piece of hardware used to send massive amounts of data quickly."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 50
machinetype = 2
receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
if(signal.data["compression"]) // if signal is still compressed from subspace transmission
// send to one linked processor unit
var/send_to_processor = relay_information(signal, "/obj/machinery/telecomms/processor", 1)
if(!send_to_processor) // failed to send to a processor, relay information anyway
relay_information(signal, "/obj/machinery/telecomms/server")
else // the signal has been decompressed by a processor unit
// send to all linked server units
relay_information(signal, "/obj/machinery/telecomms/server")
/*
The processor is a very simple machine that decompresses subspace signals and
transfers them back to the original bus. It is essential in producing audible
data.
*/
/obj/machinery/telecomms/processor
name = "processor unit"
icon = 'stationobjs.dmi'
icon_state = "processor_on"
desc = "This machine is used to process large quantities of information."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 30
machinetype = 3
receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
signal.data["compression"] = 0 // uncompress subspace signal
relay_direct_information(signal, machine_from) // send the signal back to the machine
/*
The server logs all traffic and signal data. Once it records the signal, it sends
it to the subspace broadcaster.
Store a maximum of 100 logs and then deletes them.
*/
/obj/machinery/telecomms/server
name = "telecommunication server"
icon = 'stationobjs.dmi'
icon_state = "comm_server"
desc = "A machine used to store data and network statistics."
density = 1
anchored = 1
use_power = 1
idle_power_usage = 15
machinetype = 4
var
list/freq_listening = list()
list/log_entries = list()
receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
if(signal.data["message"] && !signal.data["compression"])
if( (signal.frequency in freq_listening) || ("ALL" in freq_listening) )
// if signal contains discernable data
update_logs()
var/datum/comm_log_entry/log = new
var/mob/M = signal.data["mob"]
// Copy the signal.data entries we want
log.parameters["mobtype"] = signal.data["mobtype"]
log.parameters["job"] = signal.data["job"]
log.parameters["key"] = signal.data["key"]
log.parameters["vmessage"] = signal.data["message"]
log.parameters["vname"] = signal.data["vname"]
log.parameters["message"] = signal.data["message"]
log.parameters["name"] = signal.data["name"]
log.parameters["realname"] = signal.data["realname"]
log.parameters["uspeech"] = M.universal_speak
log_entries.Add(log)
var/identifier = num2text( rand(-1000,1000) + world.time )
log.name = "data packet ([md5(identifier)])"
relay_information(signal, "/obj/machinery/telecomms/broadcaster") // send to all broadcasters
proc/update_logs()
// deletes all logs when there are 100
if(log_entries.len >= 100)
var/list/restore = list()
for(var/datum/comm_log_entry/log in log_entries)
if(log.garbage_collector) // if garbage collector is set to 1, delete
del(log)
else
restore.Add(log)
log_entries.len = 0
log_entries.Add(restore)
// Simple log entry datum
/datum/comm_log_entry
var/parameters = list() // carbon-copy to signal.data[]
var/name = "data packet (#)"
var/garbage_collector = 1 // if set to 0, will not be garbage collected
var/input_type = "Speech File"
// ### Preset machines (Located at centcom!) (Or the Comms Satellite) ###
/obj/machinery/telecomms/receiver/preset_left
id = "Receiver A"
network = "tcommsat"
autolinkers = list("bus1", "bus2") // link to bus units 1 and 2
freq_listening = list(1351, 1355, 1347, 1349) // science, medical, cargo, mining
/obj/machinery/telecomms/receiver/preset_right
id = "Receiver B"
network = "tcommsat"
autolinkers = list("bus3", "bus4") // Bus units 3 and 4
freq_listening = list(1459, 1353, 1357, 1359) // common, command, engineering, security
/obj/machinery/telecomms/bus/preset_one
id = "Bus 1"
network = "tcommsat"
autolinkers = list("bus1", "processor1", "science", "medical")
/obj/machinery/telecomms/bus/preset_two
id = "Bus 2"
network = "tcommsat"
autolinkers = list("bus2", "processor2", "cargo", "mining")
/obj/machinery/telecomms/bus/preset_three
id = "Bus 3"
network = "tcommsat"
autolinkers = list("bus3", "processor3", "security", "command")
/obj/machinery/telecomms/bus/preset_four
id = "Bus 4"
network = "tcommsat"
autolinkers = list("bus4", "processor4", "engineering", "common")
/obj/machinery/telecomms/processor/preset_one
id = "Processor 1"
network = "tcommsat"
autolinkers = list("processor1") // processors are sort of isolated; they don't need backward links
/obj/machinery/telecomms/processor/preset_two
id = "Processor 2"
network = "tcommsat"
autolinkers = list("processor2")
/obj/machinery/telecomms/processor/preset_three
id = "Processor 3"
network = "Communications Satellite"
autolinkers = list("processor3")
/obj/machinery/telecomms/processor/preset_four
id = "Processor 4"
network = "tcommsat"
autolinkers = list("processor4")
/obj/machinery/telecomms/server/presets
network = "tcommsat"
science
id = "science server"
freq_listening = list(1351)
autolinkers = list("science", "broadcasterA")
medical
id = "medical server"
freq_listening = list(1355)
autolinkers = list("medical", "broadcasterA")
cargo
id = "cargo server"
freq_listening = list(1347)
autolinkers = list("cargo", "broadcasterA")
mining
id = "mining server"
freq_listening = list(1349)
autolinkers = list("mining", "broadcasterA")
common
id = "common server"
freq_listening = list(1459)
autolinkers = list("common", "broadcasterB")
command
id = "command server"
freq_listening = list(1353)
autolinkers = list("command", "broadcasterB")
engineering
id = "engineering server"
freq_listening = list(1357)
autolinkers = list("engineering", "broadcasterB")
security
id = "security server"
freq_listening = list(1359)
autolinkers = list("security", "broadcasterB")
/obj/machinery/telecomms/broadcaster/preset_left
id = "Broadcaster A"
network = "tcommsat"
autolinkers = list("broadcasterA")
/obj/machinery/telecomms/broadcaster/preset_right
id = "Broadcaster B"
network = "tcommsat"
autolinkers = list("broadcasterB")

View File

@@ -0,0 +1,157 @@
/*
Telecomms monitor tracks the overall trafficing of a telecommunications network
and displays a heirarchy of linked machines.
*/
/obj/machinery/computer/telecomms/monitor
name = "Telecommunications Monitor"
icon_state = "comm_monitor"
var
screen = 0 // the screen number:
list/machines = list() // the machines located by the computer
var/obj/machinery/telecomms/SelectedMachine
network = "NULL" // the network to probe
temp = "" // temporary feedback messages
req_access = list(access_engine)
attack_hand(mob/user as mob)
if(stat & (BROKEN|NOPOWER))
return
user.machine = src
var/dat = "<TITLE>Telecommunications Monitor</TITLE><center><b>Telecommunications Monitor</b></center>"
switch(screen)
// --- Main Menu ---
if(0)
dat += "<br>[temp]<br><br>"
dat += "<br>Current Network: <a href='?src=\ref[src];input=network'>[network]</a><br>"
if(machines.len)
dat += "<br>Detected Network Entities:<ul>"
for(var/obj/machinery/telecomms/T in machines)
dat += "<li><a href='?src=\ref[src];viewmachine=[T.id]'>\ref[T] [T.name]</a> ([T.id])</li>"
dat += "</ul>"
dat += "<br><a href='?src=\ref[src];operation=release'>\[Flush Buffer\]</a>"
else
dat += "<a href='?src=\ref[src];operation=probe'>\[Probe Network\]</a>"
// --- Viewing Machine ---
if(1)
dat += "<br>[temp]<br>"
dat += "<center><a href='?src=\ref[src];operation=mainmenu'>\[Main Menu\]</a></center>"
dat += "<br>Current Network: [network]<br>"
dat += "Selected Network Entity: [SelectedMachine.name] ([SelectedMachine.id])<br>"
dat += "Linked Entities: <ol>"
for(var/obj/machinery/telecomms/T in SelectedMachine.links)
dat += "<li><a href='?src=\ref[src];viewmachine=[T.id]'>\ref[T.id] [T.name]</a> ([T.id])</li>"
dat += "</ol>"
user << browse(dat, "window=comm_monitor;size=575x400")
onclose(user, "server_control")
temp = ""
return
Topic(href, href_list)
if(..())
return
add_fingerprint(usr)
usr.machine = src
if(!src.allowed(usr) && !emagged)
usr << "\red ACCESS DENIED."
return
if(href_list["viewmachine"])
screen = 1
for(var/obj/machinery/telecomms/T in machines)
if(T.id == href_list["viewmachine"])
SelectedMachine = T
break
if(href_list["operation"])
switch(href_list["operation"])
if("release")
machines = list()
screen = 0
if("mainmenu")
screen = 0
if("probe")
if(machines.len > 0)
temp = "- FAILED: CANNOT PROBE WHEN BUFFER FULL -"
else
for(var/obj/machinery/telecomms/T in range(25, src))
if(T.network == network)
machines.Add(T)
if(!machines.len)
temp = "- FAILED: UNABLE TO LOCATE NETWORK ENTITIES IN \[[network]\] -"
else
temp = "- [machines.len] ENTITIES LOCATED & BUFFERED -"
screen = 0
if(href_list["input"])
var/newnet = input(usr, "Which network do you want to view?", "Comm Monitor", network) as null|text
if(newnet && usr in range(1, src))
network = newnet
screen = 0
machines = list()
temp = "- NEW NETWORK TAG SET IN ADDRESS \[[network]\] -"
updateUsrDialog()
return
attackby(var/obj/item/weapon/D as obj, var/mob/user as mob)
if(istype(D, /obj/item/weapon/screwdriver))
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
if (src.stat & BROKEN)
user << "\blue The broken glass falls out."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
new /obj/item/weapon/shard( src.loc )
var/obj/item/weapon/circuitboard/comm_monitor/M = new /obj/item/weapon/circuitboard/comm_monitor( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.state = 3
A.icon_state = "3"
A.anchored = 1
del(src)
else
user << "\blue You disconnect the monitor."
var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc )
var/obj/item/weapon/circuitboard/comm_monitor/M = new /obj/item/weapon/circuitboard/comm_monitor( A )
for (var/obj/C in src)
C.loc = src.loc
A.circuit = M
A.state = 4
A.icon_state = "4"
A.anchored = 1
del(src)
else if(istype(D, /obj/item/weapon/card/emag) && !emagged)
playsound(src.loc, 'sparks4.ogg', 75, 1)
emagged = 1
user << "\blue You you disable the security protocols"
src.updateUsrDialog()
return

View File

@@ -72,6 +72,7 @@
radio.name = "[src] radio"
radio.icon = icon
radio.icon_state = icon_state
radio.subspace_transmission = 1
src.icon_state += "-open"
/*
src.air_contents.volume = gas_tank_volume //liters

View File

@@ -5,6 +5,7 @@
item_state = "headset"
g_amt = 0
m_amt = 75
subspace_transmission = 1
var
protective_temperature = 0
translate_binary = 0

View File

@@ -31,6 +31,7 @@
if (!src.listening)
return
/*
var/turf/T = get_turf(src)
var/list/hear = hearers(7, T)
var/list/V
@@ -44,7 +45,10 @@
V = view(7, T)
if (get_turf(M) in V) //this slow, but I don't think we'd have a lot of wardrobewhores every round --rastaf0
hear+=M
return hear
*/
//return hear
return get_mobs_in_view(4, src)
hear_talk(mob/M as mob, msg)

View File

@@ -1,3 +1,8 @@
var/GLOBAL_RADIO_TYPE = 0 // radio type to use
// 0 = old radios
// 1 = new radios (subspace technology)
/obj/item/device/radio
icon = 'radio.dmi'
name = "station bounced radio"
@@ -16,6 +21,7 @@
listening = 1
freerange = 0 // 0 - Sanitize frequencies, 1 - Full range
list/channels = list() //see communications.dm for full list. First channes is a "default" for :h
subspace_transmission = 0
// "Example" = FREQ_LISTENING|FREQ_BROADCASTING
flags = 450 // hello i'm a fucking idiot why is this 450?? CODE GODS PLEASE EXPLAIN~
throw_speed = 2
@@ -178,179 +184,351 @@
add_fingerprint(usr)
/obj/item/device/radio/talk_into(mob/M as mob, message, channel)
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if (channel == "department")
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
channel = channels[1]
connection = secure_radio_connections[channel]
else
connection = radio_connection
channel = null
if (!istype(connection))
return
var/display_freq = connection.frequency
//world << "DEBUG: used channel=\"[channel]\" frequency= \"[display_freq]\" connection.devices.len = [connection.devices.len]"
if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl
var/eqjobname
/* 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.
if (ishuman(M))
eqjobname = M:get_assignment()
else if (iscarbon(M))
eqjobname = "No id" //only humans can wear ID
else if (isAI(M))
eqjobname = "AI"
else if (isrobot(M))
eqjobname = "Cyborg"//Androids don't really describe these too well, in my opinion.
else if (istype(M, /mob/living/silicon/pai))
eqjobname = "Personal AI"
else
eqjobname = "Unknown"
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.
*/
if (!(wires & WIRE_TRANSMIT))
return
var/list/receive = list()
//for (var/obj/item/device/radio/R in radio_connection.devices)
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"]) // Modified for security headset code -- TLE
//if(R.accept_rad(src, message))
receive |= R.send_hear(display_freq)
//world << "DEBUG: receive.len=[receive.len]"
var/list/heard_masked = list() // masked name or no real name
var/list/heard_normal = list() // normal message
var/list/heard_voice = list() // voice message
var/list/heard_garbled = list() // garbled message
for (var/mob/R in receive)
if (R.client && R.client.STFU_radio) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
continue
if (R.say_understands(M))
if (!ishuman(M) || istype(M.wear_mask, /obj/item/clothing/mask/gas/voice))
heard_masked += R
else
heard_normal += R
//#### Grab the connection datum ####//
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if (channel == "department")
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
channel = channels[1]
connection = secure_radio_connections[channel]
else
if (M.voice_message)
heard_voice += R
connection = radio_connection
channel = null
if (!istype(connection))
return
//#### Tagging the signal with all appropriate identity values ####//
// ||-- The mob's name identity --||
var/displayname = M.name // grab the display name (name you get when you hover over someone's icon)
var/real_name = M.real_name // mob's real name
var/mobkey = "none" // player key associated with mob
var/voicemask = 0 // the speaker is wearing a voice mask
if(M.client)
mobkey = M.key // assign the mob's key
var/jobname // the mob's "job"
// --- Human: use their actual job ---
if (ishuman(M))
jobname = M:get_assignment()
// --- Carbon Nonhuman ---
else if (iscarbon(M)) // Nonhuman carbon mob
jobname = "No id"
// --- AI ---
else if (isAI(M))
jobname = "AI"
// --- Cyborg ---
else if (isrobot(M))
jobname = "Cyborg"
// --- Personal AI (pAI) ---
else if (istype(M, /mob/living/silicon/pai))
jobname = "Personal AI"
// --- Unidentifiable mob ---
else
jobname = "Unknown"
// --- Modifications to the mob's identity ---
// The mob is disguising their identity:
if (istype(M.wear_mask, /obj/item/clothing/mask/gas/voice)&&M.wear_mask:vchange)
displayname = M.wear_mask:voice
jobname = "Unknown"
voicemask = 1
/* ###### Radio headsets can only broadcast through subspace ###### */
if(subspace_transmission)
// First, we want to generate a new radio signal
var/datum/signal/signal = new
signal.transmission_method = 2 // 2 would be a subspace transmission.
// transmission_method could probably be enumerated through #define. Would be neater.
// --- Finally, tag the actual signal with the appropriate values ---
signal.data = list(
// Identity-associated tags:
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmessage" = M.voice_message, // the message to display if the voice wasn't understood
"vname" = M.voice_name, // the name to display if the voice wasn't understood
"vmask" = voicemask, // 1 if the mob is using a voice gas mask
// We store things that would otherwise be kept in the actual mob
// so that they can be logged even AFTER the mob is deleted or something
// Other tags:
"compression" = 1, // compressed radio signal
"message" = message, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src // stores the radio used for transmission
)
signal.frequency = connection.frequency // Quick frequency set
//#### Sending the signal to all subspace receivers ####//
for(var/obj/machinery/telecomms/receiver/R in world)
R.receive_signal(signal)
// Receiving code can be located in _____.dm
return
/* ###### Intercoms and station-bounced radios ###### */
var/filter_type = 2
/* --- Intercoms can only broadcast to other intercoms, but bounced radios can broadcast to bounced radios and intercoms --- */
if(istype(src, /obj/item/device/radio/intercom))
filter_type = 1
var/datum/signal/signal = new
signal.transmission_method = 2
/* --- Try to send a normal subspace broadcast first */
signal.data = list(
"mob" = M, // store a reference to the mob
"mobtype" = M.type, // the mob's type
"realname" = real_name, // the mob's real name
"name" = displayname, // the mob's display name
"job" = jobname, // the mob's job
"key" = mobkey, // the mob's key
"vmessage" = M.voice_message, // the message to display if the voice wasn't understood
"vname" = M.voice_name, // the name to display if the voice wasn't understood
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
"compression" = 1, // compressed radio signal
"message" = message, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src // stores the radio used for transmission
)
signal.frequency = connection.frequency // Quick frequency set
for(var/obj/machinery/telecomms/receiver/R in world)
R.receive_signal(signal)
sleep(rand(10,25)) // wait a little...
if(signal.data["done"])
del(signal) // delete the signal - we're done here.
return
// Oh my god; the comms are down or something because the signal hasn't been broadcasted yet.
// Send a mundane broadcast with limited targets:
Broadcast_Message(connection, M, voicemask, M.voice_message,
src, message, displayname, jobname, real_name, M.voice_name,
filter_type)
else // OLD RADIO SYSTEMS: By Goons?
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if (channel == "department")
//world << "DEBUG: channel=\"[channel]\" switching to \"[channels[1]]\""
channel = channels[1]
connection = secure_radio_connections[channel]
else
connection = radio_connection
channel = null
if (!istype(connection))
return
var/display_freq = connection.frequency
//world << "DEBUG: used channel=\"[channel]\" frequency= \"[display_freq]\" connection.devices.len = [connection.devices.len]"
var/eqjobname
if (ishuman(M))
eqjobname = M:get_assignment()
else if (iscarbon(M))
eqjobname = "No id" //only humans can wear ID
else if (isAI(M))
eqjobname = "AI"
else if (isrobot(M))
eqjobname = "Cyborg"//Androids don't really describe these too well, in my opinion.
else if (istype(M, /mob/living/silicon/pai))
eqjobname = "Personal AI"
else
eqjobname = "Unknown"
if (!(wires & WIRE_TRANSMIT))
return
var/list/receive = list()
//for (var/obj/item/device/radio/R in radio_connection.devices)
for (var/obj/item/device/radio/R in connection.devices["[RADIO_CHAT]"]) // Modified for security headset code -- TLE
//if(R.accept_rad(src, message))
receive |= R.send_hear(display_freq)
//world << "DEBUG: receive.len=[receive.len]"
var/list/heard_masked = list() // masked name or no real name
var/list/heard_normal = list() // normal message
var/list/heard_voice = list() // voice message
var/list/heard_garbled = list() // garbled message
for (var/mob/R in receive)
if (R.client && R.client.STFU_radio) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
continue
if (R.say_understands(M))
if (!ishuman(M) || istype(M.wear_mask, /obj/item/clothing/mask/gas/voice))
heard_masked += R
else
heard_normal += R
else
heard_garbled += R
if (M.voice_message)
heard_voice += R
else
heard_garbled += R
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled))
var/part_a = "<span class='radio'><span class='name'>"
//var/part_b = "</span><b> \icon[src]\[[format_frequency(frequency)]\]</b> <span class='message'>"
var/freq_text
switch(display_freq)
if(SYND_FREQ)
freq_text = "#unkn"
if(COMM_FREQ)
freq_text = "Command"
if(1351)
freq_text = "Science"
if(1355)
freq_text = "Medical"
if(1357)
freq_text = "Engineering"
if(1359)
freq_text = "Security"
if(1349)
freq_text = "Mining"
if(1347)
freq_text = "Cargo"
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
if(!freq_text)
freq_text = format_frequency(display_freq)
var/part_b = "</span><b> \icon[src]\[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/part_c = "</span></span>"
if (display_freq==SYND_FREQ)
part_a = "<span class='syndradio'><span class='name'>"
else if (display_freq==COMM_FREQ)
part_a = "<span class='comradio'><span class='name'>"
else if (display_freq in DEPT_FREQS)
part_a = "<span class='deptradio'><span class='name'>"
var/quotedmsg = M.say_quote(message)
//This following recording is intended for research and feedback in the use of department radio channels.
var/part_blackbox_b = "</span><b> \[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/blackbox_msg = "[part_a][M.name][part_blackbox_b][quotedmsg][part_c]"
//var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]"
for (var/obj/machinery/blackbox_recorder/BR in world)
//BR.messages_admin += blackbox_admin_msg
if (length(heard_masked) || length(heard_normal) || length(heard_voice) || length(heard_garbled))
var/part_a = "<span class='radio'><span class='name'>"
//var/part_b = "</span><b> \icon[src]\[[format_frequency(frequency)]\]</b> <span class='message'>"
var/freq_text
switch(display_freq)
if(1459)
BR.msg_common += blackbox_msg
if(SYND_FREQ)
freq_text = "#unkn"
if(COMM_FREQ)
freq_text = "Command"
if(1351)
BR.msg_science += blackbox_msg
if(1353)
BR.msg_command += blackbox_msg
freq_text = "Science"
if(1355)
BR.msg_medical += blackbox_msg
freq_text = "Medical"
if(1357)
BR.msg_engineering += blackbox_msg
freq_text = "Engineering"
if(1359)
BR.msg_security += blackbox_msg
if(1441)
BR.msg_deathsquad += blackbox_msg
if(1213)
BR.msg_syndicate += blackbox_msg
freq_text = "Security"
if(1349)
BR.msg_mining += blackbox_msg
freq_text = "Mining"
if(1347)
BR.msg_cargo += blackbox_msg
else
BR.messages += blackbox_msg
freq_text = "Cargo"
//There's probably a way to use the list var of channels in code\game\communications.dm to make the dept channels non-hardcoded, but I wasn't in an experimentive mood. --NEO
//End of research and feedback code.
if(!freq_text)
freq_text = format_frequency(display_freq)
if (length(heard_masked))
var/N = M.name
var/J = eqjobname
if (istype(M.wear_mask, /obj/item/clothing/mask/gas/voice)&&M.wear_mask:vchange)
//To properly have the ninja show up on radio. Could also be useful for similar items.
//Would not be necessary but the mob could be wearing a mask that is not a voice changer.
N = M.wear_mask:voice
J = "Unknown"
var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_masked)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[N] ([J]) </a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
var/part_b = "</span><b> \icon[src]\[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/part_c = "</span></span>"
if (length(heard_normal))
var/rendered = "[part_a][M.real_name][part_b][quotedmsg][part_c]"
if (display_freq==SYND_FREQ)
part_a = "<span class='syndradio'><span class='name'>"
else if (display_freq==COMM_FREQ)
part_a = "<span class='comradio'><span class='name'>"
else if (display_freq in DEPT_FREQS)
part_a = "<span class='deptradio'><span class='name'>"
for (var/mob/R in heard_normal)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.real_name] ([eqjobname]) </a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
var/quotedmsg = M.say_quote(message)
if (length(heard_voice))
var/rendered = "[part_a][M.voice_name][part_b][M.voice_message][part_c]"
//This following recording is intended for research and feedback in the use of department radio channels.
for (var/mob/R in heard_voice)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name] ([eqjobname]) </a>[part_b][M.voice_message][part_c]", 2)
else
R.show_message(rendered, 2)
var/part_blackbox_b = "</span><b> \[[freq_text]\]</b> <span class='message'>" // Tweaked for security headsets -- TLE
var/blackbox_msg = "[part_a][M.name][part_blackbox_b][quotedmsg][part_c]"
//var/blackbox_admin_msg = "[part_a][M.name] (Real name: [M.real_name])[part_blackbox_b][quotedmsg][part_c]"
for (var/obj/machinery/blackbox_recorder/BR in world)
//BR.messages_admin += blackbox_admin_msg
switch(display_freq)
if(1459)
BR.msg_common += blackbox_msg
if(1351)
BR.msg_science += blackbox_msg
if(1353)
BR.msg_command += blackbox_msg
if(1355)
BR.msg_medical += blackbox_msg
if(1357)
BR.msg_engineering += blackbox_msg
if(1359)
BR.msg_security += blackbox_msg
if(1441)
BR.msg_deathsquad += blackbox_msg
if(1213)
BR.msg_syndicate += blackbox_msg
if(1349)
BR.msg_mining += blackbox_msg
if(1347)
BR.msg_cargo += blackbox_msg
else
BR.messages += blackbox_msg
if (length(heard_garbled))
quotedmsg = M.say_quote(stars(message))
var/rendered = "[part_a][M.voice_name][part_b][quotedmsg][part_c]"
//End of research and feedback code.
for (var/mob/R in heard_voice)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name]</a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
if (length(heard_masked))
var/N = M.name
var/J = eqjobname
if (istype(M.wear_mask, /obj/item/clothing/mask/gas/voice)&&M.wear_mask:vchange)
//To properly have the ninja show up on radio. Could also be useful for similar items.
//Would not be necessary but the mob could be wearing a mask that is not a voice changer.
N = M.wear_mask:voice
J = "Unknown"
var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_masked)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[N] ([J]) </a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
if (length(heard_normal))
var/rendered = "[part_a][M.real_name][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_normal)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.real_name] ([eqjobname]) </a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
if (length(heard_voice))
var/rendered = "[part_a][M.voice_name][part_b][M.voice_message][part_c]"
for (var/mob/R in heard_voice)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name] ([eqjobname]) </a>[part_b][M.voice_message][part_c]", 2)
else
R.show_message(rendered, 2)
if (length(heard_garbled))
quotedmsg = M.say_quote(stars(message))
var/rendered = "[part_a][M.voice_name][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_voice)
if(istype(R, /mob/living/silicon/ai))
R.show_message("[part_a]<a href='byond://?src=\ref[src];track2=\ref[R];track=\ref[M]'>[M.voice_name]</a>[part_b][quotedmsg][part_c]", 2)
else
R.show_message(rendered, 2)
/obj/item/device/radio/hear_talk(mob/M as mob, msg)
if (broadcasting)
@@ -393,6 +571,7 @@
if (!accept)
return
/* // UURAAAGH ALL THE CPUS, WASTED. ALL OF THEM. NO. -- Doohl
var/turf/T = get_turf(src)
var/list/hear = hearers(1, T)
var/list/V
@@ -406,7 +585,12 @@
V = view(1, T)
if (get_turf(M) in V) //this slow, but I don't think we'd have a lot of wardrobewhores every round --rastaf0
hear+=M
return hear
*/
/* Instead, let's individually search potential containers for mobs! More verbose but a LOT more efficient and less laggy */
// Check gamehelpers.dm for the proc definition:
return get_mobs_in_view(1, src)
/obj/item/device/radio/examine()
set src in view()

View File

@@ -167,6 +167,7 @@
verbs += /client/proc/restartcontroller //Can call via aproccall --I_hate_easy_things.jpg, Mport --Agouri
verbs += /client/proc/Blobize//I need to remember to move/remove this later
verbs += /client/proc/toggle_clickproc //TODO ERRORAGE (Temporary proc while the enw clickproc is being tested)
verbs += /client/proc/cmd_switch_radio // BEEP BOOP FARTE -- Doohl
if (holder.level >= 4)//Badmin********************************************************************
verbs += /obj/admins/proc/adrev //toggle admin revives

View File

@@ -356,6 +356,18 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
else
alert("Invalid mob")
/client/proc/cmd_switch_radio()
set category = "Debug"
set name = "Switch Radio Mode"
set desc = "Toggle between normal radios and experimental radios. Have a coder present if you do this."
GLOBAL_RADIO_TYPE = !GLOBAL_RADIO_TYPE // toggle
log_admin("[key_name(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].")
message_admins("[key_name_admin(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].", 0)
/client/proc/cmd_admin_dress(var/mob/living/carbon/human/M in world)
set category = "Fun"

View File

@@ -339,6 +339,24 @@ datum
materials = list("$glass" = 2000, "acid" = 20)
build_path = "/obj/item/weapon/circuitboard/mining"
comm_monitor
name = "Circuit Design (Telecommunications Monitoring Console)"
desc = "Allows for the construction of circuit boards used to build a telecommunications monitor."
id = "comm_monitor"
req_tech = list("programming" = 3)
build_type = IMPRINTER
materials = list("$glass" = 2000, "acid" = 20)
build_path = "/obj/item/weapon/circuitboard/comm_monitor"
comm_server
name = "Circuit Design (Telecommunications Server Monitoring Console)"
desc = "Allows for the construction of circuit boards used to build a telecommunication server browser and monitor."
id = "comm_server"
req_tech = list("programming" = 3)
build_type = IMPRINTER
materials = list("$glass" = 2000, "acid" = 20)
build_path = "/obj/item/weapon/circuitboard/comm_server"
///////////////////////////////////
//////////AI Module Disks//////////
///////////////////////////////////

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 52 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -53,6 +53,7 @@
#define FILE_DIR "code/game/machinery/embedded_controller"
#define FILE_DIR "code/game/machinery/kitchen"
#define FILE_DIR "code/game/machinery/pipe"
#define FILE_DIR "code/game/machinery/telecomms"
#define FILE_DIR "code/game/magic"
#define FILE_DIR "code/game/magic/cultist"
#define FILE_DIR "code/game/mecha"
@@ -508,6 +509,10 @@
#include "code\game\machinery\kitchen\processor.dm"
#include "code\game\machinery\pipe\construction.dm"
#include "code\game\machinery\pipe\pipe_dispenser.dm"
#include "code\game\machinery\telecomms\broadcaster.dm"
#include "code\game\machinery\telecomms\logbrowser.dm"
#include "code\game\machinery\telecomms\telecomunications.dm"
#include "code\game\machinery\telecomms\telemonitor.dm"
#include "code\game\magic\library.dm"
#include "code\game\magic\musician.dm"
#include "code\game\magic\cultist\ritual.dm"