Files
VOREStation/code/controllers/subsystems/communications.dm
T
Selis f4bf017921 Unit Test rework & Master/Ticker update (#17912)
* Unit Test rework & Master/Ticker update

* Fixes and working unit testing

* Fixes

* Test fixes and FA update

* Fixed runtimes

* Radio subsystem

* move that glob wherever later

* ident

* CIBUILDING compile option

* Fixed runtimes

* Some changes to the workflow

* CI Split

* More split

* Pathing

* Linters and Annotators

* ci dir fix

* Missing undef fixed

* Enable grep checks

* More test conversions

* More split

* Correct file

* Removes unneeded inputs

* oop

* More dependency changes

* More conversions

* Conversion fixes

* Fixes

* Some assert fixes

* Corrects start gate

* Converted some README.dms to README.mds

* Removes duplicate proc

* Removes unused defines

* Example configs

* fix dll access viol by double calling

* Post-rebase fixes

* Cleans up names global list

* Undef restart counter

* More code/game/ cleanup

* Statpanel update

* Skybox

* add

* Fix ticker

* Roundend fix

* Persistence dependency update

* Reordering

* Reordering

* Reordering

* Initstage fix

* .

* .

* Reorder

* Reorder

* Circle

* Mobs

* Air

* Test fix

* CI Script Fix

* Configs

* More ticker stuff

* This is now in 'reboot world'

* Restart world announcements

* no glob in PreInit

* to define

* Update

* Removed old include

* Make this file normal again

* moved

* test

* shared unit testing objects

* Updates batched_spritesheets and universal_icon

* .

* job data debug

* rm that

* init order

* show us

* .

* i wonder

* .

* .

* urg

* do we not have a job ID?

* .

* rm sleep for now

* updated rust-g linux binaries

* binaries update 2

* binaries update 3

* testing something

* change that

* test something

* .

* .

* .

* locavar

* test

* move that

* .

* debug

* don't run this test

* strack trace it

* cleaner

* .

* .

* cras again

* also comment this out

* return to official rust g

* Update robot_icons.dm

* monitor the generation

* .

---------

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
2025-08-10 01:37:23 +02:00

208 lines
7.2 KiB
Plaintext

/*
HOW IT WORKS
The SSradio is a global object maintaining all radio transmissions, think about it as about "ether".
Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way.
procs:
add_object(obj/device as obj, var/new_frequency as num, var/radio_filter as text|null = null)
Adds listening object.
parameters:
device - device receiving signals, must have proc receive_signal (see description below).
one device may listen several frequencies, but not same frequency twice.
new_frequency - see possibly frequencies below;
radio_filter - thing for optimization. Optional, but recommended.
All filters should be consolidated in this file, see defines later.
Device without listening filter will receive all signals (on specified frequency).
Device with filter will receive any signals sent without filter.
Device with filter will not receive any signals sent with different filter.
returns:
Reference to frequency object.
remove_object (obj/device, old_frequency)
Obliviously, after calling this proc, device will not receive any signals on old_frequency.
Other frequencies will left unaffected.
return_frequency(var/frequency as num)
returns:
Reference to frequency object. Use it if you need to send and do not need to listen.
radio_frequency is a global object maintaining list of devices that listening specific frequency.
procs:
post_signal(obj/source as obj|null, datum/signal/signal, var/radio_filter as text|null = null, var/range as num|null = null)
Sends signal to all devices that wants such signal.
parameters:
source - object, emitted signal. Usually, devices will not receive their own signals.
signal - see description below.
radio_filter - described above.
range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels.
obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param)
Handler from received signals. By default does nothing. Define your own for your object.
Avoid of sending signals directly from this proc, use spawn(-1). DO NOT use sleep() here or call procs that sleep please. If you must, use spawn()
parameters:
signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return!
receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO.
TRANSMISSION_WIRE is currently unused.
receive_param - for TRANSMISSION_RADIO here comes frequency.
datum/signal
vars:
source
an object that emitted signal. Used for debug and bearing.
data
list with transmitting data. Usual use pattern:
data["msg"] = "hello world"
encryption
Some number symbolizing "encryption key".
Note that game actually do not use any cryptography here.
If receiving object don't know right key, it must ignore encrypted signal in its receive_signal.
*/
SUBSYSTEM_DEF(radio)
name = "Radio"
flags = SS_NO_FIRE
dependencies = list(
/datum/controller/subsystem/machines
)
var/list/datum/radio_frequency/frequencies = list()
/datum/controller/subsystem/radio/Initialize()
GLOB.autospeaker = new (null, FALSE, null, null, TRUE) //Set up Global Announcer
return SS_INIT_SUCCESS
/datum/controller/subsystem/radio/proc/add_object(obj/device as obj, var/new_frequency as num, var/radio_filter = null as text|null)
var/f_text = num2text(new_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
if(!frequency)
frequency = new
frequency.frequency = new_frequency
frequencies[f_text] = frequency
frequency.add_listener(device, radio_filter)
return frequency
/datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency)
var/f_text = num2text(old_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
if(frequency)
frequency.remove_listener(device)
if(frequency.devices.len == 0)
qdel(frequency)
frequencies -= f_text
return 1
/datum/controller/subsystem/radio/proc/return_frequency(var/new_frequency as num)
var/f_text = num2text(new_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
if(!frequency)
frequency = new
frequency.frequency = new_frequency
frequencies[f_text] = frequency
return frequency
//Frequency channels
/datum/radio_frequency
var/frequency as num
var/list/list/obj/devices = list()
/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, var/radio_filter = null as text|null, var/range = null as num|null)
var/turf/start_point
if(range)
start_point = get_turf(source)
if(!start_point)
qdel(signal)
return 0
if (radio_filter)
send_to_filter(source, signal, radio_filter, start_point, range)
send_to_filter(source, signal, RADIO_DEFAULT, start_point, range)
else
//Broadcast the signal to everyone!
for (var/next_filter in devices)
send_to_filter(source, signal, next_filter, start_point, range)
//Sends a signal to all machines belonging to a given filter. Should be called by post_signal()
/datum/radio_frequency/proc/send_to_filter(obj/source, datum/signal/signal, var/radio_filter, var/turf/start_point = null, var/range = null)
if (range && !start_point)
return
for(var/obj/device in devices[radio_filter])
if(device == source)
continue
if(range)
var/turf/end_point = get_turf(device)
if(!end_point)
continue
if(start_point.z!=end_point.z || get_dist(start_point, end_point) > range)
continue
device.receive_signal(signal, TRANSMISSION_RADIO, frequency)
/datum/radio_frequency/proc/add_listener(obj/device as obj, var/radio_filter as text|null)
if (!radio_filter)
radio_filter = RADIO_DEFAULT
//log_admin("add_listener(device=[device],radio_filter=[radio_filter]) frequency=[frequency]")
var/list/obj/devices_line = devices[radio_filter]
if (!devices_line)
devices_line = new
devices[radio_filter] = devices_line
devices_line+=device
// var/list/obj/devices_line___ = devices[filter_str]
// var/l = devices_line___.len
//log_admin("DEBUG: devices_line.len=[devices_line.len]")
//log_admin("DEBUG: devices(filter_str).len=[l]")
/datum/radio_frequency/proc/remove_listener(obj/device)
for (var/devices_filter in devices)
var/list/devices_line = devices[devices_filter]
devices_line-=device
while (null in devices_line)
devices_line -= null
if (devices_line.len==0)
devices -= devices_filter
/datum/signal
var/obj/source
var/transmission_method = 0 //unused at the moment
//0 = wire
//1 = radio transmission
//2 = subspace transmission
var/list/data = list()
var/encryption
var/frequency = 0
/datum/signal/proc/copy_from(datum/signal/model)
source = model.source
transmission_method = model.transmission_method
data = model.data
encryption = model.encryption
frequency = model.frequency
/datum/signal/proc/debug_print()
if (source)
. = "signal = {source = '[source]' ([source:x],[source:y],[source:z])\n"
else
. = "signal = {source = '[source]' ()\n"
for (var/i in data)
. += "data\[\"[i]\"\] = \"[data[i]]\"\n"
if(islist(data[i]))
var/list/L = data[i]
for(var/t in L)
. += "data\[\"[i]\"\] list has: [t]"
//callback used by objects to react to incoming radio signals
/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param)
return null