Adds USB to arrest consoles. Adds list circuit components. (#59850)

Co-authored-by: Watermelon914 <3052169-Watermelon914@users.noreply.gitlab.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
Watermelon914
2021-06-29 13:23:14 -07:00
committed by GitHub
co-authored by Watermelon914 Mothblocks
parent b2285bf29b
commit 7e9e2df721
22 changed files with 560 additions and 51 deletions
+11 -2
View File
@@ -1,5 +1,3 @@
#define PORT_INPUT_RECEIVE_DELAY 0.2 SECONDS
/// Helper define that can only be used in /obj/item/circuit_component/input_received()
#define COMPONENT_TRIGGERED_BY(trigger, port) (trigger.input_value && trigger == port)
@@ -21,6 +19,8 @@
#define PORT_TYPE_SIGNAL "signal"
/// List datatype
#define PORT_TYPE_LIST "list"
/// Table datatype. Derivative of list, contains other lists with matching columns.
#define PORT_TYPE_TABLE "table"
// Other datatypes
/// Atom datatype
@@ -88,6 +88,15 @@
#define COMP_RADIO_PUBLIC "public"
#define COMP_RADIO_PRIVATE "private"
// Security Arrest Console
#define COMP_STATE_ARREST "*Arrest*"
#define COMP_STATE_PRISONER "Incarcerated"
#define COMP_STATE_PAROL "Paroled"
#define COMP_STATE_DISCHARGED "Discharged"
#define COMP_STATE_NONE "None"
#define COMP_SECURITY_ARREST_AMOUNT_TO_FLAG 10
// Shells
/// Whether a circuit is stuck on a shell and cannot be removed (by a user)
+32 -1
View File
@@ -1,3 +1,34 @@
TIMER_SUBSYSTEM_DEF(circuit_component)
SUBSYSTEM_DEF(circuit_component)
name = "Circuit Components"
wait = 0.1 SECONDS
priority = FIRE_PRIORITY_DEFAULT
var/list/callbacks_to_invoke = list()
var/list/currentrun = list()
/datum/controller/subsystem/circuit_component/fire(resumed)
if(!resumed)
currentrun = callbacks_to_invoke.Copy()
callbacks_to_invoke.Cut()
while(length(currentrun))
var/datum/callback/to_call = currentrun[1]
currentrun.Cut(1,2)
if(QDELETED(to_call))
continue
to_call.InvokeAsync()
qdel(to_call)
if(MC_TICK_CHECK)
return
/**
* Adds a callback to be invoked when the next fire() is done. Used by the integrated circuit system.
*
* Prevents race conditions as it acts like a queue system.
* Those that registered first will be executed first and those registered last will be executed last.
*/
/datum/controller/subsystem/circuit_component/proc/add_callback(datum/callback/to_call)
callbacks_to_invoke += to_call
+1
View File
@@ -125,6 +125,7 @@
source.balloon_alert(attacker, "this is too large to fit into [parent]!")
return
logic_board.inserter_mind = WEAKREF(attacker.mind)
attach_circuit(logic_board, attacker)
/datum/component/shell/proc/on_multitool_act(atom/source, mob/user, obj/item/tool)
+174
View File
@@ -19,6 +19,180 @@
var/sortBy = "name"
var/order = 1 // -1 = Descending - 1 = Ascending
/obj/machinery/computer/secure_data/Initialize(mapload, obj/item/circuitboard/C)
. = ..()
AddComponent(/datum/component/usb_port, list(
/obj/item/circuit_component/arrest_console_data,
/obj/item/circuit_component/arrest_console_arrest,
))
/obj/item/circuit_component/arrest_console_data
display_name = "Security Records Data"
display_desc = "Outputs the security records data, where it can then be filtered with a Select Query component"
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// The records retrieved
var/datum/port/output/records
/// Sends a signal on failure
var/datum/port/output/on_fail
var/obj/machinery/computer/secure_data/attached_console
/obj/item/circuit_component/arrest_console_data/Initialize()
. = ..()
records = add_output_port("Security Records", PORT_TYPE_TABLE)
on_fail = add_output_port("Failed", PORT_TYPE_SIGNAL)
/obj/item/circuit_component/arrest_console_data/Destroy()
records = null
on_fail = null
return ..()
/obj/item/circuit_component/arrest_console_data/register_usb_parent(atom/movable/parent)
. = ..()
if(istype(parent, /obj/machinery/computer/secure_data))
attached_console = parent
/obj/item/circuit_component/arrest_console_data/unregister_usb_parent(atom/movable/parent)
attached_console = null
return ..()
/obj/item/circuit_component/arrest_console_data/get_ui_notices()
. = ..()
. += create_table_notices(list(
"name",
"id",
"rank",
"arrest_status",
"gender",
"age",
"species",
"fingerprint",
))
/obj/item/circuit_component/arrest_console_data/input_received(datum/port/input/port)
. = ..()
if(.)
return
if(!attached_console || !attached_console.authenticated)
on_fail.set_output(COMPONENT_SIGNAL)
return
if(isnull(GLOB.data_core.general))
on_fail.set_output(COMPONENT_SIGNAL)
return
var/list/new_table = list()
for(var/datum/data/record/player_record as anything in GLOB.data_core.general)
var/list/entry = list()
var/datum/data/record/player_security_record = find_record("id", player_record.fields["id"], GLOB.data_core.security)
if(player_security_record)
entry["arrest_status"] = player_security_record.fields["criminal"]
entry["security_record"] = player_security_record
entry["name"] = player_record.fields["name"]
entry["id"] = player_record.fields["id"]
entry["rank"] = player_record.fields["rank"]
entry["gender"] = player_record.fields["gender"]
entry["age"] = player_record.fields["age"]
entry["species"] = player_record.fields["species"]
entry["fingerprint"] = player_record.fields["fingerprint"]
new_table += list(entry)
records.set_output(new_table)
/obj/item/circuit_component/arrest_console_arrest
display_name = "Security Records Set Status"
display_desc = "Receives a table to use to set people's arrest status. Table should be from the security records data component. If New Status port isn't set, the status will be decided by the options."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// The targets to set the status of.
var/datum/port/input/targets
/// Sets the new status of the targets. If set to null, the status is taken from the options.
var/datum/port/input/new_status
/// Returns the new status set once the setting is complete. Good for locating errors.
var/datum/port/output/new_status_set
/// Sends a signal on failure
var/datum/port/output/on_fail
var/obj/machinery/computer/secure_data/attached_console
/obj/item/circuit_component/arrest_console_arrest/register_usb_parent(atom/movable/parent)
. = ..()
if(istype(parent, /obj/machinery/computer/secure_data))
attached_console = parent
/obj/item/circuit_component/arrest_console_arrest/unregister_usb_parent(atom/movable/parent)
attached_console = null
return ..()
/obj/item/circuit_component/arrest_console_arrest/populate_options()
var/static/list/component_options = list(
COMP_STATE_ARREST,
COMP_STATE_PRISONER,
COMP_STATE_PAROL,
COMP_STATE_DISCHARGED,
COMP_STATE_NONE,
)
options = component_options
/obj/item/circuit_component/arrest_console_arrest/Initialize()
. = ..()
targets = add_input_port("Targets", PORT_TYPE_TABLE)
new_status = add_input_port("New Status", PORT_TYPE_STRING)
new_status_set = add_output_port("Set Status", PORT_TYPE_STRING)
on_fail = add_output_port("Failed", PORT_TYPE_SIGNAL)
/obj/item/circuit_component/arrest_console_arrest/Destroy()
targets = null
new_status = null
new_status_set = null
on_fail = null
return ..()
/obj/item/circuit_component/arrest_console_arrest/input_received(datum/port/input/port)
. = ..()
if(.)
return
if(!attached_console || !attached_console.authenticated)
on_fail.set_output(COMPONENT_SIGNAL)
return
var/status_to_set = new_status.input_value
if(!status_to_set || !(status_to_set in options))
status_to_set = current_option
new_status_set.set_output(status_to_set)
var/list/target_table = targets.input_value
if(!target_table)
on_fail.set_output(COMPONENT_SIGNAL)
return
var/successful_set = 0
var/list/names_of_entries = list()
for(var/list/target in target_table)
var/datum/data/record/sec_record = target["security_record"]
if(!sec_record)
continue
successful_set++
sec_record.fields["criminal"] = status_to_set
names_of_entries += target["name"]
if(successful_set > 0)
investigate_log("[names_of_entries.Join(", ")] have been set to [status_to_set] by [parent.get_creator()].", INVESTIGATE_RECORDS)
if(successful_set > COMP_SECURITY_ARREST_AMOUNT_TO_FLAG)
message_admins("[successful_set] security entries have been set to [status_to_set] by [parent.get_creator_admin()]. [ADMIN_COORDJMP(src)]")
for(var/mob/living/carbon/human/human as anything in GLOB.human_list)
human.sec_hud_set_security_status()
/obj/machinery/computer/secure_data/syndie
icon_keyboard = "syndie_key"
@@ -183,6 +183,26 @@
id = "comp_multiplexer"
build_path = /obj/item/circuit_component/multiplexer
/datum/design/component/get_column
name = "Get Column Component"
id = "comp_get_column"
build_path = /obj/item/circuit_component/get_column
/datum/design/component/index_table
name = "Index Table Component"
id = "comp_index_table"
build_path = /obj/item/circuit_component/index_table
/datum/design/component/concat_list
name = "Concatenate List Component"
id = "comp_concat_list"
build_path = /obj/item/circuit_component/concat_list
/datum/design/component/select_query
name = "Select Query Component"
id = "comp_select_query"
build_path = /obj/item/circuit_component/select
/datum/design/compact_remote_shell
name = "Compact Remote Shell"
desc = "A handheld shell with one big button."
@@ -199,12 +199,15 @@
"comp_combiner",
"comp_comparison",
"comp_concat",
"comp_concat_list",
"comp_delay",
"comp_direction",
"comp_get_column",
"comp_gps",
"comp_health",
"comp_hear",
"comp_index",
"comp_index_table",
"comp_length",
"comp_light",
"comp_logic",
@@ -214,6 +217,7 @@
"comp_radio",
"comp_ram",
"comp_random",
"comp_select_query",
"comp_self",
"comp_species",
"comp_speech",
+32 -10
View File
@@ -218,19 +218,41 @@
. = list()
if(!removable)
. += list(list(
"icon" = "lock",
"content" = "Unremovable",
"color" = "red"
))
. += create_ui_notice("Unremovable", "red", "lock")
if(length(input_ports))
. += list(list(
"icon" = "bolt",
"content" = "Power Usage Per Input: [power_usage_per_input]",
"color" = "orange",
))
. += create_ui_notice("Power Usage Per Input: [power_usage_per_input]", "orange", "bolt")
/**
* Creates a UI notice entry to be used in get_ui_notices()
*
* Returns a list that can then be added to the return list in get_ui_notices()
*/
/obj/item/circuit_component/proc/create_ui_notice(content, color, icon)
SHOULD_BE_PURE(TRUE)
SHOULD_NOT_OVERRIDE(TRUE)
return list(list(
"icon" = icon,
"content" = content,
"color" = color,
))
/**
* Creates a table UI notice entry to be used in get_ui_notices()
*
* Returns a list that can then be added to the return list in get_ui_notices()
* Used by components to list their available columns. Recommended to use at the end of get_ui_notices()
*/
/obj/item/circuit_component/proc/create_table_notices(list/entries)
SHOULD_BE_PURE(TRUE)
SHOULD_NOT_OVERRIDE(TRUE)
. = list()
. += create_ui_notice("Available Columns:", "grey", "question-circle")
for(var/entry in entries)
. += create_ui_notice("Column Name: '[entry]'", "grey", "columns")
/obj/item/circuit_component/proc/register_usb_parent(atom/movable/parent)
return
@@ -24,11 +24,7 @@
/obj/item/circuit_component/light/get_ui_notices()
. = ..()
. += list(list(
"icon" = "lightbulb",
"content" = "Maximum Brightness: [max_power]",
"color" = "orange"
))
. += create_ui_notice("Maximum Brightness: [max_power]", "orange", "lightbulb")
/obj/item/circuit_component/light/Initialize()
. = ..()
@@ -19,11 +19,7 @@
/obj/item/circuit_component/speech/get_ui_notices()
. = ..()
. += list(list(
"icon" = "stopwatch",
"content" = "Speech Cooldown: [DisplayTimeText(speech_cooldown)]",
"color" = "orange",
))
. += create_ui_notice("Speech Cooldown: [DisplayTimeText(speech_cooldown)]", "orange", "stopwatch")
/obj/item/circuit_component/speech/Initialize()
. = ..()
@@ -26,11 +26,7 @@
/obj/item/circuit_component/direction/get_ui_notices()
. = ..()
. += list(list(
"icon" = "info",
"content" = "Maximum Range: [max_range] tiles",
"color" = "orange",
))
. += create_ui_notice("Maximum Range: [max_range] tiles", "orange", "info")
/obj/item/circuit_component/direction/Initialize()
. = ..()
@@ -27,11 +27,7 @@
/obj/item/circuit_component/health/get_ui_notices()
. = ..()
. += list(list(
"icon" = "info",
"content" = "Maximum Range: [max_range] tiles",
"color" = "orange",
))
. += create_ui_notice("Maximum Range: [max_range] tiles", "orange", "info")
/obj/item/circuit_component/health/Initialize()
. = ..()
@@ -0,0 +1,54 @@
/**
* # Concat List Component
*
* Concatenates a list with a separator
*/
/obj/item/circuit_component/concat_list
display_name = "Concatenate List"
display_desc = "A component that joins up a list with a separator into a single string."
/// The input port
var/datum/port/input/list_port
/// The seperator
var/datum/port/input/separator
/// The result from the output
var/datum/port/output/output
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/obj/item/circuit_component/concat_list/Initialize()
. = ..()
list_port = add_input_port("List", PORT_TYPE_LIST)
separator = add_input_port("Seperator", PORT_TYPE_STRING)
output = add_output_port("Output", PORT_TYPE_STRING)
/obj/item/circuit_component/concat_list/Destroy()
list_port = null
separator = null
output = null
return ..()
/obj/item/circuit_component/concat_list/input_received(datum/port/input/port)
. = ..()
if(.)
return
var/seperator = separator.input_value
if(!seperator)
return
var/list/list_input = list_port.input_value
if(!list_input)
return
var/list/text_list = list()
for(var/entry in list_input)
if(isatom(entry))
text_list += PORT_TYPE_ATOM
else
text_list += "[entry]"
output.set_output(text_list.Join(seperator))
@@ -0,0 +1,48 @@
/**
* # Get Column Component
*
* Gets the column of a table and returns it as a regular list.
*/
/obj/item/circuit_component/get_column
display_name = "Get Column"
display_desc = "Gets the column of a table and returns it as a regular list."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// The list to perform the filter on
var/datum/port/input/received_table
/// The name of the column to check
var/datum/port/input/column_name
/// The filtered list
var/datum/port/output/output_list
/obj/item/circuit_component/get_column/Initialize()
. = ..()
received_table = add_input_port("Input", PORT_TYPE_TABLE)
column_name = add_input_port("Column Name", PORT_TYPE_STRING)
output_list = add_output_port("Output", PORT_TYPE_LIST)
/obj/item/circuit_component/get_column/Destroy()
received_table = null
column_name = null
output_list = null
return ..()
/obj/item/circuit_component/get_column/input_received(datum/port/input/port)
. = ..()
if(.)
return
var/list/input_list = received_table.input_value
if(!islist(input_list) || isnum(column_name.input_value))
return
var/list/new_list = list()
for(var/list/entry in input_list)
var/anything = entry[column_name.input_value]
if(islist(anything))
continue
new_list += anything
output_list.set_output(new_list)
@@ -0,0 +1,48 @@
/**
* # Index Table Component
*
* Gets the row of a table using the index inputted. Will return no value if the index is invalid or a proper table is not returned.
*/
/obj/item/circuit_component/index_table
display_name = "Index Table"
display_desc = "Gets the row of a table using the index inputted. Will return no value if the index is invalid or a proper table is not returned."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// The list to perform the filter on
var/datum/port/input/received_table
/// The target index
var/datum/port/input/target_index
/// The filtered list
var/datum/port/output/output_list
/obj/item/circuit_component/index_table/Initialize()
. = ..()
received_table = add_input_port("Input", PORT_TYPE_TABLE)
target_index = add_input_port("Index", PORT_TYPE_NUMBER)
output_list = add_output_port("Output", PORT_TYPE_TABLE)
/obj/item/circuit_component/index_table/Destroy()
received_table = null
target_index = null
output_list = null
return ..()
/obj/item/circuit_component/index_table/input_received(datum/port/input/port)
. = ..()
if(.)
return
var/list/target_list = received_table.input_value
if(!islist(target_list) || !length(target_list))
output_list.set_output(null)
return
var/index = target_index.input_value
if(index < 1 || index > length(target_list))
output_list.set_output(null)
return
output_list.set_output(target_list[index])
@@ -0,0 +1,96 @@
/**
* # Select Component
*
* Selects a list from a list of lists by a specific column. Used only by USBs for communications to and from computers with lists of varying sizes.
*/
/obj/item/circuit_component/select
display_name = "Select Query"
display_desc = "A component used with USB cables that can perform select queries on a list based on the column name selected. The values are then compared with the comparison input."
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
/// The list to perform the filter on
var/datum/port/input/received_table
/// The name of the column to check
var/datum/port/input/column_name
/// The input to compare with
var/datum/port/input/comparison_input
/// The filtered list
var/datum/port/output/filtered_table
var/current_type = PORT_TYPE_ANY
/obj/item/circuit_component/select/populate_options()
var/static/component_options = list(
COMP_COMPARISON_EQUAL,
COMP_COMPARISON_NOT_EQUAL,
COMP_COMPARISON_GREATER_THAN,
COMP_COMPARISON_LESS_THAN,
COMP_COMPARISON_GREATER_THAN_OR_EQUAL,
COMP_COMPARISON_LESS_THAN_OR_EQUAL,
)
options = component_options
/obj/item/circuit_component/select/Initialize()
. = ..()
received_table = add_input_port("Input", PORT_TYPE_TABLE)
column_name = add_input_port("Column Name", PORT_TYPE_STRING)
comparison_input = add_input_port("Comparison Input", PORT_TYPE_ANY)
filtered_table = add_output_port("Output", PORT_TYPE_TABLE)
/obj/item/circuit_component/select/Destroy()
received_table = null
column_name = null
comparison_input = null
filtered_table = null
return ..()
/obj/item/circuit_component/select/input_received(datum/port/input/port)
. = ..()
switch(current_option)
if(COMP_COMPARISON_EQUAL, COMP_COMPARISON_NOT_EQUAL)
if(current_type != PORT_TYPE_ANY)
current_type = PORT_TYPE_ANY
comparison_input.set_datatype(PORT_TYPE_ANY)
else
if(current_type != PORT_TYPE_NUMBER)
current_type = PORT_TYPE_NUMBER
comparison_input.set_datatype(PORT_TYPE_NUMBER)
if(.)
return
var/list/input_list = received_table.input_value
if(!islist(input_list) || isnum(column_name.input_value))
return
var/comparison_value = comparison_input.input_value
var/list/new_list = list()
for(var/list/entry in input_list)
var/anything = entry[column_name.input_value]
if(islist(anything))
continue
if(current_option != COMP_COMPARISON_EQUAL && current_option != COMP_COMPARISON_NOT_EQUAL && !isnum(anything))
continue
var/add_to_list = FALSE
switch(current_option)
if(COMP_COMPARISON_EQUAL)
add_to_list = anything == comparison_value
if(COMP_COMPARISON_NOT_EQUAL)
add_to_list = anything != comparison_value
if(COMP_COMPARISON_GREATER_THAN)
add_to_list = anything > comparison_value
if(COMP_COMPARISON_GREATER_THAN_OR_EQUAL)
add_to_list = anything >= comparison_value
if(COMP_COMPARISON_LESS_THAN)
add_to_list = anything < comparison_value
if(COMP_COMPARISON_LESS_THAN_OR_EQUAL)
add_to_list = anything <= comparison_value
if(add_to_list)
new_list += list(entry)
filtered_table.set_output(new_list)
@@ -15,11 +15,7 @@
/obj/item/circuit_component/clock/get_ui_notices()
. = ..()
. += list(list(
"icon" = "clock",
"content" = "Clock Interval: [DisplayTimeText(COMP_CLOCK_DELAY)]",
"color" = "orange",
))
. += create_ui_notice("Clock Interval: [DisplayTimeText(COMP_CLOCK_DELAY)]", "orange", "clock")
/obj/item/circuit_component/clock/Initialize()
. = ..()
@@ -39,6 +39,6 @@
var/delay = delay_amount.input_value
if(delay > COMP_DELAY_MIN_VALUE)
// Convert delay into deciseconds
addtimer(CALLBACK(output, /datum/port/output.proc/set_output, trigger.input_value), delay*10, timer_subsystem =SScircuit_component)
addtimer(CALLBACK(output, /datum/port/output.proc/set_output, trigger.input_value), delay*10)
else
output.set_output(trigger.input_value)
@@ -35,6 +35,9 @@
/// The current examined component. Used in IntegratedCircuit UI
var/datum/weakref/examined_component
/// Set by the shell. Holds the reference to the owner who inserted the component into the shell.
var/datum/weakref/inserter_mind
/// X position of the examined_component
var/examined_rel_x = 0
@@ -444,3 +447,23 @@
return COMSIG_CANCEL_USB_CABLE_ATTACK
#undef WITHIN_RANGE
/**
* Returns the creator of the integrated circuit. Used in admin messages and other related things.
*/
/obj/item/integrated_circuit/proc/get_creator_admin()
return get_creator(include_link = TRUE)
/**
* Returns the creator of the integrated circuit. Used in admin logs and other related things.
*/
/obj/item/integrated_circuit/proc/get_creator(include_link = FALSE)
var/datum/mind/inserter
if(inserter_mind)
inserter = inserter_mind.resolve()
var/obj/item/card/id/id_card
if(owner_id)
id_card = owner_id.resolve()
return "(Shell: [shell || "*null*"], Inserter: [key_name(inserter, include_link)], Owner ID: [id_card?.name || "*null*"])"
+5 -10
View File
@@ -48,6 +48,8 @@
return "white"
if(PORT_TYPE_SIGNAL)
return "teal"
if(PORT_TYPE_TABLE)
return "grey"
/datum/port/Destroy(force)
if(!force && !QDELETED(connected_component))
@@ -94,8 +96,8 @@
datatype = type_to_set
color = datatype_to_color()
disconnect()
if(connected_component)
SStgui.update_uis(connected_component)
if(connected_component?.parent)
SStgui.update_uis(connected_component.parent)
/**
* Disconnects a port from all other ports
@@ -187,10 +189,6 @@
/// The connected output port
var/datum/port/output/connected_port
/// The delay before updating the input value whenever a modification is made.
/// This does not apply when when the output port is registered
var/input_receive_delay = PORT_INPUT_RECEIVE_DELAY
/// Whether this port triggers an update whenever an output is received.
var/trigger = FALSE
@@ -236,10 +234,7 @@
*/
/datum/port/input/proc/receive_output(datum/port/output/connected_port, new_value)
SIGNAL_HANDLER
if(input_receive_delay)
addtimer(CALLBACK(src, .proc/set_input, new_value), input_receive_delay, timer_subsystem = SScircuit_component)
else
set_input(new_value)
SScircuit_component.add_callback(CALLBACK(src, .proc/set_input, new_value))
/**
* Updates the value of the input
+1 -1
View File
@@ -42,7 +42,7 @@
COOLDOWN_DECLARE(west_delay)
/// Delay between each movement
var/move_delay = PORT_INPUT_RECEIVE_DELAY
var/move_delay = 0.2 SECONDS
/obj/item/circuit_component/bot_circuit/Initialize()
. = ..()
+5 -1
View File
@@ -3584,9 +3584,13 @@
#include "code\modules\wiremod\components\atom\hear.dm"
#include "code\modules\wiremod\components\atom\self.dm"
#include "code\modules\wiremod\components\atom\species.dm"
#include "code\modules\wiremod\components\list\concat.dm"
#include "code\modules\wiremod\components\list\get_column.dm"
#include "code\modules\wiremod\components\list\index.dm"
#include "code\modules\wiremod\components\list\index_table.dm"
#include "code\modules\wiremod\components\list\select.dm"
#include "code\modules\wiremod\components\math\arithmetic.dm"
#include "code\modules\wiremod\components\math\comparison.dm"
#include "code\modules\wiremod\components\math\index.dm"
#include "code\modules\wiremod\components\math\length.dm"
#include "code\modules\wiremod\components\math\logic.dm"
#include "code\modules\wiremod\components\math\not.dm"