Adds a new NFC component for circuits (#87286)

## About The Pull Request

TODO:
- [x] Main circuit code
- [x] BCI compatibility
- [x] Limiting range in some way(not intended as a private cross map
coms system)


This adds a new NFC component, its similair to NTNet component with the
distinction it will only be received by the shell's circuit you target.
Allowing more targeted networking for things like remotes

I'd love suggestions for a max range, if any. Because im not really
sure. Maby circuit has to be in vision for it to work?

gif is too big so here is direct link to discord embedded gif showing it
off

https://cdn.discordapp.com/attachments/326831214667235328/1296810437295341649/example.gif?ex=6713a455&is=671252d5&hm=f87b282ac71c318eac03b4a53e03ebcfd91e5a0b0a1e9165beb3f87318b96809&

<img
src="https://cdn.discordapp.com/attachments/326831214667235328/1296810437295341649/example.gif?ex=6713a455&is=671252d5&hm=f87b282ac71c318eac03b4a53e03ebcfd91e5a0b0a1e9165beb3f87318b96809&">

## Why It's Good For The Game

NTNet is powerfull for making networked circuits, but I lack a good way
to create a direct "remote" with complex data.
I want to make a circuit that makes it easier to controll other circuits
in a less strictly coupeld way and this seems like a clean way to make
those

## Changelog
🆑
add: A new cirucit component allows NFC communications
/🆑

---------

Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
This commit is contained in:
Autisem
2024-11-02 14:32:54 +01:00
committed by GitHub
co-authored by Ben10Omintrix
parent 0bd5b55de5
commit fec9a5d725
7 changed files with 182 additions and 0 deletions
@@ -0,0 +1,80 @@
/**
* # NFC Receiver Component
*
* Sends a data package through NFC directly to a shell
* if we ever get more shells like BCI's that are nested, keep in mind this may not work correctly unless adjusted
*/
/obj/item/circuit_component/nfc_receive
display_name = "NFC Receiver"
desc = "Receives data packages through NFC. If Encryption Key is set then only signals with the same Encryption Key will be received."
category = "Utility"
circuit_flags = CIRCUIT_FLAG_OUTPUT_SIGNAL //trigger_output
/// The list type
var/datum/port/input/option/list_options
/// Data being received
var/datum/port/output/data_package
/// Encryption key
var/datum/port/input/enc_key
/obj/item/circuit_component/nfc_receive/populate_options()
list_options = add_option_port("List Type", GLOB.wiremod_basic_types)
/obj/item/circuit_component/nfc_receive/populate_ports()
data_package = add_output_port("Data Package", PORT_TYPE_LIST(PORT_TYPE_ANY))
enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING)
/obj/item/circuit_component/nfc_receive/register_shell(atom/movable/shell)
RegisterSignal(shell, COMSIG_CIRCUIT_NFC_DATA_SENT, PROC_REF(nfc_receive))
RegisterSignal(shell, COMSIG_ORGAN_IMPLANTED, PROC_REF(on_organ_implanted))
RegisterSignal(shell, COMSIG_ORGAN_REMOVED, PROC_REF(on_organ_removed))
/obj/item/circuit_component/nfc_receive/unregister_shell(atom/movable/shell)
UnregisterSignal(shell, list(
COMSIG_CIRCUIT_NFC_DATA_SENT,
COMSIG_ORGAN_IMPLANTED,
COMSIG_ORGAN_REMOVED,
))
/obj/item/circuit_component/nfc_receive/proc/on_organ_implanted(datum/source, mob/living/carbon/owner)
SIGNAL_HANDLER
RegisterSignal(owner, COMSIG_CIRCUIT_NFC_DATA_SENT, PROC_REF(nfc_receive))
/obj/item/circuit_component/nfc_receive/proc/on_organ_removed(datum/source, mob/living/carbon/owner)
SIGNAL_HANDLER
UnregisterSignal(owner, COMSIG_CIRCUIT_NFC_DATA_SENT)
/obj/item/circuit_component/nfc_receive/pre_input_received(datum/port/input/port)
if(port == list_options)
var/new_datatype = list_options.value
data_package.set_datatype(PORT_TYPE_LIST(new_datatype))
/obj/item/circuit_component/nfc_receive/proc/nfc_receive(obj/item/circuit_component/source,obj/sender, list/data)
SIGNAL_HANDLER
if(get_dist(sender,parent) >= 10)
return
if(data["enc_key"] != enc_key.value)
return
var/datum/weakref/ref = data["port"]
var/datum/port/input/port = ref?.resolve()
if(!port)
return
var/datum/circuit_datatype/datatype_handler = data_package.datatype_handler
if(!datatype_handler?.can_receive_from_datatype(port.datatype))
return
data_package.set_output(data["data"])
trigger_output.set_output(COMPONENT_SIGNAL)
@@ -0,0 +1,48 @@
/**
* # NFC Transmitter Component
*
* Sends a data package through NFC
* Only the targeted shell will receive the message
*/
/obj/item/circuit_component/nfc_send
display_name = "NFC Transmitter"
desc = "Sends a data package through NTNet. If Encryption Key is set then transmitted data will be only picked up by receivers with the same Encryption Key."
category = "Utility"
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL
/// The list type
var/datum/port/input/option/list_options
/// The targeted circuit
var/datum/port/input/target
/// Data being sent
var/datum/port/input/data_package
/// Encryption key
var/datum/port/input/enc_key
/obj/item/circuit_component/nfc_send/populate_options()
list_options = add_option_port("List Type", GLOB.wiremod_basic_types)
/obj/item/circuit_component/nfc_send/populate_ports()
data_package = add_input_port("Data Package", PORT_TYPE_LIST(PORT_TYPE_ANY))
enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING)
target = add_input_port("Target", PORT_TYPE_ATOM)
/obj/item/circuit_component/nfc_send/should_receive_input(datum/port/input/port)
. = ..()
if(!.)
return FALSE
/obj/item/circuit_component/nfc_send/pre_input_received(datum/port/input/port)
if(port == list_options)
var/new_datatype = list_options.value
data_package.set_datatype(PORT_TYPE_LIST(new_datatype))
/obj/item/circuit_component/nfc_send/input_received(datum/port/input/port)
if(isatom(target.value))
var/atom/target_enty = target.value
SEND_SIGNAL(target_enty, COMSIG_CIRCUIT_NFC_DATA_SENT, parent, list("data" = data_package.value, "enc_key" = enc_key.value, "port" = WEAKREF(data_package)))
@@ -0,0 +1,36 @@
/**
* # NFC Transmitter List Literal Component
*
* Create a list literal and send a data package through NFC
*
* This file is based off of nfc_sendl.dm
* Any changes made to those files should be copied over with discretion
*/
/obj/item/circuit_component/list_literal/nfc_send
display_name = "NFC Transmitter List Literal"
desc = "Creates a list literal data package and sends it through NFC. If Encryption Key is set then transmitted data will be only picked up by receivers with the same Encryption Key."
category = "Utility"
/// Encryption key
var/datum/port/input/enc_key
/// The targeted circuit
var/datum/port/input/target
/obj/item/circuit_component/list_literal/nfc_send/populate_ports()
. = ..()
enc_key = add_input_port("Encryption Key", PORT_TYPE_STRING)
target = add_input_port("Target", PORT_TYPE_ATOM)
/obj/item/circuit_component/list_literal/nfc_send/should_receive_input(datum/port/input/port)
. = ..()
if(!.)
return FALSE
/// If the server is down, don't use power or attempt to send data
return find_functional_ntnet_relay()
/obj/item/circuit_component/list_literal/nfc_send/input_received(datum/port/input/port)
. = ..()
if(isatom(target.value))
var/atom/target_enty = target.value
SEND_SIGNAL(target_enty, COMSIG_CIRCUIT_NFC_DATA_SENT, list("data" = list_output.value, "enc_key" = enc_key.value, "port" = WEAKREF(list_output)))