mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Documents a lot of undocumented telecommunications code (#78934)
## About The Pull Request Telecommunications code is very old, I'm sure that isn't a shock to anyone. One of the issues it had was that it was poorly documented, so I've spent a few hours today making sure that at least one person could understand what was going on in there, and actually left some traces of what I understood from it all. Now, it's a bit cleaner, and hopefully a lot easier to understand because the stuff's actually explained, and the explanations are up to date. Because there was still code from over eight years ago that straight-up just didn't match the contents of the file at all. I tried to not change any of the logic, I did one minor adjustment just to improve the coherency of a variable that's not actually used anywhere, but I kept it in case it becomes useful in the future, since I wanted to keep feature parity here. This should open up the way to actually making some changes to telecommunications in the future, which I'm looking forward to, too. ## Why It's Good For The Game Less undocumented nightmarish code from ages ago, now it's at least documented, so it'll be easier to tweak moving forward. ## Changelog 🆑 GoldenAlpharex code: Documented a huge part of telecommunications machinery and signal code, and did some minor code improvements to said code. /🆑
This commit is contained in:
@@ -130,6 +130,7 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
|
||||
))
|
||||
|
||||
/datum/radio_frequency
|
||||
/// The frequency of this radio frequency. Of course.
|
||||
var/frequency
|
||||
/// List of filters -> list of devices
|
||||
var/list/list/datum/weakref/devices = list()
|
||||
@@ -178,6 +179,7 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
|
||||
device.receive_signal(signal)
|
||||
CHECK_TICK
|
||||
|
||||
/// Handles adding a listener to the radio frequency.
|
||||
/datum/radio_frequency/proc/add_listener(obj/device, filter as text|null)
|
||||
if (!filter)
|
||||
filter = "_default"
|
||||
@@ -190,6 +192,7 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
|
||||
devices[filter] = devices_line = list()
|
||||
devices_line += new_listener
|
||||
|
||||
/// Handles removing a listener from this radio frequency.
|
||||
/datum/radio_frequency/proc/remove_listener(obj/device)
|
||||
for(var/devices_filter in devices)
|
||||
var/list/devices_line = devices[devices_filter]
|
||||
@@ -199,15 +202,27 @@ GLOBAL_LIST_INIT(reverseradiochannels, list(
|
||||
if(!devices_line.len)
|
||||
devices -= devices_filter
|
||||
|
||||
/**
|
||||
* Proc for reacting to a received `/datum/signal`. To be implemented as needed,
|
||||
* does nothing by default.
|
||||
*/
|
||||
/obj/proc/receive_signal(datum/signal/signal)
|
||||
set waitfor = FALSE
|
||||
return
|
||||
|
||||
/datum/signal
|
||||
/// The source of this signal.
|
||||
var/obj/source
|
||||
/// The frequency on which this signal was emitted.
|
||||
var/frequency = 0
|
||||
/// The method through which this signal was transmitted.
|
||||
/// See all of the `TRANSMISSION_X` in `code/__DEFINES/radio.dm` for
|
||||
/// all of the possible options.
|
||||
var/transmission_method
|
||||
/// The data carried through this signal. Defaults to `null`, otherwise it's
|
||||
/// an associative list of (string, any).
|
||||
var/list/data
|
||||
/// Logging data, used for logging purposes. Makes sense, right?
|
||||
var/logging_data
|
||||
|
||||
/datum/signal/New(data, transmission_method = TRANSMISSION_RADIO, logging_data = null)
|
||||
|
||||
@@ -1,67 +1,26 @@
|
||||
/*
|
||||
|
||||
Here is the big, bad function that broadcasts a message given the appropriate
|
||||
parameters.
|
||||
|
||||
@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 monkeys 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 data:
|
||||
If specified:
|
||||
1 -- Will only broadcast to intercoms
|
||||
2 -- Will only broadcast to intercoms and station-bounced radios
|
||||
3 -- Broadcast to syndicate frequency
|
||||
4 -- AI can't track down this person. Useful for imitation broadcasts where you can't find the actual mob
|
||||
|
||||
@param compression:
|
||||
If 0, the signal is audible
|
||||
If nonzero, the signal may be partially inaudible or just complete gibberish.
|
||||
|
||||
@param level:
|
||||
The list of Z levels that the sending radio is broadcasting to. Having 0 in the list broadcasts on all levels
|
||||
|
||||
@param freq
|
||||
The frequency of the signal
|
||||
|
||||
**/
|
||||
|
||||
// Subtype of /datum/signal with additional processing information.
|
||||
/datum/signal/subspace
|
||||
transmission_method = TRANSMISSION_SUBSPACE
|
||||
/// The type of server this signal is meant to be relayed to.
|
||||
/// Not exclusive, the bus will usually try to send it through
|
||||
/// more signals, but for that look for
|
||||
/// `/obj/machinery/telecomms/bus/receive_information()`
|
||||
var/server_type = /obj/machinery/telecomms/server
|
||||
/// The signal that was the origin of this one, in case it was a copy.
|
||||
var/datum/signal/subspace/original
|
||||
/// The levels on which this signal can be received. Generally set by
|
||||
/// a broadcaster, a relay or a message server.
|
||||
/// If this list contains `0`, then it will be receivable on every single
|
||||
/// z-level.
|
||||
var/list/levels
|
||||
|
||||
/datum/signal/subspace/New(data)
|
||||
src.data = data || list()
|
||||
|
||||
/**
|
||||
* Handles creating a new subspace signal that's a hard copy of this one, linked
|
||||
* to this current signal via the `original` value, so that it can be traced back.
|
||||
*/
|
||||
/datum/signal/subspace/proc/copy()
|
||||
var/datum/signal/subspace/copy = new
|
||||
copy.original = src
|
||||
@@ -73,18 +32,26 @@
|
||||
copy.data = data.Copy()
|
||||
return copy
|
||||
|
||||
/**
|
||||
* Handles marking the current signal, as well as its original signal,
|
||||
* and their original signals (recursively) as done, in their `data["done"]`.
|
||||
*/
|
||||
/datum/signal/subspace/proc/mark_done()
|
||||
var/datum/signal/subspace/current = src
|
||||
while (current)
|
||||
current.data["done"] = TRUE
|
||||
current = current.original
|
||||
|
||||
/**
|
||||
* Handles sending this signal to every available receiver and mainframe.
|
||||
*/
|
||||
/datum/signal/subspace/proc/send_to_receivers()
|
||||
for(var/obj/machinery/telecomms/receiver/R in GLOB.telecomms_list)
|
||||
R.receive_signal(src)
|
||||
for(var/obj/machinery/telecomms/allinone/R in GLOB.telecomms_list)
|
||||
R.receive_signal(src)
|
||||
for(var/obj/machinery/telecomms/receiver/receiver in GLOB.telecomms_list)
|
||||
receiver.receive_signal(src)
|
||||
for(var/obj/machinery/telecomms/allinone/all_in_one_receiver in GLOB.telecomms_list)
|
||||
all_in_one_receiver.receive_signal(src)
|
||||
|
||||
/// Handles broadcasting this signal out, to be implemented by subtypes.
|
||||
/datum/signal/subspace/proc/broadcast()
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -92,9 +59,14 @@
|
||||
// Despite "subspace" in the name, these transmissions can also be RADIO
|
||||
// (intercoms and SBRs) or SUPERSPACE (CentCom).
|
||||
/datum/signal/subspace/vocal
|
||||
/// The virtualspeaker associated with this vocal transmission.
|
||||
var/atom/movable/virtualspeaker/virt
|
||||
/// The language this vocal transmission was sent in.
|
||||
var/datum/language/language
|
||||
|
||||
#define COMPRESSION_VOCAL_SIGNAL_MIN 35
|
||||
#define COMPRESSION_VOCAL_SIGNAL_MAX 65
|
||||
|
||||
/datum/signal/subspace/vocal/New(
|
||||
obj/source, // the originating radio
|
||||
frequency, // the frequency the signal is taking place on
|
||||
@@ -113,13 +85,16 @@
|
||||
"name" = speaker.name,
|
||||
"job" = speaker.job,
|
||||
"message" = message,
|
||||
"compression" = rand(35, 65),
|
||||
"compression" = rand(COMPRESSION_VOCAL_SIGNAL_MIN, COMPRESSION_VOCAL_SIGNAL_MAX),
|
||||
"language" = lang_instance.name,
|
||||
"spans" = spans,
|
||||
"mods" = message_mods
|
||||
)
|
||||
levels = SSmapping.get_connected_levels(get_turf(source))
|
||||
|
||||
#undef COMPRESSION_VOCAL_SIGNAL_MIN
|
||||
#undef COMPRESSION_VOCAL_SIGNAL_MAX
|
||||
|
||||
/datum/signal/subspace/vocal/copy()
|
||||
var/datum/signal/subspace/vocal/copy = new(source, frequency, virt, language)
|
||||
copy.original = src
|
||||
@@ -127,6 +102,10 @@
|
||||
copy.levels = levels
|
||||
return copy
|
||||
|
||||
/// Past this amount of compression, the resulting gibberish will actually
|
||||
/// replace characters, making it even harder to understand.
|
||||
#define COMPRESSION_REPLACE_CHARACTER_THRESHOLD 30
|
||||
|
||||
/// This is the meat function for making radios hear vocal transmissions.
|
||||
/datum/signal/subspace/vocal/broadcast()
|
||||
set waitfor = FALSE
|
||||
@@ -137,7 +116,7 @@
|
||||
return
|
||||
var/compression = data["compression"]
|
||||
if(compression > 0)
|
||||
message = Gibberish(message, compression >= 30)
|
||||
message = Gibberish(message, compression >= COMPRESSION_REPLACE_CHARACTER_THRESHOLD)
|
||||
|
||||
var/list/signal_reaches_every_z_level = levels
|
||||
|
||||
@@ -206,8 +185,8 @@
|
||||
var/spans_part = ""
|
||||
if(length(spans))
|
||||
spans_part = "(spans:"
|
||||
for(var/S in spans)
|
||||
spans_part = "[spans_part] [S]"
|
||||
for(var/span in spans)
|
||||
spans_part = "[spans_part] [span]"
|
||||
spans_part = "[spans_part] ) "
|
||||
|
||||
var/lang_name = data["language"]
|
||||
@@ -220,4 +199,6 @@
|
||||
else
|
||||
log_telecomms("[virt.source] [log_text] [loc_name(get_turf(virt.source))]")
|
||||
|
||||
QDEL_IN(virt, 50) // Make extra sure the virtualspeaker gets qdeleted
|
||||
QDEL_IN(virt, 5 SECONDS) // Make extra sure the virtualspeaker gets qdeleted
|
||||
|
||||
#undef COMPRESSION_REPLACE_CHARACTER_THRESHOLD
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
// Send selected server data
|
||||
var/list/server_out = list()
|
||||
server_out["name"] = SelectedServer.name
|
||||
server_out["traffic"] = SelectedServer.totaltraffic
|
||||
server_out["traffic"] = SelectedServer.total_traffic
|
||||
// Get the messages on this server
|
||||
var/list/packets = list()
|
||||
for(var/datum/comm_log_entry/packet in SelectedServer.log_entries)
|
||||
|
||||
@@ -20,13 +20,16 @@
|
||||
var/obj/machinery/telecomms/message_server/linkedServer = null
|
||||
/// Sparks effect - For emag
|
||||
var/datum/effect_system/spark_spread/spark_system
|
||||
/// Computer properties
|
||||
var/screen = MSG_MON_SCREEN_MAIN // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
|
||||
var/message = "System bootup complete. Please select an option." // The message that shows on the main menu.
|
||||
var/auth = FALSE // Are they authenticated?
|
||||
/// Error, Success & Notice messages
|
||||
/// Computer properties.
|
||||
/// 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message
|
||||
var/screen = MSG_MON_SCREEN_MAIN
|
||||
/// The message that shows on the main menu.
|
||||
var/message = "System bootup complete. Please select an option."
|
||||
/// Error message to display in the interface.
|
||||
var/error_message = ""
|
||||
/// Notice message to display in the interface.
|
||||
var/notice_message = ""
|
||||
/// Success message to display in the interface.
|
||||
var/success_message = ""
|
||||
/// Decrypt password
|
||||
var/password = ""
|
||||
@@ -89,7 +92,7 @@
|
||||
"error_message" = error_message,
|
||||
"notice_message" = notice_message,
|
||||
"success_message" = success_message,
|
||||
"auth" = auth,
|
||||
"auth" = authenticated,
|
||||
"server_status" = !LINKED_SERVER_NONRESPONSIVE,
|
||||
)
|
||||
|
||||
@@ -109,7 +112,7 @@
|
||||
if(MSG_MON_SCREEN_REQUEST_LOGS)
|
||||
var/list/request_list = list()
|
||||
for(var/datum/data_rc_msg/rc in linkedServer.rc_msgs)
|
||||
request_list += list(list("ref" = REF(rc), "message" = rc.message, "stamp" = rc.stamp, "id_auth" = rc.id_auth, "departament" = rc.send_dpt))
|
||||
request_list += list(list("ref" = REF(rc), "message" = rc.message, "stamp" = rc.stamp, "id_auth" = rc.id_auth, "departament" = rc.sender_department))
|
||||
data["requests"] = request_list
|
||||
return data
|
||||
|
||||
@@ -126,15 +129,15 @@
|
||||
if("auth")
|
||||
var/authPass = params["auth_password"]
|
||||
|
||||
if(auth)
|
||||
auth = FALSE
|
||||
if(authenticated)
|
||||
authenticated = FALSE
|
||||
return TRUE
|
||||
|
||||
if(linkedServer.decryptkey != authPass)
|
||||
error_message = "ALERT: Incorrect decryption key!"
|
||||
return TRUE
|
||||
|
||||
auth = TRUE
|
||||
authenticated = TRUE
|
||||
success_message = "YOU SUCCESFULLY LOGGED IN!"
|
||||
|
||||
return TRUE
|
||||
@@ -246,14 +249,14 @@
|
||||
linkedServer.receive_information(signal, null)
|
||||
usr.log_message("(Tablet: [name] | [usr.real_name]) sent \"[message]\" to [signal.format_target()]", LOG_PDA)
|
||||
return TRUE
|
||||
// Malfunction AI and cyborgs can hack console. This will auth console, but you need to wait password selection
|
||||
// Malfunction AI and cyborgs can hack console. This will authenticate the console, but you need to wait password selection
|
||||
if("hack")
|
||||
var/time = 10 SECONDS * length(linkedServer.decryptkey)
|
||||
addtimer(CALLBACK(src, PROC_REF(unemag_console)), time)
|
||||
screen = MSG_MON_SCREEN_HACKED
|
||||
error_message = "%$&(£: Critical %$$@ Error // !RestArting! <lOadiNg backUp iNput ouTput> - ?pLeaSe wAit!"
|
||||
linkedServer.toggled = FALSE
|
||||
auth = TRUE
|
||||
authenticated = TRUE
|
||||
return TRUE
|
||||
return TRUE
|
||||
|
||||
@@ -284,6 +287,9 @@
|
||||
else
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/**
|
||||
* Handles printing the monitor key for a given server onto this piece of paper.
|
||||
*/
|
||||
/obj/item/paper/monitorkey/proc/print(obj/machinery/telecomms/message_server/server)
|
||||
add_raw_text("<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is <b>[server.decryptkey]</b>.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one.")
|
||||
add_overlay("paper_words")
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
|
||||
/*
|
||||
|
||||
All telecommunications interactions:
|
||||
|
||||
*/
|
||||
// This file is separate from telecommunications.dm to isolate the implementation
|
||||
// of basic interactions with the machines.
|
||||
|
||||
/obj/machinery/telecomms
|
||||
var/temp = "" // output message
|
||||
/// The current temporary frequency used to add new filtered frequencies
|
||||
/// options.
|
||||
var/tempfreq = FREQ_COMMON
|
||||
/// The current mob operating the machine.
|
||||
var/mob/living/operator
|
||||
///Illegal frequencies that can't be listened to by telecommunication servers.
|
||||
/// Illegal frequencies that can't be listened to by telecommunication servers.
|
||||
var/list/banned_frequencies = list(
|
||||
FREQ_SYNDICATE,
|
||||
FREQ_CENTCOM,
|
||||
@@ -19,7 +17,7 @@
|
||||
FREQ_CTF_BLUE,
|
||||
)
|
||||
|
||||
/obj/machinery/telecomms/attackby(obj/item/P, mob/user, params)
|
||||
/obj/machinery/telecomms/attackby(obj/item/attacking_item, mob/user, params)
|
||||
|
||||
var/icon_closed = initial(icon_state)
|
||||
var/icon_open = "[initial(icon_state)]_o"
|
||||
@@ -27,13 +25,13 @@
|
||||
icon_closed = "[initial(icon_state)]_off"
|
||||
icon_open = "[initial(icon_state)]_o_off"
|
||||
|
||||
if(default_deconstruction_screwdriver(user, icon_open, icon_closed, P))
|
||||
if(default_deconstruction_screwdriver(user, icon_open, icon_closed, attacking_item))
|
||||
return
|
||||
// Using a multitool lets you access the receiver's interface
|
||||
else if(P.tool_behaviour == TOOL_MULTITOOL)
|
||||
else if(attacking_item.tool_behaviour == TOOL_MULTITOOL)
|
||||
attack_hand(user)
|
||||
|
||||
else if(default_deconstruction_crowbar(P))
|
||||
else if(default_deconstruction_crowbar(attacking_item))
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
@@ -122,8 +120,8 @@
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
|
||||
return
|
||||
else
|
||||
for(var/obj/machinery/telecomms/T in links)
|
||||
remove_link(T)
|
||||
for(var/obj/machinery/telecomms/linked_machine in links)
|
||||
remove_link(linked_machine)
|
||||
network = params["value"]
|
||||
links = list()
|
||||
operator.log_message("has changed the network for [src] to [network].", LOG_GAME)
|
||||
@@ -145,13 +143,13 @@
|
||||
operator.log_message("removed frequency [params["value"]] for [src].", LOG_GAME)
|
||||
. = TRUE
|
||||
if("unlink")
|
||||
var/obj/machinery/telecomms/T = links[text2num(params["value"])]
|
||||
if(T)
|
||||
. = remove_link(T, operator)
|
||||
var/obj/machinery/telecomms/machine_to_unlink = links[text2num(params["value"])]
|
||||
if(machine_to_unlink)
|
||||
. = remove_link(machine_to_unlink, operator)
|
||||
if("link")
|
||||
if(heldmultitool)
|
||||
var/obj/machinery/telecomms/T = heldmultitool.buffer
|
||||
. = add_new_link(T, operator)
|
||||
var/obj/machinery/telecomms/machine_to_link = heldmultitool.buffer
|
||||
. = add_new_link(machine_to_link, operator)
|
||||
if("buffer")
|
||||
heldmultitool.set_buffer(src)
|
||||
. = TRUE
|
||||
@@ -162,7 +160,7 @@
|
||||
add_act(action, params)
|
||||
. = TRUE
|
||||
|
||||
///adds new_connection to src's links list AND vice versa. also updates links_by_telecomms_type
|
||||
/// Adds new_connection to src's links list AND vice versa. Also updates `links_by_telecomms_type`.
|
||||
/obj/machinery/telecomms/proc/add_new_link(obj/machinery/telecomms/new_connection, mob/user)
|
||||
if(!istype(new_connection) || new_connection == src)
|
||||
return FALSE
|
||||
@@ -180,7 +178,7 @@
|
||||
user.log_message("linked [src] for [new_connection].", LOG_GAME)
|
||||
return TRUE
|
||||
|
||||
///removes old_connection from src's links list AND vice versa. also updates links_by_telecomms_type
|
||||
/// Removes old_connection from src's links list AND vice versa. Also updates `links_by_telecomms_type`.
|
||||
/obj/machinery/telecomms/proc/remove_link(obj/machinery/telecomms/old_connection, mob/user)
|
||||
if(!istype(old_connection) || old_connection == src)
|
||||
return FALSE
|
||||
@@ -198,6 +196,11 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Wrapper for adding additional options to a machine's interface.
|
||||
*
|
||||
* Returns a list, or `null` if it wasn't implemented by the machine.
|
||||
*/
|
||||
/obj/machinery/telecomms/proc/add_option()
|
||||
return
|
||||
|
||||
@@ -214,7 +217,14 @@
|
||||
data["receiving"] = receiving
|
||||
return data
|
||||
|
||||
/**
|
||||
* Wrapper for adding another time of action for `ui_act()`, rather than
|
||||
* having you override `ui_act` yourself.
|
||||
*
|
||||
* Returns `TRUE` if the action was handled, nothing if not.
|
||||
*/
|
||||
/obj/machinery/telecomms/proc/add_act(action, params)
|
||||
return
|
||||
|
||||
/obj/machinery/telecomms/relay/add_act(action, params)
|
||||
switch(action)
|
||||
@@ -236,20 +246,19 @@
|
||||
else
|
||||
change_frequency = 0
|
||||
|
||||
// Returns a multitool from a user depending on their mobtype.
|
||||
|
||||
/// Returns a multitool from a user depending on their mobtype.
|
||||
/obj/machinery/telecomms/proc/get_multitool(mob/user)
|
||||
var/obj/item/multitool/P = null
|
||||
var/obj/item/multitool/multitool = null
|
||||
// Let's double check
|
||||
if(!issilicon(user) && istype(user.get_active_held_item(), /obj/item/multitool))
|
||||
P = user.get_active_held_item()
|
||||
multitool = user.get_active_held_item()
|
||||
else if(isAI(user))
|
||||
var/mob/living/silicon/ai/U = user
|
||||
P = U.aiMulti
|
||||
multitool = U.aiMulti
|
||||
else if(iscyborg(user) && in_range(user, src))
|
||||
if(istype(user.get_active_held_item(), /obj/item/multitool))
|
||||
P = user.get_active_held_item()
|
||||
return P
|
||||
multitool = user.get_active_held_item()
|
||||
return multitool
|
||||
|
||||
/obj/machinery/telecomms/proc/canAccess(mob/user)
|
||||
if(issilicon(user) || in_range(user, src))
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/*
|
||||
Basically just an empty shell for receiving and broadcasting radio messages. Not
|
||||
very flexible, but it gets the job done.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basically just an empty shell for receiving and broadcasting radio messages. Not
|
||||
* very flexible, but it gets the job done.
|
||||
*/
|
||||
/obj/machinery/telecomms/allinone
|
||||
name = "telecommunications mainframe"
|
||||
icon_state = "comm_server"
|
||||
@@ -41,6 +40,6 @@
|
||||
sleep(signal.data["slow"]) // simulate the network lag if necessary
|
||||
signal.broadcast()
|
||||
|
||||
/obj/machinery/telecomms/allinone/attackby(obj/item/P, mob/user, params)
|
||||
if(P.tool_behaviour == TOOL_MULTITOOL)
|
||||
/obj/machinery/telecomms/allinone/attackby(obj/item/attacking_item, mob/user, params)
|
||||
if(attacking_item.tool_behaviour == TOOL_MULTITOOL)
|
||||
return attack_hand(user)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_EMPTY(recentmessages) // global list of recent messages broadcasted : used to circumvent massive radio spam
|
||||
GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages list is kept in sync
|
||||
/// Global list of recent messages broadcasted : used to circumvent massive radio spam
|
||||
GLOBAL_LIST_EMPTY(recent_messages)
|
||||
/// Used to make sure restarting the recent_messages list is kept in sync.
|
||||
GLOBAL_VAR_INIT(message_delay, FALSE)
|
||||
|
||||
/**
|
||||
* 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_state = "broadcaster"
|
||||
@@ -18,15 +19,17 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages
|
||||
circuit = /obj/item/circuitboard/machine/telecomms/broadcaster
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
|
||||
// Don't broadcast rejected signals
|
||||
if(!istype(signal))
|
||||
return
|
||||
|
||||
// Don't broadcast rejected signals
|
||||
if(signal.data["reject"])
|
||||
return
|
||||
if(!signal.data["message"])
|
||||
return
|
||||
|
||||
var/signal_message = "[signal.frequency]:[signal.data["message"]]:[signal.data["name"]]"
|
||||
if(signal_message in GLOB.recentmessages)
|
||||
if(signal_message in GLOB.recent_messages)
|
||||
return
|
||||
|
||||
// Prevents massive radio spam
|
||||
@@ -35,11 +38,11 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages
|
||||
if(original && ("compression" in signal.data))
|
||||
original.data["compression"] = signal.data["compression"]
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (T)
|
||||
signal.levels |= SSmapping.get_connected_levels(T)
|
||||
var/turf/current_turf = get_turf(src)
|
||||
if (current_turf)
|
||||
signal.levels |= SSmapping.get_connected_levels(current_turf)
|
||||
|
||||
GLOB.recentmessages.Add(signal_message)
|
||||
GLOB.recent_messages.Add(signal_message)
|
||||
|
||||
if(signal.data["slow"] > 0)
|
||||
sleep(signal.data["slow"]) // simulate the network lag if necessary
|
||||
@@ -55,29 +58,31 @@ GLOBAL_VAR_INIT(message_delay, 0) // To make sure restarting the recentmessages
|
||||
|
||||
use_power(idle_power_usage)
|
||||
|
||||
/**
|
||||
* Simply resets the message delay and the recent messages list, to ensure that
|
||||
* recent messages can be sent again. Is called on a one second timer after a
|
||||
* delay is set, from `/obj/machinery/telecomms/broadcaster/receive_information()`
|
||||
*/
|
||||
/proc/end_message_delay()
|
||||
GLOB.message_delay = FALSE
|
||||
GLOB.recentmessages = list()
|
||||
GLOB.recent_messages = list()
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/Destroy()
|
||||
// In case message_delay is left on 1, otherwise it won't reset the list and people can't say the same thing twice anymore.
|
||||
if(GLOB.message_delay)
|
||||
GLOB.message_delay = 0
|
||||
GLOB.message_delay = FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
|
||||
//Preset Broadcasters
|
||||
// Preset Broadcasters
|
||||
|
||||
//--PRESET LEFT--//
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/preset_left
|
||||
id = "Broadcaster A"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("broadcasterA")
|
||||
|
||||
//--PRESET RIGHT--//
|
||||
|
||||
/obj/machinery/telecomms/broadcaster/preset_right
|
||||
id = "Broadcaster B"
|
||||
network = "tcommsat"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
The bus mainframe idles and waits for hubs to relay them signals. They act
|
||||
as junctions for the network.
|
||||
|
||||
They transfer uncompressed subspace packets to processor units, and then take
|
||||
the processed packet to a server for logging.
|
||||
|
||||
Link to a subspace hub if it can't send to a server.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The bus mainframe idles and waits for hubs to relay them signals. They act
|
||||
* as junctions for the network.
|
||||
*
|
||||
* They transfer uncompressed subspace packets to processor units, and then take
|
||||
* the processed packet to a server for logging.
|
||||
*
|
||||
* Can be linked to a telecommunications hub or a broadcaster in the absence
|
||||
* of a server, at the cost of some added latency.
|
||||
*/
|
||||
/obj/machinery/telecomms/bus
|
||||
name = "bus mainframe"
|
||||
icon_state = "bus"
|
||||
@@ -17,7 +17,9 @@
|
||||
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.01
|
||||
netspeed = 40
|
||||
circuit = /obj/item/circuitboard/machine/telecomms/bus
|
||||
var/change_frequency = 0
|
||||
/// The frequency this bus will use to override the received signal's frequency,
|
||||
/// if not `NONE`.
|
||||
var/change_frequency = NONE
|
||||
|
||||
/obj/machinery/telecomms/bus/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
|
||||
if(!istype(signal) || !is_freq_listening(signal))
|
||||
@@ -47,7 +49,7 @@
|
||||
|
||||
use_power(idle_power_usage)
|
||||
|
||||
//Preset Buses
|
||||
// Preset Buses
|
||||
|
||||
/obj/machinery/telecomms/bus/preset_one
|
||||
id = "Bus 1"
|
||||
@@ -75,6 +77,8 @@
|
||||
|
||||
/obj/machinery/telecomms/bus/preset_four/Initialize(mapload)
|
||||
. = ..()
|
||||
// We want to include every freely-available frequency on this one, so they
|
||||
// get processed quickly when used on-station.
|
||||
for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2)
|
||||
freq_listening |= i
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/*
|
||||
The HUB idles until it receives information. It then passes on that information
|
||||
depending on where it came from.
|
||||
|
||||
This is the heart of the Telecommunications Network, sending information where it
|
||||
is needed. It mainly receives information from long-distance Relays and then sends
|
||||
that information to be processed. Afterwards it gets the uncompressed information
|
||||
from Servers/Buses and sends that back to the relay, to then be broadcasted.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The HUB idles until it receives information. It then passes on that information
|
||||
* depending on where it came from.
|
||||
*
|
||||
* This is the heart of the Telecommunications Network, sending information where it
|
||||
* is needed. It mainly receives information from long-distance Relays and then sends
|
||||
* that information to be processed. Afterwards it gets the uncompressed information
|
||||
* from Servers/Buses and sends that back to the relay, to then be broadcasted.
|
||||
*/
|
||||
/obj/machinery/telecomms/hub
|
||||
name = "telecommunication hub"
|
||||
icon_state = "hub"
|
||||
@@ -53,12 +52,31 @@
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
//Preset HUB
|
||||
// Preset HUB
|
||||
|
||||
/obj/machinery/telecomms/hub/preset
|
||||
id = "Hub"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("hub", "relay", "s_relay", "m_relay", "r_relay", "h_relay", "science", "medical",
|
||||
"supply", "service", "common", "command", "engineering", "security",
|
||||
"receiverA", "receiverB", "broadcasterA", "broadcasterB", "autorelay", "messaging")
|
||||
autolinkers = list(
|
||||
"hub",
|
||||
"relay",
|
||||
"s_relay",
|
||||
"m_relay",
|
||||
"r_relay",
|
||||
"h_relay",
|
||||
"science",
|
||||
"medical",
|
||||
"supply",
|
||||
"service",
|
||||
"common",
|
||||
"command",
|
||||
"engineering",
|
||||
"security",
|
||||
"receiverA",
|
||||
"receiverB",
|
||||
"broadcasterA",
|
||||
"broadcasterB",
|
||||
"autorelay",
|
||||
"messaging",
|
||||
)
|
||||
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
/*
|
||||
The equivalent of the server, for PDA and request console messages.
|
||||
Without it, PDA and request console messages cannot be transmitted.
|
||||
PDAs require the rest of the telecomms setup, but request consoles only
|
||||
require the message server.
|
||||
*/
|
||||
|
||||
// A decorational representation of SSblackbox, usually placed alongside the message server. Also contains a traitor theft item.
|
||||
/obj/machinery/blackbox_recorder
|
||||
name = "Blackbox Recorder"
|
||||
icon = 'icons/obj/machines/telecomms.dmi'
|
||||
icon_state = "blackbox"
|
||||
name = "Blackbox Recorder"
|
||||
density = TRUE
|
||||
armor_type = /datum/armor/machinery_blackbox_recorder
|
||||
/// The object that's stored in the machine, which is to say, the blackbox itself.
|
||||
/// When it hasn't already been stolen, of course.
|
||||
var/obj/item/stored
|
||||
|
||||
/datum/armor/machinery_blackbox_recorder
|
||||
@@ -39,15 +34,15 @@
|
||||
to_chat(user, span_warning("It seems that the blackbox is missing..."))
|
||||
return
|
||||
|
||||
/obj/machinery/blackbox_recorder/attackby(obj/item/I, mob/living/user, params)
|
||||
if(istype(I, /obj/item/blackbox))
|
||||
if(HAS_TRAIT(I, TRAIT_NODROP) || !user.transferItemToLoc(I, src))
|
||||
to_chat(user, span_warning("[I] is stuck to your hand!"))
|
||||
/obj/machinery/blackbox_recorder/attackby(obj/item/attacking_item, mob/living/user, params)
|
||||
if(istype(attacking_item, /obj/item/blackbox))
|
||||
if(HAS_TRAIT(attacking_item, TRAIT_NODROP) || !user.transferItemToLoc(attacking_item, src))
|
||||
to_chat(user, span_warning("[attacking_item] is stuck to your hand!"))
|
||||
return
|
||||
user.visible_message(span_notice("[user] clicks [I] into [src]!"), \
|
||||
user.visible_message(span_notice("[user] clicks [attacking_item] into [src]!"), \
|
||||
span_notice("You press the device into [src], and it clicks into place. The tapes begin spinning again."))
|
||||
playsound(src, 'sound/machines/click.ogg', 50, TRUE)
|
||||
stored = I
|
||||
stored = attacking_item
|
||||
update_appearance()
|
||||
return
|
||||
return ..()
|
||||
@@ -73,26 +68,41 @@
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
|
||||
#define MESSAGE_SERVER_FUNCTIONING_MESSAGE "This is an automated message. The messaging system is functioning correctly."
|
||||
|
||||
// The message server itself.
|
||||
/**
|
||||
* The equivalent of the server, for PDA and request console messages.
|
||||
* Without it, PDA and request console messages cannot be transmitted.
|
||||
* PDAs require the rest of the telecomms setup, but request consoles only
|
||||
* require the message server.
|
||||
*/
|
||||
/obj/machinery/telecomms/message_server
|
||||
icon_state = "message_server"
|
||||
name = "Messaging Server"
|
||||
desc = "A machine that processes and routes PDA and request console messages."
|
||||
icon_state = "message_server"
|
||||
telecomms_type = /obj/machinery/telecomms/message_server
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/telecomms/message_server
|
||||
|
||||
/// A list of all the PDA messages that were intercepted and processed by
|
||||
/// this messaging server.
|
||||
var/list/datum/data_tablet_msg/pda_msgs = list()
|
||||
/// A list of all the Request Console messages that were intercepted and
|
||||
/// processed by this messaging server.
|
||||
var/list/datum/data_rc_msg/rc_msgs = list()
|
||||
/// The password of this messaging server.
|
||||
var/decryptkey = "password"
|
||||
var/calibrating = 15 MINUTES //Init reads this and adds world.time, then becomes 0 when that time has passed and the machine works
|
||||
/// Init reads this and adds world.time, then becomes 0 when that time has
|
||||
/// passed and the machine works.
|
||||
/// Basically, if it's not 0, it's calibrating and therefore non-functional.
|
||||
var/calibrating = 15 MINUTES
|
||||
|
||||
|
||||
#define MESSAGE_SERVER_FUNCTIONING_MESSAGE "This is an automated message. The messaging system is functioning correctly."
|
||||
|
||||
/obj/machinery/telecomms/message_server/Initialize(mapload)
|
||||
. = ..()
|
||||
if (!decryptkey)
|
||||
decryptkey = GenerateKey()
|
||||
decryptkey = generate_key()
|
||||
|
||||
if (calibrating)
|
||||
calibrating += world.time
|
||||
@@ -112,12 +122,16 @@
|
||||
if(calibrating)
|
||||
. += span_warning("It's still calibrating.")
|
||||
|
||||
/obj/machinery/telecomms/message_server/proc/GenerateKey()
|
||||
var/newKey
|
||||
newKey += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le")
|
||||
newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai")
|
||||
newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
|
||||
return newKey
|
||||
/**
|
||||
* Handles generating a key for the message server, returning it. Doesn't assign
|
||||
* it in this proc, you have to do so yourself.
|
||||
*/
|
||||
/obj/machinery/telecomms/message_server/proc/generate_key()
|
||||
var/generated_key
|
||||
generated_key += pick("the", "if", "of", "as", "in", "a", "you", "from", "to", "an", "too", "little", "snow", "dead", "drunk", "rosebud", "duck", "al", "le")
|
||||
generated_key += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai")
|
||||
generated_key += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
|
||||
return generated_key
|
||||
|
||||
/obj/machinery/telecomms/message_server/process()
|
||||
. = ..()
|
||||
@@ -125,6 +139,8 @@
|
||||
calibrating = 0
|
||||
pda_msgs += new /datum/data_tablet_msg("System Administrator", "system", MESSAGE_SERVER_FUNCTIONING_MESSAGE)
|
||||
|
||||
#undef MESSAGE_SERVER_FUNCTIONING_MESSAGE
|
||||
|
||||
/obj/machinery/telecomms/message_server/receive_information(datum/signal/subspace/messaging/signal, obj/machinery/telecomms/machine_from)
|
||||
// can't log non-message signals
|
||||
if(!istype(signal) || !signal.data["message"] || !on || calibrating)
|
||||
@@ -136,8 +152,8 @@
|
||||
var/datum/data_tablet_msg/log_message = new(PDAsignal.format_target(), PDAsignal.format_sender(), PDAsignal.format_message(), PDAsignal.format_photo_path())
|
||||
pda_msgs += log_message
|
||||
else if(istype(signal, /datum/signal/subspace/messaging/rc))
|
||||
var/datum/data_rc_msg/msg = new(signal.data["rec_dpt"], signal.data["send_dpt"], signal.data["message"], signal.data["stamped"], signal.data["verified"], signal.data["priority"])
|
||||
if(signal.data["send_dpt"]) // don't log messages not from a department but allow them to work
|
||||
var/datum/data_rc_msg/msg = new(signal.data["receiving_department"], signal.data["sender_department"], signal.data["message"], signal.data["stamped"], signal.data["verified"], signal.data["priority"])
|
||||
if(signal.data["sender_department"]) // don't log messages not from a department but allow them to work
|
||||
rc_msgs += msg
|
||||
signal.data["reject"] = FALSE
|
||||
|
||||
@@ -151,6 +167,14 @@
|
||||
if(calibrating)
|
||||
. += "message_server_calibrate"
|
||||
|
||||
// Preset messaging server
|
||||
/obj/machinery/telecomms/message_server/preset
|
||||
id = "Messaging Server"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("messaging")
|
||||
decryptkey = null //random
|
||||
calibrating = 0
|
||||
|
||||
|
||||
// Root messaging signal datum
|
||||
/datum/signal/subspace/messaging
|
||||
@@ -160,8 +184,8 @@
|
||||
/datum/signal/subspace/messaging/New(init_source, init_data)
|
||||
source = init_source
|
||||
data = init_data
|
||||
var/turf/T = get_turf(source)
|
||||
levels = SSmapping.get_connected_levels(T)
|
||||
var/turf/origin_turf = get_turf(source)
|
||||
levels = SSmapping.get_connected_levels(origin_turf)
|
||||
if(!("reject" in data))
|
||||
data["reject"] = TRUE
|
||||
|
||||
@@ -172,20 +196,26 @@
|
||||
return copy
|
||||
|
||||
// Tablet message signal datum
|
||||
/// Returns a string representing the target of this message, formatted properly.
|
||||
/datum/signal/subspace/messaging/tablet_message/proc/format_target()
|
||||
if (data["everyone"])
|
||||
return "Everyone"
|
||||
|
||||
var/datum/computer_file/program/messenger/target_app = data["targets"][1]
|
||||
var/obj/item/modular_computer/target = target_app.computer
|
||||
return "[target.saved_identification] ([target.saved_job])"
|
||||
return STRINGIFY_PDA_TARGET(target.saved_identification, target.saved_job)
|
||||
|
||||
/// Returns a string representing the sender of this message, formatted properly.
|
||||
/datum/signal/subspace/messaging/tablet_message/proc/format_sender()
|
||||
var/display_name = get_messenger_name(locate(data["ref"]))
|
||||
return display_name ? display_name : STRINGIFY_PDA_TARGET(data["fakename"], data["fakejob"])
|
||||
|
||||
/// Returns the formatted message contained in this message. Use this to apply
|
||||
/// any processing to it if it needs to be formatted in a specific way.
|
||||
/datum/signal/subspace/messaging/tablet_message/proc/format_message()
|
||||
return data["message"]
|
||||
|
||||
/// Returns the formatted photo path contained in this message, if there's one.
|
||||
/datum/signal/subspace/messaging/tablet_message/proc/format_photo_path()
|
||||
return data["photo"]
|
||||
|
||||
@@ -201,13 +231,19 @@
|
||||
if(ckey(console.department) == recipient_department || (data["ore_update"] && console.receive_ore_updates))
|
||||
console.create_message(data)
|
||||
|
||||
// Log datums stored by the message server.
|
||||
/// Log datums stored by the message server.
|
||||
/datum/data_tablet_msg
|
||||
/// Who sent the message.
|
||||
var/sender = "Unspecified"
|
||||
/// Who was targeted by the message.
|
||||
var/recipient = "Unspecified"
|
||||
var/message = "Blank" // transferred message
|
||||
var/picture_asset_key // attached photo path
|
||||
var/automated = FALSE // automated message
|
||||
/// The transfered message.
|
||||
var/message = "Blank"
|
||||
/// The attached photo path, if any.
|
||||
var/picture_asset_key
|
||||
/// Whether or not it's an automated message. Defaults to `FALSE`.
|
||||
var/automated = FALSE
|
||||
|
||||
|
||||
/datum/data_tablet_msg/New(param_rec, param_sender, param_message, param_photo)
|
||||
if(param_rec)
|
||||
@@ -219,19 +255,32 @@
|
||||
if(param_photo)
|
||||
picture_asset_key = param_photo
|
||||
|
||||
|
||||
#define REQUEST_PRIORITY_NORMAL "Normal"
|
||||
#define REQUEST_PRIORITY_HIGH "High"
|
||||
#define REQUEST_PRIORITY_EXTREME "Extreme"
|
||||
#define REQUEST_PRIORITY_UNDETERMINED "Undetermined"
|
||||
|
||||
|
||||
/datum/data_rc_msg
|
||||
var/rec_dpt = "Unspecified" // receiving department
|
||||
var/send_dpt = "Unspecified" // sending department
|
||||
/// The department that sent the request.
|
||||
var/sender_department = "Unspecified"
|
||||
/// The department that was targeted by the request.
|
||||
var/receiving_department = "Unspecified"
|
||||
/// The message of the request.
|
||||
var/message = "Blank"
|
||||
/// The stamp that authenticated this message, if any.
|
||||
var/stamp = "Unstamped"
|
||||
/// The ID that authenticated this message, if any.
|
||||
var/id_auth = "Unauthenticated"
|
||||
var/priority = "Normal"
|
||||
/// The priority of this request.
|
||||
var/priority = REQUEST_PRIORITY_NORMAL
|
||||
|
||||
/datum/data_rc_msg/New(param_rec, param_sender, param_message, param_stamp, param_id_auth, param_priority)
|
||||
if(param_rec)
|
||||
rec_dpt = param_rec
|
||||
receiving_department = param_rec
|
||||
if(param_sender)
|
||||
send_dpt = param_sender
|
||||
sender_department = param_sender
|
||||
if(param_message)
|
||||
message = param_message
|
||||
if(param_stamp)
|
||||
@@ -241,19 +290,15 @@
|
||||
if(param_priority)
|
||||
switch(param_priority)
|
||||
if(REQ_NORMAL_MESSAGE_PRIORITY)
|
||||
priority = "Normal"
|
||||
priority = REQUEST_PRIORITY_NORMAL
|
||||
if(REQ_HIGH_MESSAGE_PRIORITY)
|
||||
priority = "High"
|
||||
priority = REQUEST_PRIORITY_HIGH
|
||||
if(REQ_EXTREME_MESSAGE_PRIORITY)
|
||||
priority = "Extreme"
|
||||
priority = REQUEST_PRIORITY_EXTREME
|
||||
else
|
||||
priority = "Undetermined"
|
||||
priority = REQUEST_PRIORITY_UNDETERMINED
|
||||
|
||||
#undef MESSAGE_SERVER_FUNCTIONING_MESSAGE
|
||||
|
||||
/obj/machinery/telecomms/message_server/preset
|
||||
id = "Messaging Server"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("messaging")
|
||||
decryptkey = null //random
|
||||
calibrating = 0
|
||||
#undef REQUEST_PRIORITY_NORMAL
|
||||
#undef REQUEST_PRIORITY_HIGH
|
||||
#undef REQUEST_PRIORITY_EXTREME
|
||||
#undef REQUEST_PRIORITY_UNDETERMINED
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
Link to servers if bus is not present
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* They'll link to servers if bus is not present, with some delay added to it.
|
||||
*/
|
||||
/obj/machinery/telecomms/processor
|
||||
name = "processor unit"
|
||||
icon_state = "processor"
|
||||
@@ -14,16 +13,22 @@
|
||||
density = TRUE
|
||||
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.01
|
||||
circuit = /obj/item/circuitboard/machine/telecomms/processor
|
||||
var/process_mode = 1 // 1 = Uncompress Signals, 0 = Compress Signals
|
||||
/// Whether this processor is currently compressing the data,
|
||||
/// or actually decompressing it. Defaults to `FALSE`.
|
||||
var/compressing = FALSE
|
||||
|
||||
#define COMPRESSION_AMOUNT_COMPRESSING 100
|
||||
#define COMPRESSION_AMOUNT_DECOMPRESSING 0
|
||||
|
||||
/obj/machinery/telecomms/processor/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
|
||||
if(!is_freq_listening(signal))
|
||||
return
|
||||
|
||||
if (!process_mode)
|
||||
signal.data["compression"] = 100 // even more compressed signal
|
||||
else if (signal.data["compression"])
|
||||
signal.data["compression"] = 0 // uncompress subspace signal
|
||||
if(compressing)
|
||||
signal.data["compression"] = COMPRESSION_AMOUNT_COMPRESSING // We compress the signal even further.
|
||||
// Otherwise we just fully decompress it if it was compressed to begin with.
|
||||
else if(signal.data["compression"])
|
||||
signal.data["compression"] = COMPRESSION_AMOUNT_DECOMPRESSING
|
||||
|
||||
if(istype(machine_from, /obj/machinery/telecomms/bus))
|
||||
relay_direct_information(signal, machine_from) // send the signal back to the machine
|
||||
@@ -31,7 +36,10 @@
|
||||
signal.data["slow"] += rand(5, 10) // slow the signal down
|
||||
relay_information(signal, signal.server_type)
|
||||
|
||||
//Preset Processors
|
||||
#undef COMPRESSION_AMOUNT_COMPRESSING
|
||||
#undef COMPRESSION_AMOUNT_DECOMPRESSING
|
||||
|
||||
// Preset Processors
|
||||
|
||||
/obj/machinery/telecomms/processor/preset_one
|
||||
id = "Processor 1"
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
The receiver idles and receives messages from subspace-compatible radio equipment;
|
||||
primarily headsets. Then they just relay this information to all linked devices,
|
||||
which would probably be network hubs.
|
||||
|
||||
Link to Processor Units in case receiver can't send to bus units.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The receiver idles and receives messages from subspace-compatible radio equipment,
|
||||
* primarily headsets. Then they just relay this information to all linked devices,
|
||||
* which would usually be through the telecommunications hub.
|
||||
*
|
||||
* Link to Processor Units in case receiver can't send to a telecommunication hub.
|
||||
*/
|
||||
/obj/machinery/telecomms/receiver
|
||||
name = "subspace receiver"
|
||||
icon_state = "broadcast receiver"
|
||||
@@ -27,21 +26,27 @@
|
||||
|
||||
use_power(idle_power_usage)
|
||||
|
||||
/**
|
||||
* Checks whether the signal can be received by this receiver or not, based on
|
||||
* if it's in the signal's `levels`, or if there's a liked hub with a linked
|
||||
* relay that can receive the signal for it.
|
||||
*
|
||||
* Returns `TRUE` if it can receive the signal, `FALSE` if not.
|
||||
*/
|
||||
/obj/machinery/telecomms/receiver/proc/check_receive_level(datum/signal/subspace/signal)
|
||||
if (z in signal.levels)
|
||||
return TRUE
|
||||
|
||||
for(var/obj/machinery/telecomms/hub/H in links)
|
||||
for(var/obj/machinery/telecomms/relay/R in H.links)
|
||||
if(R.can_receive(signal) && (R.z in signal.levels))
|
||||
for(var/obj/machinery/telecomms/hub/linked_hub in links)
|
||||
for(var/obj/machinery/telecomms/relay/linked_relay in linked_hub.links)
|
||||
if(linked_relay.can_receive(signal) && (linked_relay.z in signal.levels))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
//Preset Receivers
|
||||
// Preset Receivers
|
||||
|
||||
//--PRESET LEFT--//
|
||||
|
||||
/obj/machinery/telecomms/receiver/preset_left
|
||||
id = "Receiver A"
|
||||
network = "tcommsat"
|
||||
@@ -50,16 +55,16 @@
|
||||
|
||||
|
||||
//--PRESET RIGHT--//
|
||||
|
||||
/obj/machinery/telecomms/receiver/preset_right
|
||||
id = "Receiver B"
|
||||
network = "tcommsat"
|
||||
autolinkers = list("receiverB") // link to relay
|
||||
freq_listening = list(FREQ_COMMAND, FREQ_ENGINEERING, FREQ_SECURITY)
|
||||
|
||||
//Common and other radio frequencies for people to freely use
|
||||
/obj/machinery/telecomms/receiver/preset_right/Initialize(mapload)
|
||||
. = ..()
|
||||
// Also add common and other freely-available radio frequencies for people
|
||||
// to have access to.
|
||||
for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2)
|
||||
freq_listening |= i
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
The relay idles until it receives information. It then passes on that information
|
||||
depending on where it came from.
|
||||
|
||||
The relay is needed in order to send information pass Z levels. It must be linked
|
||||
with a HUB, the only other machine that can send/receive pass Z levels.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The relay idles until it receives information. It then passes on that information
|
||||
* depending on where it came from.
|
||||
*
|
||||
* The relay is needed in order to send information to different Z levels. It
|
||||
* must be linked with a hub, the only other machine that can send to/receive
|
||||
* from other Z levels.
|
||||
*/
|
||||
/obj/machinery/telecomms/relay
|
||||
name = "telecommunication relay"
|
||||
icon_state = "relay"
|
||||
@@ -14,10 +14,12 @@
|
||||
density = TRUE
|
||||
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.01
|
||||
netspeed = 5
|
||||
long_range_link = 1
|
||||
long_range_link = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/telecomms/relay
|
||||
var/broadcasting = 1
|
||||
var/receiving = 1
|
||||
/// Can this relay broadcast signals to other Z levels?
|
||||
var/broadcasting = TRUE
|
||||
/// Can this relay receive signals from other Z levels?
|
||||
var/receiving = TRUE
|
||||
|
||||
/obj/machinery/telecomms/relay/receive_information(datum/signal/subspace/signal, obj/machinery/telecomms/machine_from)
|
||||
// Add our level and send it back
|
||||
@@ -25,33 +27,49 @@
|
||||
if(can_send(signal) && relay_turf)
|
||||
// Relays send signals to all ZTRAIT_STATION z-levels
|
||||
if(SSmapping.level_trait(relay_turf.z, ZTRAIT_STATION))
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
signal.levels |= SSmapping.get_connected_levels(z)
|
||||
for(var/z_level in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
signal.levels |= SSmapping.get_connected_levels(z_level)
|
||||
else
|
||||
signal.levels |= SSmapping.get_connected_levels(relay_turf)
|
||||
|
||||
use_power(idle_power_usage)
|
||||
|
||||
/// Checks to see if it can send/receive.
|
||||
/obj/machinery/telecomms/relay/proc/can(datum/signal/signal)
|
||||
/**
|
||||
* Checks to see if the relay can send/receive the signal, by checking if it's
|
||||
* on, and if it's listening to the frequency of the signal.
|
||||
*
|
||||
* Returns `TRUE` if it can listen to the signal, `FALSE` if not.
|
||||
*/
|
||||
/obj/machinery/telecomms/relay/proc/can_listen_to_signal(datum/signal/signal)
|
||||
if(!on)
|
||||
return FALSE
|
||||
if(!is_freq_listening(signal))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Checks to see if the relay can send this signal, which requires it to have
|
||||
* `broadcasting` set to `TRUE`.
|
||||
*
|
||||
* Returns `TRUE` if it can send the signal, `FALSE` if not.
|
||||
*/
|
||||
/obj/machinery/telecomms/relay/proc/can_send(datum/signal/signal)
|
||||
if(!can(signal))
|
||||
if(!can_listen_to_signal(signal))
|
||||
return FALSE
|
||||
return broadcasting
|
||||
|
||||
/**
|
||||
* Checks to see if the relay can receive this signal, which requires it to have
|
||||
* `receiving` set to `TRUE`.
|
||||
*
|
||||
* Returns `TRUE` if it can receive the signal, `FALSE` if not.
|
||||
*/
|
||||
/obj/machinery/telecomms/relay/proc/can_receive(datum/signal/signal)
|
||||
if(!can(signal))
|
||||
if(!can_listen_to_signal(signal))
|
||||
return FALSE
|
||||
return receiving
|
||||
|
||||
//Preset Relay
|
||||
|
||||
// Preset Relays
|
||||
/obj/machinery/telecomms/relay/preset
|
||||
network = "tcommsat"
|
||||
|
||||
@@ -78,7 +96,7 @@
|
||||
toggled = FALSE
|
||||
autolinkers = list("r_relay")
|
||||
|
||||
//Generic preset relay
|
||||
// Generic preset relay
|
||||
/obj/machinery/telecomms/relay/preset/auto
|
||||
hide = TRUE
|
||||
autolinkers = list("autorelay")
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
#define MAX_LOG_ENTRIES 400
|
||||
|
||||
/**
|
||||
* The server logs all traffic and signal data. Once it records the signal, it
|
||||
* sends it to the subspace broadcaster.
|
||||
*
|
||||
* Store a maximum of `MAX_LOG_ENTRIES` (400) log entries and then deletes them.
|
||||
*/
|
||||
/obj/machinery/telecomms/server
|
||||
name = "telecommunication server"
|
||||
icon_state = "comm_server"
|
||||
@@ -13,8 +14,13 @@
|
||||
density = TRUE
|
||||
idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.01
|
||||
circuit = /obj/item/circuitboard/machine/telecomms/server
|
||||
/// A list of previous entries on the network. It will not exceed
|
||||
/// `MAX_LOG_ENTRIES` entries in length, flushing the oldest entries
|
||||
/// automatically.
|
||||
var/list/log_entries = list()
|
||||
var/totaltraffic = 0 // gigabytes (if > 1024, divide by 1024 -> terrabytes)
|
||||
/// Total trafic, which is increased every time a signal is increased and
|
||||
/// the current traffic is higher than 0. See `traffic` for more info.
|
||||
var/total_traffic = 0
|
||||
|
||||
/obj/machinery/telecomms/server/receive_information(datum/signal/subspace/vocal/signal, obj/machinery/telecomms/machine_from)
|
||||
// can't log non-vocal signals
|
||||
@@ -22,10 +28,10 @@
|
||||
return
|
||||
|
||||
if(traffic > 0)
|
||||
totaltraffic += traffic // add current traffic to total traffic
|
||||
total_traffic += traffic // add current traffic to total traffic
|
||||
|
||||
// Delete particularly old logs
|
||||
if (log_entries.len >= 400)
|
||||
if (log_entries.len >= MAX_LOG_ENTRIES)
|
||||
log_entries.Cut(1, 2)
|
||||
|
||||
// Don't create a log if the frequency is banned from being logged
|
||||
@@ -39,7 +45,7 @@
|
||||
|
||||
// If the signal is still compressed, make the log entry gibberish
|
||||
var/compression = signal.data["compression"]
|
||||
if(compression > 0)
|
||||
if(compression > NONE)
|
||||
log.input_type = "Corrupt File"
|
||||
var/replace_characters = compression >= 20 ? TRUE : FALSE
|
||||
log.parameters["name"] = Gibberish(signal.data["name"], replace_characters)
|
||||
@@ -47,7 +53,7 @@
|
||||
log.parameters["message"] = Gibberish(signal.data["message"], replace_characters)
|
||||
|
||||
// Give the log a name and store it
|
||||
var/identifier = num2text( rand(-1000,1000) + world.time )
|
||||
var/identifier = num2text(rand(-1000, 1000) + world.time)
|
||||
log.name = "data packet ([md5(identifier)])"
|
||||
log_entries.Add(log)
|
||||
|
||||
@@ -57,11 +63,16 @@
|
||||
|
||||
use_power(idle_power_usage)
|
||||
|
||||
// Simple log entry datum
|
||||
#undef MAX_LOG_ENTRIES
|
||||
|
||||
/// Simple log entry datum for the telecommunication server
|
||||
/datum/comm_log_entry
|
||||
/// Type of entry.
|
||||
var/input_type = "Speech File"
|
||||
/// Name of the entry.
|
||||
var/name = "data packet (#)"
|
||||
var/parameters = list() // copied from signal.data above
|
||||
/// Parameters extracted from the signal.
|
||||
var/parameters = list()
|
||||
|
||||
|
||||
// Preset Servers
|
||||
@@ -98,9 +109,9 @@
|
||||
freq_listening = list()
|
||||
autolinkers = list("common")
|
||||
|
||||
//Common and other radio frequencies for people to freely use
|
||||
/obj/machinery/telecomms/server/presets/common/Initialize(mapload)
|
||||
. = ..()
|
||||
// Common and other radio frequencies for people to freely use
|
||||
for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2)
|
||||
freq_listening |= i
|
||||
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
|
||||
/*
|
||||
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 telecom machines 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.
|
||||
*/
|
||||
|
||||
/// A list of all of the `/obj/machinery/telecomms` (and subtypes) machines
|
||||
/// that exist in the world currently.
|
||||
GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
|
||||
/**
|
||||
* The basic telecomms machinery type, implementing all of the logic that's
|
||||
* shared between all of the telecomms machinery.
|
||||
*/
|
||||
/obj/machinery/telecomms
|
||||
icon = 'icons/obj/machines/telecomms.dmi'
|
||||
critical_machine = TRUE
|
||||
@@ -40,15 +32,16 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
// list of frequencies to tune into: if none, will listen to all
|
||||
var/list/freq_listening = list()
|
||||
|
||||
/// Is it actually active or not?
|
||||
var/on = TRUE
|
||||
/// Is it toggled on
|
||||
/// Is it toggled on, so is it /meant/ to be active?
|
||||
var/toggled = TRUE
|
||||
/// Can you link it across Z levels or on the otherside of the map? (Relay & Hub)
|
||||
var/long_range_link = FALSE
|
||||
/// Is it a hidden machine?
|
||||
var/hide = FALSE
|
||||
|
||||
///Looping sounds for any servers
|
||||
/// Looping sounds for any servers
|
||||
var/datum/looping_sound/server/soundloop
|
||||
|
||||
/// relay signal to all linked machinery that are of type [filter]. If signal has been sent [amount] times, stop sending
|
||||
@@ -90,16 +83,20 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
|
||||
return send_count
|
||||
|
||||
/// Sends a signal directly to a machine.
|
||||
/obj/machinery/telecomms/proc/relay_direct_information(datum/signal/signal, obj/machinery/telecomms/machine)
|
||||
// send signal directly to a machine
|
||||
machine.receive_information(signal, src)
|
||||
|
||||
///receive information from linked machinery
|
||||
/// Receive information from linked machinery
|
||||
/obj/machinery/telecomms/proc/receive_information(datum/signal/signal, obj/machinery/telecomms/machine_from)
|
||||
return
|
||||
|
||||
/**
|
||||
* Checks whether the machinery is listening to that signal.
|
||||
*
|
||||
* Returns `TRUE` if found, `FALSE` if not.
|
||||
*/
|
||||
/obj/machinery/telecomms/proc/is_freq_listening(datum/signal/signal)
|
||||
// return TRUE if found, FALSE if not found
|
||||
return signal && (!length(freq_listening) || (signal.frequency in freq_listening))
|
||||
|
||||
/obj/machinery/telecomms/Initialize(mapload)
|
||||
@@ -122,17 +119,17 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
links = list()
|
||||
return ..()
|
||||
|
||||
/// Used in auto linking
|
||||
/obj/machinery/telecomms/proc/add_automatic_link(obj/machinery/telecomms/T)
|
||||
/// Handles the automatic linking of another machine to this one.
|
||||
/obj/machinery/telecomms/proc/add_automatic_link(obj/machinery/telecomms/machine_to_link)
|
||||
var/turf/position = get_turf(src)
|
||||
var/turf/T_position = get_turf(T)
|
||||
if((position.z != T_position.z) && !(long_range_link && T.long_range_link))
|
||||
var/turf/T_position = get_turf(machine_to_link)
|
||||
if((position.z != T_position.z) && !(long_range_link && machine_to_link.long_range_link))
|
||||
return
|
||||
if(src == T)
|
||||
if(src == machine_to_link)
|
||||
return
|
||||
for(var/autolinker_id in autolinkers)
|
||||
if(autolinker_id in T.autolinkers)
|
||||
add_new_link(T)
|
||||
if(autolinker_id in machine_to_link.autolinkers)
|
||||
add_new_link(machine_to_link)
|
||||
return
|
||||
|
||||
/obj/machinery/telecomms/update_icon_state()
|
||||
@@ -143,6 +140,11 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
update_appearance()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Handles updating the power state of the machine, modifying its `on`
|
||||
* variable based on if it's `toggled` and if it's either broken, has no power
|
||||
* or it's EMP'd. Handles updating appearance based on that power change.
|
||||
*/
|
||||
/obj/machinery/telecomms/proc/update_power()
|
||||
var/old_on = on
|
||||
if(toggled)
|
||||
@@ -167,8 +169,9 @@ GLOBAL_LIST_EMPTY(telecomms_list)
|
||||
return
|
||||
if(prob(100/severity) && !(machine_stat & EMPED))
|
||||
set_machine_stat(machine_stat | EMPED)
|
||||
var/duration = (300 * 10)/severity
|
||||
addtimer(CALLBACK(src, PROC_REF(de_emp)), rand(duration - 20, duration + 20))
|
||||
var/duration = (300 SECONDS)/severity
|
||||
addtimer(CALLBACK(src, PROC_REF(de_emp)), rand(duration - 2 SECONDS, duration + 2 SECONDS))
|
||||
|
||||
/// Handles the machine stopping being affected by an EMP.
|
||||
/obj/machinery/telecomms/proc/de_emp()
|
||||
set_machine_stat(machine_stat & ~EMPED)
|
||||
|
||||
@@ -28,7 +28,7 @@ type Request = {
|
||||
ref: string;
|
||||
message: string;
|
||||
stamp: string;
|
||||
send_dpt: string;
|
||||
sender_department: string;
|
||||
id_auth: string;
|
||||
};
|
||||
|
||||
@@ -75,7 +75,7 @@ const RequestLogsScreen = (props, context) => {
|
||||
</Table.Cell>
|
||||
<Table.Cell>{request.message}</Table.Cell>
|
||||
<Table.Cell>{request.stamp}</Table.Cell>
|
||||
<Table.Cell>{request.send_dpt}</Table.Cell>
|
||||
<Table.Cell>{request.sender_department}</Table.Cell>
|
||||
<Table.Cell>{request.id_auth}</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user