-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathbroadcasting.dm
217 lines (177 loc) · 7.09 KB
/
broadcasting.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/**
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
var/server_type = /obj/machinery/telecomms/server
var/datum/signal/subspace/original
var/list/levels
/datum/signal/subspace/New(data)
src.data = data || list()
/datum/signal/subspace/proc/copy()
var/datum/signal/subspace/copy = new
copy.original = src
copy.source = source
copy.levels = levels
copy.frequency = frequency
copy.server_type = server_type
copy.transmission_method = transmission_method
copy.data = data.Copy()
return copy
/datum/signal/subspace/proc/mark_done()
var/datum/signal/subspace/current = src
while (current)
current.data["done"] = TRUE
current = current.original
/datum/signal/subspace/proc/send_to_receivers()
for(var/obj/machinery/telecomms/receiver/R in GLOB.telecomms_list)
R.receive_signal(src.copy(src))
for(var/obj/machinery/telecomms/allinone/R in GLOB.telecomms_list)
R.receive_signal(src.copy(src))
/datum/signal/subspace/proc/broadcast()
set waitfor = FALSE
// Vocal transmissions (i.e. using saycode).
// Despite "subspace" in the name, these transmissions can also be RADIO
// (intercoms and SBRs) or SUPERSPACE (CentCom).
/datum/signal/subspace/vocal
var/atom/movable/virtualspeaker/virt
var/datum/language/language
/datum/signal/subspace/vocal/New(
obj/source, // the originating radio
frequency, // the frequency the signal is taking place on
atom/movable/virtualspeaker/speaker, // representation of the method's speaker
datum/language/language, // the language of the message
message, // the text content of the message
spans, // the list of spans applied to the message
list/message_mods, // the list of modification applied to the message. Whispering, singing, ect
lvls = null //Yogs -- For NTSL. It's the list of Z-levels that should hear this message.
)
src.source = source
src.frequency = frequency
src.language = language
virt = speaker
var/datum/language/lang_instance = GLOB.language_datum_instances[language]
data = list(
"name" = speaker.name,
"job" = speaker.job,
"message" = message,
"compression" = rand(35, 65),
"language" = lang_instance.name,
"spans" = spans,
"mods" = message_mods
)
//Yogs start
if(lvls)
levels = lvls
else
//Yogs end, technically, I guess
levels = SSmapping.get_connected_levels(get_turf_global(source)) // yogs - get_turf_global instead of get_turf
/datum/signal/subspace/vocal/copy()
var/datum/signal/subspace/vocal/copy = new(source, frequency, virt, language)
copy.original = src
copy.data = data.Copy()
copy.levels = levels
return copy
// This is the meat function for making radios hear vocal transmissions.
/datum/signal/subspace/vocal/broadcast()
set waitfor = FALSE
// Perform final composition steps on the message.
var/message = copytext_char(data["message"], 1, MAX_BROADCAST_LEN)
if(!message)
return
var/compression = data["compression"]
if(compression > 0)
message = Gibberish(message, compression + 40)
// Assemble the list of radios
var/list/radios = list()
switch (transmission_method)
if (TRANSMISSION_SUBSPACE)
// Reaches any radios on the levels
for(var/obj/item/radio/R in GLOB.all_radios["[frequency]"])
if(R.can_receive(frequency, levels))
radios += R
// Syndicate radios can hear all well-known radio channels
if (num2text(frequency) in GLOB.reverseradiochannels)
for(var/obj/item/radio/R in GLOB.all_radios["[FREQ_SYNDICATE]"])
if(R.can_receive(FREQ_SYNDICATE, list(R.z)))
radios |= R
if (TRANSMISSION_RADIO)
// Only radios not currently in subspace mode
for(var/obj/item/radio/R in GLOB.all_radios["[frequency]"])
if(!R.subspace_transmission && R.can_receive(frequency, levels))
radios += R
if (TRANSMISSION_SUPERSPACE)
// Only radios which are independent
for(var/obj/item/radio/R in GLOB.all_radios["[frequency]"])
if(R.independent && R.can_receive(frequency, levels))
radios += R
// From the list of radios, find all mobs who can hear those.
var/list/receive = get_mobs_in_radio_ranges(radios)
// Cut out mobs with clients who are admins and have radio chatter disabled.
for(var/mob/R in receive)
if (R.client && R.client.holder && !(R.client.prefs.chat_toggles & CHAT_RADIO))
receive -= R
// Add observers who have ghost radio enabled.
for(var/mob/dead/observer/M in GLOB.player_list)
if(M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTRADIO))
receive |= M
// Render the message and have everybody hear it.
// Always call this on the virtualspeaker to avoid issues.
var/spans = data["spans"]
var/list/message_mods = data["mods"]
var/rendered = virt.compose_message(virt, language, message, frequency, spans)
for(var/atom/movable/hearer in receive)
hearer.Hear(rendered, virt, language, message, frequency, spans, message_mods)
// This following recording is intended for research and feedback in the use of department radio channels
if(length(receive))
SSblackbox.LogBroadcast(frequency)
var/spans_part = ""
if(length(spans))
spans_part = "(spans:"
for(var/S in spans)
spans_part = "[spans_part] [S]"
spans_part = "[spans_part] ) "
var/lang_name = data["language"]
var/log_text = "\[[get_radio_name(frequency)]\] [spans_part]\"[message]\" (language: [lang_name])"
var/mob/source_mob = virt.source
if(istype(source_mob))
source_mob.log_message(log_text, LOG_TELECOMMS)
else
log_telecomms("[virt.source] [log_text] [loc_name(get_turf(virt.source))]")
QDEL_IN(virt, 50) // Make extra sure the virtualspeaker gets qdeleted