mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
[READY]integrated circuitry port+upgrade.
This commit is contained in:
committed by
CitadelStationBot
parent
4afc4f5b39
commit
d8847ea167
41
code/__DEFINES/integrated_electronics.dm
Normal file
41
code/__DEFINES/integrated_electronics.dm
Normal file
@@ -0,0 +1,41 @@
|
||||
#define IC_INPUT "input"
|
||||
#define IC_OUTPUT "output"
|
||||
#define IC_ACTIVATOR "activator"
|
||||
|
||||
// Pin functionality.
|
||||
#define DATA_CHANNEL "data channel"
|
||||
#define PULSE_CHANNEL "pulse channel"
|
||||
|
||||
// Methods of obtaining a circuit.
|
||||
#define IC_SPAWN_DEFAULT 1 // If the circuit comes in the default circuit box and able to be printed in the IC printer.
|
||||
#define IC_SPAWN_RESEARCH 2 // If the circuit design will be available in the IC printer after upgrading it.
|
||||
|
||||
// Displayed along with the pin name to show what type of pin it is.
|
||||
#define IC_FORMAT_ANY "\<ANY\>"
|
||||
#define IC_FORMAT_STRING "\<TEXT\>"
|
||||
#define IC_FORMAT_CHAR "\<CHAR\>"
|
||||
#define IC_FORMAT_COLOR "\<COLOR\>"
|
||||
#define IC_FORMAT_NUMBER "\<NUM\>"
|
||||
#define IC_FORMAT_DIR "\<DIR\>"
|
||||
#define IC_FORMAT_BOOLEAN "\<BOOL\>"
|
||||
#define IC_FORMAT_REF "\<REF\>"
|
||||
#define IC_FORMAT_LIST "\<LIST\>"
|
||||
|
||||
#define IC_FORMAT_PULSE "\<PULSE\>"
|
||||
|
||||
// Used inside input/output list to tell the constructor what pin to make.
|
||||
#define IC_PINTYPE_ANY /datum/integrated_io
|
||||
#define IC_PINTYPE_STRING /datum/integrated_io/string
|
||||
#define IC_PINTYPE_CHAR /datum/integrated_io/char
|
||||
#define IC_PINTYPE_COLOR /datum/integrated_io/color
|
||||
#define IC_PINTYPE_NUMBER /datum/integrated_io/number
|
||||
#define IC_PINTYPE_DIR /datum/integrated_io/dir
|
||||
#define IC_PINTYPE_BOOLEAN /datum/integrated_io/boolean
|
||||
#define IC_PINTYPE_REF /datum/integrated_io/ref
|
||||
#define IC_PINTYPE_LIST /datum/integrated_io/lists
|
||||
|
||||
#define IC_PINTYPE_PULSE_IN /datum/integrated_io/activate
|
||||
#define IC_PINTYPE_PULSE_OUT /datum/integrated_io/activate/out
|
||||
|
||||
// Data limits.
|
||||
#define IC_MAX_LIST_LENGTH 500
|
||||
@@ -12,6 +12,7 @@
|
||||
#define INVESTIGATE_PORTAL "portals"
|
||||
#define INVESTIGATE_HALLUCINATIONS "hallucinations"
|
||||
#define INVESTIGATE_RADIATION "radiation"
|
||||
#define INVESTIGATE_EXONET "exonet"
|
||||
|
||||
//Individual logging defines
|
||||
#define INDIVIDUAL_ATTACK_LOG "Attack log"
|
||||
|
||||
@@ -475,3 +475,6 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
|
||||
#define MAX_PROC_DEPTH 195 // 200 proc calls deep and shit breaks, this is a bit lower to give some safety room
|
||||
|
||||
#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation"
|
||||
|
||||
#define SYRINGE_DRAW 0
|
||||
#define SYRINGE_INJECT 1
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#define INIT_ORDER_ATOMS 11
|
||||
#define INIT_ORDER_LANGUAGE 10
|
||||
#define INIT_ORDER_MACHINES 9
|
||||
#define INIT_ORDER_CIRCUIT 8
|
||||
#define INIT_ORDER_TIMER 1
|
||||
#define INIT_ORDER_DEFAULT 0
|
||||
#define INIT_ORDER_AIR -1
|
||||
|
||||
@@ -578,3 +578,23 @@
|
||||
return "turf"
|
||||
else //regex everything else (works for /proc too)
|
||||
return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", ""))
|
||||
|
||||
/proc/strtohex(str)
|
||||
if(!istext(str)||!str)
|
||||
return
|
||||
var/r
|
||||
var/c
|
||||
for(var/i = 1 to length(str))
|
||||
c= text2ascii(str,i)
|
||||
r+= num2hex(c)
|
||||
return r
|
||||
|
||||
/proc/hextostr(str)
|
||||
if(!istext(str)||!str)
|
||||
return
|
||||
var/r
|
||||
var/c
|
||||
for(var/i = 1 to length(str)/2)
|
||||
c= hex2num(copytext(str,i*2-1,i*2+1))
|
||||
r+= ascii2text(c)
|
||||
return r
|
||||
@@ -506,6 +506,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
/*
|
||||
Gets all contents of contents and returns them all in a list.
|
||||
*/
|
||||
|
||||
/atom/proc/GetAllContents()
|
||||
var/list/processing_list = list(src)
|
||||
var/list/assembled = list()
|
||||
@@ -1425,6 +1426,46 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
/proc/turf_z_is_planet(turf/T)
|
||||
return GLOB.z_is_planet["[T.z]"]
|
||||
|
||||
|
||||
//same as do_mob except for movables and it allows both to drift and doesn't draw progressbar
|
||||
/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null)
|
||||
if(!user || !target)
|
||||
return TRUE
|
||||
var/user_loc = user.loc
|
||||
|
||||
var/drifting = FALSE
|
||||
if(!user.Process_Spacemove(0) && user.inertia_dir)
|
||||
drifting = TRUE
|
||||
|
||||
var/target_drifting = FALSE
|
||||
if(!target.Process_Spacemove(0) && target.inertia_dir)
|
||||
target_drifting = TRUE
|
||||
|
||||
var/target_loc = target.loc
|
||||
|
||||
var/endtime = world.time+time
|
||||
// var/starttime = world.time
|
||||
. = TRUE
|
||||
while (world.time < endtime)
|
||||
stoplag(1)
|
||||
if(QDELETED(user) || QDELETED(target))
|
||||
. = 0
|
||||
break
|
||||
if(uninterruptible)
|
||||
continue
|
||||
|
||||
if(drifting && !user.inertia_dir)
|
||||
drifting = FALSE
|
||||
user_loc = user.loc
|
||||
|
||||
if(target_drifting && !target.inertia_dir)
|
||||
target_drifting = FALSE
|
||||
target_loc = target.loc
|
||||
|
||||
if((!drifting && user.loc != user_loc) || (!target_drifting && target.loc != target_loc) || (extra_checks && !extra_checks.Invoke()))
|
||||
. = FALSE
|
||||
break
|
||||
|
||||
//returns a GUID like identifier (using a mostly made up record format)
|
||||
//guids are not on their own suitable for access or security tokens, as most of their bits are predictable.
|
||||
// (But may make a nice salt to one)
|
||||
|
||||
@@ -262,3 +262,5 @@ CONFIG_DEF(number/emergency_shuttle_autocall_threshold)
|
||||
min_val = 0
|
||||
max_val = 1
|
||||
integer = FALSE
|
||||
|
||||
CONFIG_DEF(flag/ic_printing)
|
||||
70
code/controllers/subsystem/processing/circuit.dm
Normal file
70
code/controllers/subsystem/processing/circuit.dm
Normal file
@@ -0,0 +1,70 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(circuit)
|
||||
name = "Circuit"
|
||||
stat_tag = "CIR"
|
||||
init_order = INIT_ORDER_CIRCUIT
|
||||
flags = NONE
|
||||
|
||||
var/cipherkey
|
||||
|
||||
var/list/all_exonet_connections = list() //Address = connection datum.
|
||||
var/list/obj/machinery/exonet_node/all_exonet_nodes = list()
|
||||
|
||||
var/list/all_circuits = list() // Associative list of [circuit_name]:[circuit_path] pairs
|
||||
var/list/circuit_fabricator_recipe_list = list() // Associative list of [category_name]:[list_of_circuit_paths] pairs
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/Initialize(start_timeofday)
|
||||
SScircuit.cipherkey = random_string(2000+rand(0,10), GLOB.alphabet)
|
||||
circuits_init()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/circuits_init()
|
||||
//Cached lists for free performance
|
||||
var/list/all_circuits = src.all_circuits
|
||||
var/list/circuit_fabricator_recipe_list = src.circuit_fabricator_recipe_list
|
||||
for(var/path in typesof(/obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = path
|
||||
var/name = initial(IC.name)
|
||||
all_circuits[name] = IC // Populating the complete list
|
||||
|
||||
if(!(initial(IC.spawn_flags) & (IC_SPAWN_DEFAULT | IC_SPAWN_RESEARCH)))
|
||||
continue
|
||||
|
||||
var/category = initial(IC.category_text)
|
||||
if(!circuit_fabricator_recipe_list[category])
|
||||
circuit_fabricator_recipe_list[category] = list()
|
||||
var/list/category_list = circuit_fabricator_recipe_list[category]
|
||||
category_list += IC // Populating the fabricator categories
|
||||
|
||||
circuit_fabricator_recipe_list["Assemblies"] = list(
|
||||
/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
//new /obj/item/weapon/implant/integrated_circuit,
|
||||
//new /obj/item/device/assembly/electronic_assembly
|
||||
)
|
||||
|
||||
circuit_fabricator_recipe_list["Tools"] = list(
|
||||
/obj/item/device/integrated_electronics/wirer,
|
||||
/obj/item/device/integrated_electronics/debugger,
|
||||
/obj/item/device/integrated_electronics/analyzer
|
||||
)
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_exonet_node()
|
||||
for(var/i in 1 to all_exonet_nodes.len)
|
||||
var/obj/machinery/exonet_node/E = all_exonet_nodes[i]
|
||||
if(E.is_operating())
|
||||
return E
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_exonet_address(addr)
|
||||
return all_exonet_connections[addr]
|
||||
|
||||
|
||||
// Proc: get_atom_from_address()
|
||||
// Parameters: 1 (target_address - the desired address to find)
|
||||
// Description: Searches an address for the atom it is attached for, otherwise returns null.
|
||||
|
||||
/datum/controller/subsystem/processing/circuit/proc/get_atom_from_address(var/target_address)
|
||||
var/datum/exonet_protocol/exonet = SScircuit.get_exonet_address(target_address)
|
||||
if(exonet)
|
||||
return exonet.holder
|
||||
113
code/datums/EPv2.dm
Normal file
113
code/datums/EPv2.dm
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
Exonet Protocol Version 2
|
||||
|
||||
This is designed to be a fairly simple fake-networking system, allowing you to send and receive messages
|
||||
between the exonet_protocol datums, and for atoms to react to those messages, based on the contents of the message.
|
||||
Hopefully, this can evolve to be a more robust fake-networking system and allow for some devious network hacking in the future.
|
||||
|
||||
Version 1 never existed.
|
||||
|
||||
*Setting up*
|
||||
|
||||
To set up the exonet link, define a variable on your desired atom it is like this;
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
Afterwards, before you want to do networking, call exonet = New(src), then exonet.make_address(string), and give it a string to hash into the new IP.
|
||||
The reason it needs a string is so you can have the addresses be persistant, assuming no-one already took it first.
|
||||
|
||||
When you're no longer wanting to use the address and want to free it up, like when you want to Destroy() it, you need to call remove_address()
|
||||
Destroy() also automatically calls remove_address().
|
||||
|
||||
*Sending messages*
|
||||
|
||||
To send a message to another datum, you need to know it's EPv2 (fake IP) address. Once you know that, call send_message(), place your
|
||||
intended address in the first argument, then the message in the second. For example, send_message(exonet.address, "ping") will make you
|
||||
ping yourself.
|
||||
|
||||
*Receiving messages*
|
||||
You don't need to do anything special to receive the messages, other than give your target exonet datum an address as well. Once something hits
|
||||
your datum with send_message(), receive_message() is called, and the default action is to call receive_exonet_message() on the datum's holder.
|
||||
You'll want to override receive_exonet_message() on your atom, and define what will occur when the message is received.
|
||||
The receiving atom will receive the origin atom (the atom that sent the message), the origin address, and finally the message itself.
|
||||
It's suggested to start with an if or switch statement for the message, to determine what to do.
|
||||
*/
|
||||
|
||||
/datum/exonet_protocol
|
||||
var/address = "" //Resembles IPv6, but with only five 'groups', e.g. XXXX:XXXX:XXXX:XXXX:XXXX
|
||||
var/atom/holder
|
||||
|
||||
/datum/exonet_protocol/New(var/atom/H)
|
||||
holder = H
|
||||
|
||||
/datum/exonet_protocol/Destroy()
|
||||
remove_address()
|
||||
holder = null
|
||||
return ..()
|
||||
|
||||
// Proc: make_address()
|
||||
// Parameters: 1 (string - used to make into a hash that will be part of the new address)
|
||||
// Description: Allocates a new address based on the string supplied. It results in consistant addresses for each round assuming it is not already taken..
|
||||
/datum/exonet_protocol/proc/make_address(var/string)
|
||||
if(!string)
|
||||
return
|
||||
var/hex = copytext(md5(string),1,25)
|
||||
if(!hex)
|
||||
return
|
||||
var/addr_1 = copytext(hex,1,5)
|
||||
var/addr_2 = copytext(hex,5,9)
|
||||
var/addr_3 = copytext(hex,9,13)
|
||||
var/addr_4 = copytext(hex,13,17)
|
||||
address = "fc00:[addr_1]:[addr_2]:[addr_3]:[addr_4]"
|
||||
if(SScircuit.all_exonet_connections[address])
|
||||
stack_trace("WARNING: Exonet address collision in make_address. Holder type if applicable is [holder? holder.type : "NO HOLDER"]!")
|
||||
SScircuit.all_exonet_connections[address] = src
|
||||
|
||||
|
||||
// Proc: make_arbitrary_address()
|
||||
// Parameters: 1 (new_address - the desired address)
|
||||
// Description: Allocates that specific address, if it is available.
|
||||
/datum/exonet_protocol/proc/make_arbitrary_address(var/new_address)
|
||||
if(new_address)
|
||||
if(new_address == SScircuit.get_exonet_address(new_address) ) //Collision test.
|
||||
return FALSE
|
||||
address = new_address
|
||||
SScircuit.all_exonet_connections[address] = src
|
||||
return TRUE
|
||||
|
||||
|
||||
// Proc: remove_address()
|
||||
// Parameters: None
|
||||
// Description: Deallocates the address, freeing it for use.
|
||||
/datum/exonet_protocol/proc/remove_address()
|
||||
SScircuit.all_exonet_connections -= address
|
||||
address = ""
|
||||
|
||||
|
||||
|
||||
// Proc: send_message()
|
||||
// Parameters: 3 (target_address - the desired address to send the message to, data_type - text stating what the content is meant to be used for,
|
||||
// content - the actual 'message' being sent to the address)
|
||||
// Description: Sends the message to target_address, by calling receive_message() on the desired datum. Returns true if the message is recieved.
|
||||
/datum/exonet_protocol/proc/send_message(var/target_address, var/data_type, var/content)
|
||||
if(!address)
|
||||
return FALSE
|
||||
var/obj/machinery/exonet_node/node = SScircuit.get_exonet_node()
|
||||
if(!node) // Telecomms went boom, ion storm, etc.
|
||||
return FALSE
|
||||
var/datum/exonet_protocol/exonet = SScircuit.get_exonet_address(target_address)
|
||||
if(exonet)
|
||||
node.write_log(address, target_address, data_type, content)
|
||||
return exonet.receive_message(holder, address, data_type, content)
|
||||
|
||||
// Proc: receive_message()
|
||||
// Parameters: 4 (origin_atom - the origin datum's holder, origin_address - the address the message originated from,
|
||||
// data_type - text stating what the content is meant to be used for, content - the actual 'message' being sent from origin_atom)
|
||||
// Description: Called when send_message() successfully reaches the intended datum. By default, calls receive_exonet_message() on the holder atom.
|
||||
/datum/exonet_protocol/proc/receive_message(var/atom/origin_atom, var/origin_address, var/data_type, var/content)
|
||||
holder.receive_exonet_message(origin_atom, origin_address, data_type, content)
|
||||
return TRUE // for send_message()
|
||||
|
||||
// Proc: receive_exonet_message()
|
||||
// Parameters: 3 (origin_atom - the origin datum's holder, origin_address - the address the message originated from, message - the message that was sent)
|
||||
// Description: Override this to make your atom do something when a message is received.
|
||||
/atom/proc/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
return
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/proc/WEAKREF(datum/input)
|
||||
if(istype(input) && !QDELETED(input))
|
||||
if(!input.weak_reference)
|
||||
@@ -16,4 +15,9 @@
|
||||
|
||||
/datum/weakref/proc/resolve()
|
||||
var/datum/D = locate(reference)
|
||||
<<<<<<< HEAD
|
||||
return D.weak_reference == src? D : null
|
||||
=======
|
||||
return (!QDELETED(D) && D.weak_reference == src) ? D : null
|
||||
|
||||
>>>>>>> bdfbafd... [READY]integrated circuitry port+upgrade. (#32481)
|
||||
|
||||
@@ -69,5 +69,4 @@
|
||||
// Motion cameras outside of an "ai monitored" area will use this to detect stuff.
|
||||
if (!area_motion)
|
||||
if(isliving(AM))
|
||||
newTarget(AM)
|
||||
|
||||
newTarget(AM)
|
||||
106
code/game/machinery/exonet_node.dm
Normal file
106
code/game/machinery/exonet_node.dm
Normal file
@@ -0,0 +1,106 @@
|
||||
/obj/machinery/exonet_node
|
||||
name = "exonet node"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "exonet_node"
|
||||
idle_power_usage = 25
|
||||
var/on = TRUE
|
||||
var/toggle = TRUE
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/exonet_node
|
||||
max_integrity = 300
|
||||
integrity_failure = 100
|
||||
armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70)
|
||||
desc = "This machine is exonet node."
|
||||
var/list/logs = list() // Gets written to by exonet's send_message() function.
|
||||
var/opened = FALSE
|
||||
|
||||
/obj/machinery/exonet_node/Initialize()
|
||||
. = ..()
|
||||
SScircuit.all_exonet_nodes += src
|
||||
|
||||
/obj/machinery/exonet_node/Destroy()
|
||||
SScircuit.all_exonet_nodes -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/exonet_node/proc/is_operating()
|
||||
return on && !stat
|
||||
|
||||
// Proc: update_icon()
|
||||
// Parameters: None
|
||||
// Description: Self explanatory.
|
||||
/obj/machinery/exonet_node/update_icon()
|
||||
icon_state = "[initial(icon_state)][on? "" : "_off"]"
|
||||
|
||||
// Proc: update_power()
|
||||
// Parameters: None
|
||||
// Description: Sets the device on/off and adjusts power draw based on stat and toggle variables.
|
||||
/obj/machinery/exonet_node/proc/update_power()
|
||||
on = is_operational() && toggle
|
||||
use_power = on
|
||||
update_icon()
|
||||
|
||||
// Proc: emp_act()
|
||||
// Parameters: 1 (severity - how strong the EMP is, with lower numbers being stronger)
|
||||
// Description: Shuts off the machine for awhile if an EMP hits it. Ion anomalies also call this to turn it off.
|
||||
/obj/machinery/exonet_node/emp_act(severity)
|
||||
if(!(stat & EMPED))
|
||||
stat |= EMPED
|
||||
var/duration = (300 * 10)/severity
|
||||
addtimer(CALLBACK(src, /obj/machinery/exonet_node/proc/unemp_act), rand(duration - 20, duration + 20))
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/obj/machinery/exonet_node/proc/unemp_act(severity)
|
||||
stat &= ~EMPED
|
||||
|
||||
// Proc: attackby()
|
||||
// Parameters: 2 (I - the item being whacked against the machine, user - the person doing the whacking)
|
||||
// Description: Handles deconstruction.
|
||||
/obj/machinery/exonet_node/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/screwdriver))
|
||||
default_deconstruction_screwdriver(user, I)
|
||||
else if(istype(I, /obj/item/crowbar))
|
||||
default_deconstruction_crowbar(user, I)
|
||||
else
|
||||
return ..()
|
||||
|
||||
// Proc: attack_ai()
|
||||
// Parameters: 1 (user - the AI clicking on the machine)
|
||||
// Description: Redirects to attack_hand()
|
||||
/obj/machinery/exonet_node/attack_ai(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
|
||||
/obj/machinery/exonet_node/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, var/force_open = 1,datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "exonet_node", name, 600, 300, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/exonet_node/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["toggle"] = toggle
|
||||
data["logs"] = logs
|
||||
return data
|
||||
|
||||
/obj/machinery/exonet_node/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("toggle_power")
|
||||
toggle = !toggle
|
||||
update_power()
|
||||
if(!toggle)
|
||||
investigate_log("has been turned off by [key_name(usr)].", INVESTIGATE_EXONET)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
add_fingerprint(usr)
|
||||
|
||||
// Proc: get_exonet_node()
|
||||
// Parameters: None
|
||||
// Description: Helper proc to get a reference to an Exonet node.
|
||||
|
||||
/obj/machinery/exonet_node/proc/write_log(var/origin_address, var/target_address, var/data_type, var/content)
|
||||
var/msg = "[time2text(world.time, "hh:mm:ss")] | FROM [origin_address] TO [target_address] | TYPE: [data_type] | CONTENT: [content]"
|
||||
logs.Add(msg)
|
||||
@@ -193,6 +193,19 @@
|
||||
/obj/item/stack/cable_coil = 1,
|
||||
/obj/item/stock_parts/subspace/filter = 1)
|
||||
|
||||
/obj/item/circuitboard/machine/exonet_node
|
||||
name = "Exonet Node(machine board)"
|
||||
build_path = /obj/machinery/exonet_node
|
||||
origin_tech = "programming=3;engineering=4;bluespace=3;materials=3"
|
||||
req_components = list(
|
||||
/obj/item/stock_parts/subspace/ansible = 1,
|
||||
/obj/item/stock_parts/subspace/filter = 1,
|
||||
/obj/item/stock_parts/manipulator = 2,
|
||||
/obj/item/stock_parts/micro_laser = 1,
|
||||
/obj/item/stock_parts/subspace/crystal = 1,
|
||||
/obj/item/stock_parts/subspace/treatment = 2,
|
||||
/obj/item/stack/cable_coil = 2)
|
||||
|
||||
/obj/item/circuitboard/machine/teleporter_hub
|
||||
name = "Teleporter Hub (Machine Board)"
|
||||
build_path = /obj/machinery/teleport/hub
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
#define PROXIMITY_NONE ""
|
||||
#define PROXIMITY_ON_SCREEN "_red"
|
||||
#define PROXIMITY_NEAR "_yellow"
|
||||
@@ -99,3 +100,172 @@
|
||||
icon_state = "multitool"
|
||||
toolspeed = 0.1
|
||||
origin_tech = "magnets=5;engineering=5;abductor=3"
|
||||
=======
|
||||
#define PROXIMITY_NONE ""
|
||||
#define PROXIMITY_ON_SCREEN "_red"
|
||||
#define PROXIMITY_NEAR "_yellow"
|
||||
|
||||
/**
|
||||
* Multitool -- A multitool is used for hacking electronic devices.
|
||||
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/device/multitool
|
||||
name = "multitool"
|
||||
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
|
||||
icon_state = "multitool"
|
||||
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
|
||||
force = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 0
|
||||
throw_range = 7
|
||||
throw_speed = 3
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=20)
|
||||
origin_tech = "magnets=1;engineering=2"
|
||||
var/obj/machinery/buffer // simple machine buffer for device linkage
|
||||
hitsound = 'sound/weapons/tap.ogg'
|
||||
toolspeed = 1
|
||||
var/datum/integrated_io/selected_io = null //functional for integrated circuits.
|
||||
var/mode = 0
|
||||
|
||||
/obj/item/device/multitool/attack_self(mob/user)
|
||||
if(selected_io)
|
||||
selected_io = null
|
||||
to_chat(user, "<span class='notice'>You clear the wired connection from the multitool.</span>")
|
||||
else
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/multitool/update_icon()
|
||||
if(selected_io)
|
||||
icon_state = "multitool_red"
|
||||
else
|
||||
icon_state = "multitool"
|
||||
|
||||
/obj/item/device/multitool/proc/wire(var/datum/integrated_io/io, mob/user)
|
||||
if(!io.holder.assembly)
|
||||
to_chat(user, "<span class='warning'>\The [io.holder] needs to be secured inside an assembly first.</span>")
|
||||
return
|
||||
|
||||
if(selected_io)
|
||||
if(io == selected_io)
|
||||
to_chat(user, "<span class='warning'>Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.</span>")
|
||||
return
|
||||
if(io.io_type != selected_io.io_type)
|
||||
to_chat(user, "<span class='warning'>Those two types of channels are incompatable. The first is a [selected_io.io_type], \
|
||||
while the second is a [io.io_type].</span>")
|
||||
return
|
||||
if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly)
|
||||
to_chat(user, "<span class='warning'>Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.</span>")
|
||||
return
|
||||
selected_io.linked |= io
|
||||
io.linked |= selected_io
|
||||
|
||||
to_chat(user, "<span class='notice'>You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].</span>")
|
||||
selected_io.holder.interact(user) // This is to update the UI.
|
||||
selected_io = null
|
||||
|
||||
else
|
||||
selected_io = io
|
||||
to_chat(user, "<span class='notice'>You link \the multitool to \the [selected_io.holder]'s [selected_io.name] data channel.</span>")
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/device/multitool/proc/unwire(var/datum/integrated_io/io1, var/datum/integrated_io/io2, mob/user)
|
||||
if(!io1.linked.len || !io2.linked.len)
|
||||
to_chat(user, "<span class='warning'>There is nothing connected to the data channel.</span>")
|
||||
return
|
||||
|
||||
if(!(io1 in io2.linked) || !(io2 in io1.linked) )
|
||||
to_chat(user, "<span class='warning'>These data pins aren't connected!</span>")
|
||||
return
|
||||
else
|
||||
io1.linked.Remove(io2)
|
||||
io2.linked.Remove(io1)
|
||||
to_chat(user, "<span class='notice'>You clip the data connection between the [io1.holder.displayed_name]'s \
|
||||
[io1.name] and the [io2.holder.displayed_name]'s [io2.name].</span>")
|
||||
io1.holder.interact(user) // This is to update the UI.
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
|
||||
|
||||
|
||||
/obj/item/device/multitool/ai_detect
|
||||
var/track_cooldown = 0
|
||||
var/track_delay = 10 //How often it checks for proximity
|
||||
var/detect_state = PROXIMITY_NONE
|
||||
var/rangealert = 8 //Glows red when inside
|
||||
var/rangewarning = 20 //Glows yellow when inside
|
||||
origin_tech = "magnets=1;engineering=2;syndicate=1"
|
||||
|
||||
/obj/item/device/multitool/ai_detect/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/device/multitool/ai_detect/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/multitool/ai_detect/process()
|
||||
if(track_cooldown > world.time)
|
||||
return
|
||||
detect_state = PROXIMITY_NONE
|
||||
multitool_detect()
|
||||
icon_state = "[initial(icon_state)][detect_state]"
|
||||
track_cooldown = world.time + track_delay
|
||||
|
||||
/obj/item/device/multitool/ai_detect/proc/multitool_detect()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
for(var/mob/living/silicon/ai/AI in GLOB.ai_list)
|
||||
if(AI.cameraFollow == src)
|
||||
detect_state = PROXIMITY_ON_SCREEN
|
||||
break
|
||||
|
||||
if(!detect_state && GLOB.cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z))
|
||||
var/datum/camerachunk/chunk = GLOB.cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z)
|
||||
if(chunk)
|
||||
if(chunk.seenby.len)
|
||||
for(var/mob/camera/aiEye/A in chunk.seenby)
|
||||
var/turf/detect_turf = get_turf(A)
|
||||
if(get_dist(our_turf, detect_turf) < rangealert)
|
||||
detect_state = PROXIMITY_ON_SCREEN
|
||||
break
|
||||
if(get_dist(our_turf, detect_turf) < rangewarning)
|
||||
detect_state = PROXIMITY_NEAR
|
||||
break
|
||||
|
||||
/obj/item/device/multitool/ai_detect/admin
|
||||
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors. Has a strange tag that says 'Grief in Safety'." //What else should I say for a meme item?
|
||||
track_delay = 5
|
||||
|
||||
/obj/item/device/multitool/ai_detect/admin/multitool_detect()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
for(var/mob/J in urange(rangewarning,our_turf))
|
||||
if(GLOB.admin_datums[J.ckey])
|
||||
detect_state = PROXIMITY_NEAR
|
||||
var/turf/detect_turf = get_turf(J)
|
||||
if(get_dist(our_turf, detect_turf) < rangealert)
|
||||
detect_state = PROXIMITY_ON_SCREEN
|
||||
break
|
||||
|
||||
/obj/item/device/multitool/cyborg
|
||||
name = "multitool"
|
||||
desc = "Optimised and stripped-down version of a regular multitool."
|
||||
toolspeed = 0.5
|
||||
|
||||
/obj/item/device/multitool/abductor
|
||||
name = "alien multitool"
|
||||
desc = "An omni-technological interface."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "multitool"
|
||||
toolspeed = 0.1
|
||||
origin_tech = "magnets=5;engineering=5;abductor=3"
|
||||
>>>>>>> bdfbafd... [READY]integrated circuitry port+upgrade. (#32481)
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
var/F = file("[GLOB.log_directory]/[subject].html")
|
||||
WRITE_FILE(F, "<small>[time_stamp()] [REF(src)] ([x],[y],[z])</small> || [src] [message]<br>")
|
||||
|
||||
|
||||
/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) )
|
||||
/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) )
|
||||
set name = "Investigate"
|
||||
set category = "Admin"
|
||||
if(!holder)
|
||||
|
||||
103
code/modules/integrated_electronics/core/analyzer.dm
Normal file
103
code/modules/integrated_electronics/core/analyzer.dm
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
|
||||
/obj/item/device/integrated_electronics/analyzer
|
||||
name = "circuit analyzer"
|
||||
desc = "This tool can scan an assembly and generate code necessary to recreate it in a circuit printer."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "analyzer"
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/list/circuit_list = list()
|
||||
var/list/assembly_list = list(/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone)
|
||||
|
||||
/obj/item/device/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user)
|
||||
visible_message( "<span class='notice'>attempt to scan</span>")
|
||||
if(ispath(A.type,/obj/item/device/electronic_assembly))
|
||||
var/i = 0
|
||||
var/j = 0
|
||||
var/HTML ="start.assembly{{*}}" //1-st in chapters.1-st block is just to secure start of program from excess symbols.{{*}} is delimeter for chapters.
|
||||
visible_message( "<span class='notice'>start of scan</span>")
|
||||
for(var/ix in 1 to assembly_list.len)
|
||||
var/obj/item/I = assembly_list[ix]
|
||||
if( A.type == I )
|
||||
HTML += initial(I.name) +"=-="+A.name //2-nd block.assembly type and name. Maybe in future there will also be color and accesories.
|
||||
break
|
||||
/*
|
||||
If(I.name == "electronic implant")
|
||||
var/obj/item/weapon/implant/integrated_circuit/PI = PA //now it can't recreate electronic implants.and devices maybe I'll fix it later.
|
||||
var/obj/item/device/electronic_assembly/implant/PIC = PI.IC
|
||||
A = PIC
|
||||
*/
|
||||
HTML += "{{*}}components" //3-rd block.components. First element is useless.delimeter for elements is ^%^.In element first circuit's default name.Second is user given name.delimiter is =-=
|
||||
|
||||
for(var/obj/item/integrated_circuit/IC in A.contents)
|
||||
i =i + 1
|
||||
HTML += "^%^"+IC.name+"=-="+IC.displayed_name
|
||||
if(i == 0)
|
||||
return
|
||||
HTML += "{{*}}values" //4-th block.values. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second is data type.third is value.delimiter is :+:
|
||||
|
||||
i = 0
|
||||
var/val
|
||||
var/list/inp=list()
|
||||
var/list/out=list()
|
||||
var/list/act=list()
|
||||
var/list/ioa=list()
|
||||
for(var/obj/item/integrated_circuit/IC in A.contents)
|
||||
i += 1
|
||||
if(IC.inputs && IC.inputs.len)
|
||||
for(j in 1 to IC.inputs.len)
|
||||
var/datum/integrated_io/IN =IC.inputs[j]
|
||||
inp[IN] = "[i]i[j]"
|
||||
if(islist(IN.data))
|
||||
val = list2params(IN.data)
|
||||
HTML += "^%^"+"[i]i[j]:+:list:+:[val]"
|
||||
else if(isnum(IN.data))
|
||||
val= IN.data
|
||||
HTML += "^%^"+"[i]i[j]:+:num:+:[val]"
|
||||
else if(istext(IN.data))
|
||||
val = IN.data
|
||||
HTML += "^%^"+"[i]i[j]:+:text:+:[val]"
|
||||
if(IC.outputs && IC.outputs.len)
|
||||
for(j in 1 to IC.outputs.len) //Also this block uses for setting all i/o id's
|
||||
var/datum/integrated_io/OUT = IC.outputs[j]
|
||||
out[OUT] = "[i]o[j]"
|
||||
if(IC.activators && IC.activators.len)
|
||||
for(j in 1 to IC.activators.len)
|
||||
var/datum/integrated_io/ACT = IC.activators[j]
|
||||
act[ACT] = "[i]a[j]"
|
||||
ioa.Add(inp)
|
||||
ioa.Add(out)
|
||||
ioa.Add(act)
|
||||
HTML += "{{*}}wires"
|
||||
if(inp && inp.len)
|
||||
for(i in 1 to inp.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
|
||||
var/datum/integrated_io/P = inp[i]
|
||||
for(j in 1 to P.linked.len)
|
||||
var/datum/integrated_io/C = P.linked[j]
|
||||
HTML += "^%^"+inp[P]+"=-="+ioa[C]
|
||||
if(out && out.len)
|
||||
for(i in 1 to out.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
|
||||
var/datum/integrated_io/P = out[i]
|
||||
for(j in 1 to P.linked.len)
|
||||
var/datum/integrated_io/C = P.linked[j]
|
||||
HTML += "^%^"+out[P]+"=-="+ioa[C]
|
||||
if(act && act.len)
|
||||
for(i in 1 to act.len) //5-th block.wires. First element is useless.delimeter for elements is ^%^.In element first i/o id.Second too.delimiter is =-=
|
||||
var/datum/integrated_io/P = act[i]
|
||||
for(j in 1 to P.linked.len)
|
||||
var/datum/integrated_io/C = P.linked[j]
|
||||
HTML += "^%^"+act[P]+"=-="+ioa[C]
|
||||
|
||||
HTML += "{{*}}end" //6 block.like 1.
|
||||
visible_message( "<span class='notice'>[A] has been scanned,</span>")
|
||||
user << browse(jointext(HTML, null), "window=analyzer;size=[500]x[600];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
342
code/modules/integrated_electronics/core/assemblies.dm
Normal file
342
code/modules/integrated_electronics/core/assemblies.dm
Normal file
@@ -0,0 +1,342 @@
|
||||
#define IC_MAX_SIZE_BASE 25
|
||||
#define IC_COMPLEXITY_BASE 75
|
||||
|
||||
/obj/item/device/electronic_assembly
|
||||
name = "electronic assembly"
|
||||
desc = "It's a case, for building small electronics with."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "setup_small"
|
||||
flags_1 = NOBLUDGEON_1
|
||||
var/max_components = IC_MAX_SIZE_BASE
|
||||
var/max_complexity = IC_COMPLEXITY_BASE
|
||||
var/opened = FALSE
|
||||
var/obj/item/stock_parts/cell/battery // Internal cell which most circuits need to work.
|
||||
var/cell_type = /obj/item/stock_parts/cell
|
||||
var/can_charge = TRUE //Can it be charged in a recharger?
|
||||
var/charge_sections = 4
|
||||
var/charge_tick = FALSE
|
||||
var/charge_delay = 4
|
||||
var/use_cyborg_cell = TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/check_interactivity(mob/user)
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
icon_state = "setup_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_components = IC_MAX_SIZE_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
|
||||
/obj/item/device/electronic_assembly/large
|
||||
name = "electronic machine"
|
||||
icon_state = "setup_large"
|
||||
desc = "It's a case, for building large electronics with."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
max_components = IC_MAX_SIZE_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
anchored = FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/large/attackby(var/obj/item/O, var/mob/user)
|
||||
if(default_unfasten_wrench(user, O, 20))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/large/attack_tk(mob/user)
|
||||
if(anchored)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/large/attack_hand(mob/user)
|
||||
if(anchored)
|
||||
attack_self(user)
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
icon_state = "setup_drone"
|
||||
desc = "It's a case, for building mobile electronics with."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
max_components = IC_MAX_SIZE_BASE * 3
|
||||
max_complexity = IC_COMPLEXITY_BASE * 3
|
||||
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/Initialize()
|
||||
.=..()
|
||||
START_PROCESSING(SScircuit, src)
|
||||
|
||||
/obj/item/device/electronic_assembly/Destroy()
|
||||
STOP_PROCESSING(SScircuit, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/electronic_assembly/process()
|
||||
handle_idle_power()
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/handle_idle_power()
|
||||
// First we generate power.
|
||||
for(var/obj/item/integrated_circuit/passive/power/P in contents)
|
||||
P.make_energy()
|
||||
|
||||
// Now spend it.
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
if(IC.power_draw_idle)
|
||||
if(!draw_power(IC.power_draw_idle))
|
||||
IC.power_fail()
|
||||
|
||||
|
||||
/obj/item/device/electronic_assembly/interact(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
|
||||
var/total_part_size = return_total_size()
|
||||
var/total_complexity = return_total_complexity()
|
||||
var/HTML = list()
|
||||
|
||||
HTML += "<html><head><title>[name]</title></head><body>"
|
||||
HTML += "<br><a href='?src=[REF(src)]'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a><br>"
|
||||
HTML += "[total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.<br>"
|
||||
HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.<br>"
|
||||
if(battery)
|
||||
HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. <a href='?src=[REF(src)];remove_cell=1'>\[Remove\]</a>"
|
||||
else
|
||||
HTML += "<span class='danger'>No powercell detected!</span>"
|
||||
HTML += "<br><br>"
|
||||
HTML += "Components:<hr>"
|
||||
HTML += "Built in:<br>"
|
||||
|
||||
|
||||
//Put removable circuits in separate categories from non-removable
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
if(!circuit.removable)
|
||||
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "<hr>"
|
||||
HTML += "Removable:<br>"
|
||||
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
if(circuit.removable)
|
||||
HTML += "<a href=?src=[REF(circuit)];examine=1;from_assembly=1>[circuit.displayed_name]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];rename=1;from_assembly=1>\[Rename\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];scan=1;from_assembly=1>\[Scan with Debugger\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];remove=1;from_assembly=1>\[Remove\]</a> | "
|
||||
HTML += "<a href=?src=[REF(circuit)];bottom=[REF(circuit)];from_assembly=1>\[Move to Bottom\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
user << browse(jointext(HTML,null), "window=assembly-\[REF(src)];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
/obj/item/device/electronic_assembly/Topic(href, href_list[])
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["rename"])
|
||||
rename(usr)
|
||||
|
||||
if(href_list["remove_cell"])
|
||||
if(!battery)
|
||||
to_chat(usr, "<span class='warning'>There's no power cell to remove from \the [src].</span>")
|
||||
else
|
||||
var/turf/T = get_turf(src)
|
||||
battery.forceMove(T)
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(usr, "<span class='notice'>You pull \the [battery] out of \the [src]'s power supplier.</span>")
|
||||
battery = null
|
||||
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/rename()
|
||||
|
||||
var/mob/M = usr
|
||||
if(!check_interactivity(M))
|
||||
return
|
||||
|
||||
var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text,1)
|
||||
if(!check_interactivity(M))
|
||||
return
|
||||
if(src && input)
|
||||
to_chat(M, "<span class='notice'>The machine now has a label reading '[input]'.</span>")
|
||||
name = input
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/can_move()
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/can_move()
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/update_icon()
|
||||
if(opened)
|
||||
icon_state = initial(icon_state) + "-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/device/electronic_assembly/examine(mob/user)
|
||||
..()
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.external_examine(user)
|
||||
if(istype(IC,/obj/item/integrated_circuit/output/screen))
|
||||
var/obj/item/integrated_circuit/output/screen/S
|
||||
if(S.stuff_to_display)
|
||||
to_chat(user, "There's a little screen labeled '[S]', which displays '[S.stuff_to_display]'.")
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/return_total_complexity()
|
||||
. = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.complexity
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/return_total_size()
|
||||
. = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.size
|
||||
|
||||
// Returns true if the circuit made it inside.
|
||||
/obj/item/device/electronic_assembly/proc/add_circuit(var/obj/item/integrated_circuit/IC, var/mob/user)
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>")
|
||||
return FALSE
|
||||
|
||||
if(IC.w_class > w_class)
|
||||
to_chat(user, "<span class='warning'>\The [IC] is way too big to fit into \the [src].</span>")
|
||||
return FALSE
|
||||
|
||||
var/total_part_size = return_total_size()
|
||||
var/total_complexity = return_total_complexity()
|
||||
|
||||
if((total_part_size + IC.size) > max_components)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add the '[IC]', as there's insufficient space.</span>")
|
||||
return FALSE
|
||||
if((total_complexity + IC.complexity) > max_complexity)
|
||||
to_chat(user, "<span class='warning'>You can't seem to add the '[IC]', since this setup's too complicated for the case.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!user.transferItemToLoc(IC, src))
|
||||
return FALSE
|
||||
|
||||
IC.assembly = src
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
|
||||
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
|
||||
if(!proximity)
|
||||
if(istype(S,/obj/item/integrated_circuit/input/sensor/ranged)||(!user))
|
||||
if(user.client)
|
||||
if(!(target in view(user.client)))
|
||||
continue
|
||||
else
|
||||
if(!(target in view(user)))
|
||||
continue
|
||||
else
|
||||
continue
|
||||
S.set_pin_data(IC_OUTPUT, 1, WEAKREF(target))
|
||||
S.check_then_do_work()
|
||||
S.scan(target)
|
||||
|
||||
visible_message("<span class='notice'> [user] waves [src] around [target].</span>")
|
||||
|
||||
/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/integrated_circuit))
|
||||
if(!user.canUnEquip(I))
|
||||
return FALSE
|
||||
if(add_circuit(I, user))
|
||||
to_chat(user, "<span class='notice'>You slide [I] inside [src].</span>")
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
interact(user)
|
||||
return TRUE
|
||||
else if(istype(I, /obj/item/crowbar))
|
||||
playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
|
||||
opened = !opened
|
||||
to_chat(user, "<span class='notice'>You [opened ? "opened" : "closed"] [src].</span>")
|
||||
update_icon()
|
||||
return TRUE
|
||||
else if(istype(I, /obj/item/device/integrated_electronics/wirer) || istype(I, /obj/item/device/integrated_electronics/debugger) || istype(I, /obj/item/screwdriver))
|
||||
if(opened)
|
||||
interact(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'> [src] isn't opened, so you can't fiddle with the internal components. \
|
||||
Try using a crowbar.</span>")
|
||||
else if(istype(I, /obj/item/stock_parts/cell))
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'> [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>")
|
||||
return FALSE
|
||||
if(battery)
|
||||
to_chat(user, "<span class='warning'> [src] already has \a [battery] inside. Remove it first if you want to replace it.</span>")
|
||||
return FALSE
|
||||
var/obj/item/stock_parts/cell = I
|
||||
user.transferItemToLoc(I, loc)
|
||||
cell.forceMove(src)
|
||||
battery = cell
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
to_chat(user, "<span class='notice'>You slot \the [cell] inside \the [src]'s power supplier.</span>")
|
||||
interact(user)
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/electronic_assembly/attack_self(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
var/list/input_selection = list()
|
||||
var/list/available_inputs = list()
|
||||
for(var/obj/item/integrated_circuit/input/input in contents)
|
||||
if(input.can_be_asked_input)
|
||||
available_inputs.Add(input)
|
||||
var/i = 0
|
||||
for(var/obj/item/integrated_circuit/s in available_inputs)
|
||||
if(s.name == input.name && s.displayed_name == input.displayed_name && s != input)
|
||||
i++
|
||||
var/disp_name= "[input.displayed_name] \[[input]\]"
|
||||
if(i)
|
||||
disp_name += " ([i+1])"
|
||||
input_selection.Add(disp_name)
|
||||
|
||||
var/obj/item/integrated_circuit/input/choice
|
||||
if(available_inputs)
|
||||
if(available_inputs.len ==1)
|
||||
choice = available_inputs[1]
|
||||
else
|
||||
var/selection = input(user, "What do you want to interact with?", "Interaction") as null|anything in input_selection
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
if(selection)
|
||||
var/index = input_selection.Find(selection)
|
||||
choice = available_inputs[index]
|
||||
|
||||
if(choice)
|
||||
choice.ask_for_input(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/emp_act(severity)
|
||||
..()
|
||||
for(var/i in 1 to contents.len)
|
||||
var/atom/movable/AM = contents[i]
|
||||
AM.emp_act(severity)
|
||||
|
||||
// Returns true if power was successfully drawn.
|
||||
/obj/item/device/electronic_assembly/proc/draw_power(amount)
|
||||
if(battery && battery.use(amount * GLOB.CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Ditto for giving.
|
||||
/obj/item/device/electronic_assembly/proc/give_power(amount)
|
||||
if(battery && battery.give(amount * GLOB.CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/Moved(oldLoc, dir)
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.ext_moved(oldLoc, dir)
|
||||
64
code/modules/integrated_electronics/core/debugger.dm
Normal file
64
code/modules/integrated_electronics/core/debugger.dm
Normal file
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger
|
||||
name = "circuit debugger"
|
||||
desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \
|
||||
settings to specific circuits, or for debugging purposes. It can also pulse activation pins."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "debugger"
|
||||
flags_1 = CONDUCT_1 | NOBLUDGEON_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/data_to_write = null
|
||||
var/accepting_refs = FALSE
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/attack_self(mob/user)
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null")
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data) && user.IsAdvancedToolUser())
|
||||
data_to_write = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to \"[new_data]\".</span>")
|
||||
if("number")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && user.IsAdvancedToolUser())
|
||||
data_to_write = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [new_data].</span>")
|
||||
if("ref")
|
||||
accepting_refs = TRUE
|
||||
to_chat(user, "<span class='notice'>You turn \the [src]'s ref scanner on. Slide it across \
|
||||
an object for a ref of that object to save it in memory.</span>")
|
||||
if("null")
|
||||
data_to_write = null
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to absolutely nothing.</span>")
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity)
|
||||
if(accepting_refs && proximity)
|
||||
data_to_write = WEAKREF(target)
|
||||
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \
|
||||
now off.</span>")
|
||||
accepting_refs = FALSE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user)
|
||||
if(io.io_type == DATA_CHANNEL)
|
||||
io.write_data_to_pin(data_to_write)
|
||||
var/data_to_show = data_to_write
|
||||
if(isweakref(data_to_write))
|
||||
var/datum/weakref/w = data_to_write
|
||||
var/atom/A = w.resolve()
|
||||
data_to_show = A.name
|
||||
to_chat(user, "<span class='notice'>You write '[data_to_write ? data_to_show : "NULL"]' to the '[io]' pin of \the [io.holder].</span>")
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(user, "<span class='notice'>You pulse \the [io.holder]'s [io].</span>")
|
||||
|
||||
io.holder.interact(user) // This is to update the UI.
|
||||
136
code/modules/integrated_electronics/core/helpers.dm
Normal file
136
code/modules/integrated_electronics/core/helpers.dm
Normal file
@@ -0,0 +1,136 @@
|
||||
/obj/item/integrated_circuit/proc/setup_io(var/list/io_list, var/io_type, var/list/io_default_list)
|
||||
var/list/io_list_copy = io_list.Copy()
|
||||
io_list.Cut()
|
||||
for(var/i in 1 to io_list_copy.len)
|
||||
var/io_entry = io_list_copy[i]
|
||||
var/default_data = null
|
||||
var/io_type_override = null
|
||||
// Override the default data.
|
||||
if(io_default_list && io_default_list.len) // List containing special pin types that need to be added.
|
||||
default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form.
|
||||
// Override the pin type.
|
||||
if(io_list_copy[io_entry])
|
||||
io_type_override = io_list_copy[io_entry]
|
||||
|
||||
if(io_type_override)
|
||||
// world << "io_type_override is now [io_type_override] on [src]."
|
||||
io_list.Add(new io_type_override(src, io_entry, default_data))
|
||||
else
|
||||
io_list.Add(new io_type(src, io_entry, default_data))
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/proc/set_pin_data(var/pin_type, var/pin_number, datum/new_data)
|
||||
if (istype(new_data) && !isweakref(new_data))
|
||||
new_data = WEAKREF(new_data)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
return pin.write_data_to_pin(new_data)
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_data(var/pin_type, var/pin_number)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
return pin.get_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_data_as_type(var/pin_type, var/pin_number, var/as_type)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
return pin.data_as_type(as_type)
|
||||
|
||||
/obj/item/integrated_circuit/proc/activate_pin(var/pin_number)
|
||||
var/datum/integrated_io/activate/A = activators[pin_number]
|
||||
A.push_data()
|
||||
|
||||
/datum/integrated_io/proc/get_data()
|
||||
if(isweakref(data))
|
||||
return data.resolve()
|
||||
return data
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number)
|
||||
switch(pin_type)
|
||||
if(IC_INPUT)
|
||||
if(pin_number > inputs.len)
|
||||
return
|
||||
return inputs[pin_number]
|
||||
if(IC_OUTPUT)
|
||||
if(pin_number > outputs.len)
|
||||
return
|
||||
return outputs[pin_number]
|
||||
if(IC_ACTIVATOR)
|
||||
if(pin_number > activators.len)
|
||||
return
|
||||
return activators[pin_number]
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/handle_wire(var/datum/integrated_io/pin, var/obj/item/device/integrated_electronics/tool)
|
||||
if(istype(tool, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = tool
|
||||
if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
return TRUE
|
||||
|
||||
else if(istype(tool, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/debugger = tool
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/proc/asc2b64(var/S)
|
||||
var/static/list/b64 = list(
|
||||
"A"=0,"B"=1,"C"=2,"D"=3,
|
||||
"E"=4,"F"=5,"G"=6,"H"=7,
|
||||
"I"=8,"J"=9,"K"=10,"L"=11,
|
||||
"M"=12,"N"=13,"O"=14,"P"=15,
|
||||
"Q"=16,"R"=17,"S"=18,"T"=19,
|
||||
"U"=20,"V"=21,"W"=22,"X"=23,
|
||||
"Y"=24,"Z"=25,"a"=26,"b"=27,
|
||||
"c"=28,"d"=29,"e"=30,"f"=31,
|
||||
"g"=32,"h"=33,"i"=34,"j"=35,
|
||||
"k"=36,"l"=37,"m"=38,"n"=39,
|
||||
"o"=40,"p"=41,"q"=42,"r"=43,
|
||||
"s"=44,"t"=45,"u"=46,"v"=47,
|
||||
"w"=48,"x"=49,"y"=50,"z"=51,
|
||||
"0"=52,"1"=53,"2"=54,"3"=55,
|
||||
"4"=56,"5"=57,"6"=58,"7"=59,
|
||||
"8"=60,"9"=61,","=62,"."=63
|
||||
)
|
||||
var/ls = lentext(S)
|
||||
var/c
|
||||
var/i=1
|
||||
while(i <= ls)
|
||||
var/sb1=text2ascii(S,i)
|
||||
var/sb2=text2ascii(S,i+1)
|
||||
var/sb3=text2ascii(S,i+2)
|
||||
var/cb1 = (sb1 & 252)>>2
|
||||
var/cb2 = ((sb1 & 3)<<6 | (sb2 & 240)>>2)>>2
|
||||
var/cb3 = (sb2 & 15)<<2 | (sb3 & 192)>>6
|
||||
var/cb4 = (sb3 & 63)
|
||||
c=c+b64[cb1+1]+b64[cb2+1]+b64[cb3+1]+b64[cb4+1]
|
||||
i=i+3
|
||||
return c
|
||||
|
||||
/obj/item/integrated_circuit/proc/b642asc(var/S)
|
||||
var/static/list/b64 = list("A"=1,"B"=2,"C"=3,"D"=4,"E"=5,"F"=6,"G"=7,"H"=8,"I"=9,"J"=10,"K"=11,"L"=12,"M"=13,"N"=14,"O"=15,"P"=16,"Q"=17,"R"=18,
|
||||
"S"=19,"T"=20,"U"=21,"V"=22,"W"=23,"X"=24,"Y"=25,"Z"=26,"a"=27,"b"=28,"c"=29,"d"=30,"e"=31,"f"=32,"g"=33,"h"=34,"i"=35,"j"=36,"k"=37,"l"=38,"m"=39,"n"=40,"o"=41,
|
||||
"p"=42,"q"=43,"r"=44,"s"=45,"t"=46,"u"=47,"v"=48,"w"=49,"x"=50,"y"=51,"z"=52,"0"=53,"1"=54,"2"=55,"3"=56,"4"=57,"5"=58,"6"=59,"7"=60,"8"=61,"9"=62,","=63,"."=64)
|
||||
var/ls = lentext(S)
|
||||
var/c
|
||||
var/i=1
|
||||
while(i<=ls)
|
||||
var/cb1=b64[copytext(S,i,i+1)]-1
|
||||
var/cb2=b64[copytext(S,i+1,i+2)]-1
|
||||
var/cb3=b64[copytext(S,i+2,i+3)]-1
|
||||
var/cb4=b64[copytext(S,i+3,i+4)]-1
|
||||
var/sb1=cb1<<2 | (cb2 & 48)>>4
|
||||
var/sb2=(cb2 & 15) <<4 | (cb3 & 60)>>2
|
||||
var/sb3=(cb3 & 3)<<6 | cb4
|
||||
c=c+ascii2text(sb1)+ascii2text(sb2)+ascii2text(sb3)
|
||||
i=i+4
|
||||
return c
|
||||
|
||||
/proc/XorEncrypt(string,key)
|
||||
if(!string || !key ||!istext(string)||!istext(key))
|
||||
return
|
||||
var/r
|
||||
for(var/i = 1 to length(string))
|
||||
r += ascii2text(text2ascii(string,i) ^ text2ascii(key,(i-1)%length(string)+1))
|
||||
return r
|
||||
|
||||
437
code/modules/integrated_electronics/core/integrated_circuit.dm
Normal file
437
code/modules/integrated_electronics/core/integrated_circuit.dm
Normal file
@@ -0,0 +1,437 @@
|
||||
/obj/item/integrated_circuit
|
||||
name = "integrated circuit"
|
||||
desc = "It's a tiny chip! This one doesn't seem to do much, however."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "template"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/obj/item/device/electronic_assembly/assembly // Reference to the assembly holding this circuit, if any.
|
||||
var/extended_desc
|
||||
var/list/inputs = list()
|
||||
var/list/inputs_default = list()// Assoc list which will fill a pin with data upon creation. e.g. "2" = 0 will set input pin 2 to equal 0 instead of null.
|
||||
var/list/outputs = list()
|
||||
var/list/outputs_default =list()// Ditto, for output.
|
||||
var/list/activators = list()
|
||||
var/next_use = 0 // Uses world.time
|
||||
var/complexity = 1 // This acts as a limitation on building machines, more resource-intensive components cost more 'space'.
|
||||
var/size = 1 // This acts as a limitation on building machines, bigger components cost more 'space'. -1 for size 0
|
||||
var/cooldown_per_use = 9 // Circuits are limited in how many times they can be work()'d by this variable.
|
||||
var/power_draw_per_use = 0 // How much power is drawn when work()'d.
|
||||
var/power_draw_idle = 0 // How much power is drawn when doing nothing.
|
||||
var/spawn_flags // Used for world initializing, see the #defines above.
|
||||
var/category_text = "NO CATEGORY THIS IS A BUG" // To show up on circuit printer, and perhaps other places.
|
||||
var/removable = TRUE // Determines if a circuit is removable from the assembly.
|
||||
var/displayed_name = ""
|
||||
var/allow_multitool = TRUE // Allows additional multitool functionality
|
||||
// Used as a global var, (Do not set manually in children).
|
||||
|
||||
/*
|
||||
Integrated circuits are essentially modular machines. Each circuit has a specific function, and combining them inside Electronic Assemblies allows
|
||||
a creative player the means to solve many problems. Circuits are held inside an electronic assembly, and are wired using special tools.
|
||||
*/
|
||||
|
||||
/obj/item/integrated_circuit/examine(mob/user)
|
||||
interact(user)
|
||||
external_examine(user)
|
||||
. = ..()
|
||||
|
||||
// This should be used when someone is examining while the case is opened.
|
||||
/obj/item/integrated_circuit/proc/internal_examine(mob/user)
|
||||
to_chat(user, "This board has [inputs.len] input pin\s, [outputs.len] output pin\s and [activators.len] activation pin\s.")
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I.linked.len)
|
||||
to_chat(user, "The '[I]' is connected to [I.get_linked_to_desc()].")
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
if(O.linked.len)
|
||||
to_chat(user, "The '[O]' is connected to [O.get_linked_to_desc()].")
|
||||
for(var/k in 1 to activators.len)
|
||||
var/datum/integrated_io/activate/A = activators[k]
|
||||
if(A.linked.len)
|
||||
to_chat(user, "The '[A]' is connected to [A.get_linked_to_desc()].")
|
||||
any_examine(user)
|
||||
interact(user)
|
||||
|
||||
// This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED.
|
||||
/obj/item/integrated_circuit/proc/external_examine(mob/user)
|
||||
any_examine(user)
|
||||
|
||||
/obj/item/integrated_circuit/proc/any_examine(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_interactivity(mob/user)
|
||||
if(assembly)
|
||||
return assembly.check_interactivity(user)
|
||||
else
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
|
||||
/obj/item/integrated_circuit/Initialize()
|
||||
displayed_name = name
|
||||
setup_io(inputs, /datum/integrated_io, inputs_default)
|
||||
setup_io(outputs, /datum/integrated_io, outputs_default)
|
||||
setup_io(activators, /datum/integrated_io/activate)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit.
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/Destroy()
|
||||
QDEL_LIST(inputs)
|
||||
QDEL_LIST(outputs)
|
||||
QDEL_LIST(activators)
|
||||
. = ..()
|
||||
/*
|
||||
/obj/item/integrated_circuit/nano_host()
|
||||
if(istype(src.loc, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/assembly = loc
|
||||
return assembly.resolve_nano_host()
|
||||
return ..()
|
||||
*/
|
||||
/obj/item/integrated_circuit/emp_act(severity)
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.scramble()
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
O.scramble()
|
||||
for(var/k in 1 to activators.len)
|
||||
var/datum/integrated_io/activate/A = activators[k]
|
||||
A.scramble()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/verb/rename_component()
|
||||
set name = "Rename Circuit"
|
||||
set category = "Object"
|
||||
set desc = "Rename your circuit, useful to stay organized."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!check_interactivity(M))
|
||||
return
|
||||
|
||||
var/input = reject_bad_name(input("What do you want to name this?", "Rename", src.name) as null|text,1)
|
||||
if(src && input && check_interactivity(M))
|
||||
to_chat(M, "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>")
|
||||
displayed_name = input
|
||||
|
||||
/obj/item/integrated_circuit/interact(mob/user)
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
// if(!assembly)
|
||||
// return
|
||||
|
||||
var/window_height = 350
|
||||
var/window_width = 600
|
||||
|
||||
//var/table_edge_width = "[(window_width - window_width * 0.1) / 4]px"
|
||||
//var/table_middle_width = "[(window_width - window_width * 0.1) - (table_edge_width * 2)]px"
|
||||
var/table_edge_width = "30%"
|
||||
var/table_middle_width = "40%"
|
||||
|
||||
var/HTML = list()
|
||||
HTML += "<html><head><title>[src.displayed_name]</title></head><body>"
|
||||
HTML += "<div align='center'>"
|
||||
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
|
||||
|
||||
HTML += "<br><a href='?src=[REF(src)];return=1'>\[Return to Assembly\]</a>"
|
||||
|
||||
HTML += "<br><a href='?src=[REF(src)];'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=[REF(src)];rename=1'>\[Rename\]</a> | "
|
||||
HTML += "<a href='?src=[REF(src)];scan=1'>\[Scan with Device\]</a> | "
|
||||
if(src.removable)
|
||||
HTML += "<a href='?src=[REF(src)];remove=1'>\[Remove\]</a><br>"
|
||||
|
||||
HTML += "<colgroup>"
|
||||
HTML += "<col style='width: [table_edge_width]'>"
|
||||
HTML += "<col style='width: [table_middle_width]'>"
|
||||
HTML += "<col style='width: [table_edge_width]'>"
|
||||
HTML += "</colgroup>"
|
||||
|
||||
var/column_width = 3
|
||||
var/row_height = max(inputs.len, outputs.len, 1)
|
||||
|
||||
for(var/i = 1 to row_height)
|
||||
HTML += "<tr>"
|
||||
for(var/j = 1 to column_width)
|
||||
var/datum/integrated_io/io = null
|
||||
var/words = list()
|
||||
var/height = 1
|
||||
switch(j)
|
||||
if(1)
|
||||
io = get_pin_ref(IC_INPUT, i)
|
||||
if(io)
|
||||
words += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]>[io.display_pin_type()] [io.name]</a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]>[io.display_data(io.data)]</a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/k in 1 to io.linked.len)
|
||||
var/datum/integrated_io/linked = io.linked[k]
|
||||
// words += "<a href=?src=[REF(linked.holder)];pin_name=1;pin=[REF(linked)];link=[REF(io)]>\[[linked]\]</a>
|
||||
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]>[linked]</a> \
|
||||
@ <a href=?src=[REF(linked.holder)];examine=1;>[linked.holder.displayed_name]</a><br>"
|
||||
|
||||
if(outputs.len > inputs.len)
|
||||
height = 1
|
||||
if(2)
|
||||
if(i == 1)
|
||||
words += "[src.displayed_name]<br>[src.name != src.displayed_name ? "([src.name])":""]<hr>[src.desc]"
|
||||
height = row_height
|
||||
else
|
||||
continue
|
||||
if(3)
|
||||
io = get_pin_ref(IC_OUTPUT, i)
|
||||
if(io)
|
||||
words += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]>[io.display_pin_type()] [io.name]</a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]>[io.display_data(io.data)]</a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/k in 1 to io.linked.len)
|
||||
var/datum/integrated_io/linked = io.linked[k]
|
||||
// words += "<a href=?src=[REF(linked.holder)];pin_name=1;pin=[REF(linked)];link=[REF(io)]>\[[linked]\]</a>
|
||||
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]>[linked]</a> \
|
||||
@ <a href=?src=[REF(linked.holder)];examine=1;>[linked.holder.displayed_name]</a><br>"
|
||||
|
||||
if(inputs.len > outputs.len)
|
||||
height = 1
|
||||
HTML += "<td align='center' rowspan='[height]'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
for(var/activator in activators)
|
||||
var/datum/integrated_io/io = activator
|
||||
var/words = list()
|
||||
|
||||
words += "<b><a href=?src=[REF(src)];pin_name=1;pin=[REF(io)]><font color='FF0000'>[io]</font></a> <a href=?src=[REF(src)];pin_data=1;pin=[REF(io)]><font color='FF0000'>[io.data?"\<PULSE OUT\>":"\<PULSE IN\>"]</font></a></b><br>"
|
||||
if(io.linked.len)
|
||||
for(var/k in 1 to io.linked.len)
|
||||
var/datum/integrated_io/linked = io.linked[k]
|
||||
// words += "<a href=?src=[REF(linked.holder)];pin_name=1;pin=[REF(linked)];link=[REF(io)]>\[[linked]\]</a>
|
||||
words += "<a href=?src=[REF(src)];pin_unwire=1;pin=[REF(io)];link=[REF(linked)]><font color='FF0000'>[linked]</font></a> \
|
||||
@ <a href=?src=[REF(linked.holder)];examine=1;><font color='FF0000'>[linked.holder.displayed_name]</font></a><br>"
|
||||
|
||||
HTML += "<tr>"
|
||||
HTML += "<td colspan='3' align='center'>[jointext(words, null)]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
HTML += "</table>"
|
||||
HTML += "</div>"
|
||||
|
||||
// HTML += "<br><font color='33CC33'>Meta Variables;</font>" // If more meta vars get introduced, uncomment this.
|
||||
// HTML += "<br>"
|
||||
|
||||
HTML += "<br><font color='0000AA'>Complexity: [complexity]</font>"
|
||||
if(power_draw_idle)
|
||||
HTML += "<br><font color='0000AA'>Power Draw: [power_draw_idle] W (Idle)</font>"
|
||||
if(power_draw_per_use)
|
||||
HTML += "<br><font color='0000AA'>Power Draw: [power_draw_per_use] W (Active)</font>" // Borgcode says that powercells' checked_use() takes joules as input.
|
||||
HTML += "<br><font color='0000AA'>[extended_desc]</font>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
if(src.assembly)
|
||||
user << browse(jointext(HTML, null), "window=assembly-[REF(src.assembly)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
user << browse(jointext(HTML, null), "window=circuit-[REF(src)];size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
onclose(user, "assembly-[REF(src.assembly)]")
|
||||
|
||||
/obj/item/integrated_circuit/Topic(href, href_list)
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
var/update = TRUE
|
||||
var/obj/item/device/electronic_assembly/A = src.assembly
|
||||
var/update_to_assembly = FALSE
|
||||
var/datum/integrated_io/pin = locate(href_list["pin"]) in inputs + outputs + activators
|
||||
var/datum/integrated_io/linked = null
|
||||
if(href_list["link"])
|
||||
linked = locate(href_list["link"]) in pin.linked
|
||||
|
||||
var/obj/held_item = usr.get_active_held_item()
|
||||
|
||||
if(href_list["rename"])
|
||||
rename_component(usr)
|
||||
if(href_list["from_assembly"])
|
||||
update = FALSE
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
|
||||
if(href_list["pin_name"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = TRUE
|
||||
else
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
M.wire(pin,usr)
|
||||
|
||||
|
||||
|
||||
if(href_list["pin_data"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = TRUE
|
||||
|
||||
else
|
||||
var/datum/integrated_io/io = pin
|
||||
io.ask_for_pin_data(usr) // The pins themselves will determine how to ask for data, and will validate the data.
|
||||
/*
|
||||
if(io.io_type == DATA_CHANNEL)
|
||||
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number", "null")
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
to_chat(usr, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
//to_chat(user, "<span class='notice'>You write '[new_data]' to the '[io]' pin of \the [io.holder].</span>")
|
||||
if("number")
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && check_interactivity(usr) )
|
||||
to_chat(usr, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
if("null")
|
||||
if(check_interactivity(usr))
|
||||
to_chat(usr, "<span class='notice'>You clear the pin's memory.</span>")
|
||||
|
||||
io.write_data_to_pin(new_data)
|
||||
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(usr, "<span class='notice'>You pulse \the [io.holder]'s [io] pin.</span>")
|
||||
*/
|
||||
|
||||
|
||||
if(href_list["pin_unwire"])
|
||||
if (!istype(held_item, /obj/item/device/multitool) || !allow_multitool)
|
||||
href_list["wire"] = TRUE
|
||||
else
|
||||
var/obj/item/device/multitool/M = held_item
|
||||
M.unwire(pin, linked, usr)
|
||||
|
||||
if(href_list["wire"])
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = held_item
|
||||
if(linked)
|
||||
wirer.wire(linked, usr)
|
||||
else if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
|
||||
else if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/debugger = held_item
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You can't do a whole lot without the proper tools.</span>")
|
||||
|
||||
if(href_list["examine"])
|
||||
var/obj/item/integrated_circuit/examined
|
||||
if(href_list["examined"])
|
||||
examined = href_list["examined"]
|
||||
else
|
||||
examined = src
|
||||
examined.interact(usr)
|
||||
update = FALSE
|
||||
|
||||
if(href_list["bottom"])
|
||||
var/obj/item/integrated_circuit/circuit = locate(href_list["bottom"]) in src.assembly.contents
|
||||
var/assy = circuit.assembly
|
||||
if(!circuit)
|
||||
return
|
||||
circuit.loc = null
|
||||
circuit.loc = assy
|
||||
. = TRUE
|
||||
update_to_assembly = TRUE
|
||||
|
||||
if(href_list["scan"])
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/debugger))
|
||||
var/obj/item/device/integrated_electronics/debugger/D = held_item
|
||||
if(D.accepting_refs)
|
||||
D.afterattack(src, usr, TRUE)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>The Debugger's 'ref scanner' needs to be on.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You need a multitool/debugger set to 'ref' mode to do that.</span>")
|
||||
|
||||
if(href_list["return"])
|
||||
if(A)
|
||||
update_to_assembly = TRUE
|
||||
usr << browse(null, "window=circuit-[REF(src)];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
|
||||
|
||||
if(href_list["remove"])
|
||||
if(!A)
|
||||
to_chat(usr, "<span class='warning'>This circuit is not in an assembly!</span>")
|
||||
return
|
||||
if(!removable)
|
||||
to_chat(usr, "<span class='warning'>\The [src] seems to be permanently attached to the case.</span>")
|
||||
return
|
||||
var/obj/item/device/electronic_assembly/ea = loc
|
||||
disconnect_all()
|
||||
var/turf/T = get_turf(src)
|
||||
forceMove(T)
|
||||
assembly = null
|
||||
playsound(T, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
to_chat(usr, "<span class='notice'>You pop \the [src] out of the case, and slide it out.</span>")
|
||||
|
||||
if(istype(ea))
|
||||
ea.interact(usr)
|
||||
update = FALSE
|
||||
return
|
||||
|
||||
if(update)
|
||||
if(A && istype(A) && update_to_assembly)
|
||||
A.interact(usr)
|
||||
else
|
||||
interact(usr) // To refresh the UI.
|
||||
|
||||
/obj/item/integrated_circuit/proc/push_data()
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/pull_data()
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/draw_idle_power()
|
||||
if(assembly)
|
||||
return assembly.draw_power(power_draw_idle)
|
||||
|
||||
// Override this for special behaviour when there's no power left.
|
||||
/obj/item/integrated_circuit/proc/power_fail()
|
||||
return
|
||||
|
||||
// Returns true if there's enough power to work().
|
||||
/obj/item/integrated_circuit/proc/check_power()
|
||||
if(!assembly)
|
||||
return FALSE // Not in an assembly, therefore no power.
|
||||
if(assembly.draw_power(power_draw_per_use))
|
||||
return TRUE // Battery has enough.
|
||||
return FALSE // Not enough power.
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work(var/ignore_power = FALSE)
|
||||
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
return
|
||||
if(power_draw_per_use && !ignore_power)
|
||||
if(!check_power())
|
||||
power_fail()
|
||||
return
|
||||
next_use = world.time + cooldown_per_use
|
||||
do_work()
|
||||
|
||||
/obj/item/integrated_circuit/proc/do_work()
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/disconnect_all()
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.disconnect()
|
||||
for(var/k in 1 to outputs.len)
|
||||
var/datum/integrated_io/O = outputs[k]
|
||||
O.disconnect()
|
||||
for(var/k in 1 to activators.len)
|
||||
var/datum/integrated_io/activate/A = activators[k]
|
||||
A.disconnect()
|
||||
|
||||
/obj/item/integrated_circuit/proc/ext_moved(oldLoc, dir)
|
||||
return
|
||||
197
code/modules/integrated_electronics/core/pins.dm
Normal file
197
code/modules/integrated_electronics/core/pins.dm
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
Pins both hold data for circuits, as well move data between them. Some also cause circuits to do their function. DATA_CHANNEL pins are the data holding/moving kind,
|
||||
where as PULSE_CHANNEL causes circuits to work() when their pulse hits them.
|
||||
|
||||
|
||||
A visualization of how pins work is below. Imagine the below image involves an addition circuit.
|
||||
When the bottom pin, the activator, receives a pulse, all the numbers on the left (input) get added, and the answer goes on the right side (output).
|
||||
|
||||
Inputs Outputs
|
||||
|
||||
A [2]\ /[8] result
|
||||
B [1]-\|++|/
|
||||
C [4]-/|++|
|
||||
D [1]/ ||
|
||||
||
|
||||
Activator
|
||||
|
||||
|
||||
|
||||
*/
|
||||
/datum/integrated_io
|
||||
var/name = "input/output"
|
||||
var/obj/item/integrated_circuit/holder
|
||||
var/datum/weakref/data // This is a weakref, to reduce typecasts. Note that oftentimes numbers and text may also occupy this.
|
||||
var/list/linked = list()
|
||||
var/io_type = DATA_CHANNEL
|
||||
|
||||
/datum/integrated_io/New(newloc, name1, new_data)
|
||||
name = name1
|
||||
if(new_data)
|
||||
data = new_data
|
||||
holder = newloc
|
||||
if(!istype(holder))
|
||||
message_admins("ERROR: An integrated_io ([name]) spawned without a valid holder! This is a bug.")
|
||||
|
||||
/datum/integrated_io/Destroy()
|
||||
disconnect()
|
||||
data = null
|
||||
holder = null
|
||||
return ..()
|
||||
/*
|
||||
/datum/integrated_io/nano_host()
|
||||
return holder.nano_host()
|
||||
*/
|
||||
|
||||
/datum/integrated_io/proc/data_as_type(var/as_type)
|
||||
if(!isweakref(data))
|
||||
return
|
||||
var/datum/weakref/w = data
|
||||
var/output = w.resolve()
|
||||
return istype(output, as_type) ? output : null
|
||||
|
||||
/datum/integrated_io/proc/display_data(var/input)
|
||||
if(isnull(input))
|
||||
return "(null)" // Empty data means nothing to show.
|
||||
|
||||
if(istext(input))
|
||||
return "(\"[input]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'.
|
||||
|
||||
/*
|
||||
list[](
|
||||
"A",
|
||||
"B",
|
||||
"C"
|
||||
)
|
||||
*/
|
||||
|
||||
if(islist(input))
|
||||
var/list/my_list = input
|
||||
var/result = "list\[[my_list.len]\]("
|
||||
if(my_list.len)
|
||||
result += "<br>"
|
||||
var/pos = 0
|
||||
for(var/line in my_list)
|
||||
result += "[display_data(line)]"
|
||||
pos++
|
||||
if(pos != my_list.len)
|
||||
result += ",<br>"
|
||||
result += "<br>"
|
||||
result += ")"
|
||||
return result
|
||||
|
||||
if(isweakref(input))
|
||||
var/datum/weakref/w = input
|
||||
var/atom/A = w.resolve()
|
||||
return A ? "([A.name] \[Ref\])" : "(null)" // For refs, we want just the name displayed.
|
||||
//return A ? "([REF(A)] \[Ref\])" : "(null)"
|
||||
|
||||
return "([input])" // Nothing special needed for numbers or other stuff.
|
||||
|
||||
/datum/integrated_io/activate/display_data()
|
||||
return "(\[pulse\])"
|
||||
|
||||
/datum/integrated_io/proc/display_pin_type()
|
||||
return IC_FORMAT_ANY
|
||||
|
||||
/datum/integrated_io/activate/display_pin_type()
|
||||
return IC_FORMAT_PULSE
|
||||
|
||||
/datum/integrated_io/proc/scramble()
|
||||
if(isnull(data))
|
||||
return
|
||||
if(isnum(data))
|
||||
write_data_to_pin(rand(-10000, 10000))
|
||||
if(istext(data))
|
||||
write_data_to_pin("ERROR")
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/activate/scramble()
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/proc/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || isnum(new_data) || istext(new_data) || isweakref(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
else if(islist(new_data))
|
||||
var/list/new_list = new_data
|
||||
data = new_list.Copy(1,min( IC_MAX_LIST_LENGTH+1, new_list.len ))
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/proc/push_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
io.write_data_to_pin(data)
|
||||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
io.holder.check_then_do_work()
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
for(var/k in 1 to linked.len)
|
||||
var/datum/integrated_io/io = linked[k]
|
||||
write_data_to_pin(io.data)
|
||||
|
||||
/datum/integrated_io/proc/get_linked_to_desc()
|
||||
if(linked.len)
|
||||
return "the [english_list(linked)]"
|
||||
return "nothing"
|
||||
|
||||
/datum/integrated_io/proc/disconnect()
|
||||
//First we iterate over everything we are linked to.
|
||||
if(linked && linked.len)
|
||||
for(var/i in 1 to linked.len)
|
||||
var/datum/integrated_io/their_io = linked[i]
|
||||
//While doing that, we iterate them as well, and disconnect ourselves from them.
|
||||
if(their_io.linked.len && their_io.linked)
|
||||
for(var/j in 1 to their_io.linked.len)
|
||||
var/datum/integrated_io/their_linked_io = their_io.linked[j]
|
||||
if(their_linked_io == src)
|
||||
their_io.linked.Remove(src)
|
||||
else
|
||||
continue
|
||||
//Now that we're removed from them, we gotta remove them from us.
|
||||
linked.Remove(their_io)
|
||||
|
||||
/datum/integrated_io/proc/ask_for_data_type(mob/user, var/default, var/list/allowed_data_types = list("string","number","null"))
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in allowed_data_types
|
||||
if(!holder.check_interactivity(user))
|
||||
return
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
new_data = input("Now type in a string.","[src] string writing", istext(default) ? default : null) as null|text
|
||||
if(istext(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input "+new_data+" into the pin.</span>")
|
||||
return new_data
|
||||
if("number")
|
||||
new_data = input("Now type in a number.","[src] number writing", isnum(default) ? default : null) as null|num
|
||||
if(isnum(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
return new_data
|
||||
if("null")
|
||||
if(holder.check_interactivity(user))
|
||||
to_chat(user, "<span class='notice'>You clear the pin's memory.</span>")
|
||||
return new_data
|
||||
|
||||
// Basically a null check
|
||||
/datum/integrated_io/proc/is_valid()
|
||||
return !isnull(data)
|
||||
|
||||
// This proc asks for the data to write, then writes it.
|
||||
/datum/integrated_io/proc/ask_for_pin_data(mob/user)
|
||||
var/new_data = ask_for_data_type(user)
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/activate/ask_for_pin_data(mob/user) // This just pulses the pin.
|
||||
holder.check_then_do_work(ignore_power = TRUE)
|
||||
to_chat(user, "<span class='notice'>You pulse \the [holder]'s [src] pin.</span>")
|
||||
|
||||
/datum/integrated_io/activate
|
||||
name = "activation pin"
|
||||
io_type = PULSE_CHANNEL
|
||||
|
||||
/datum/integrated_io/activate/out // All this does is just make the UI say 'out' instead of 'in'
|
||||
data = 1
|
||||
156
code/modules/integrated_electronics/core/prefab.dm
Normal file
156
code/modules/integrated_electronics/core/prefab.dm
Normal file
@@ -0,0 +1,156 @@
|
||||
/obj/item/device/integrated_electronics/prefab
|
||||
var/debug = FALSE
|
||||
name = "prefab"
|
||||
desc = "new machine in package"
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "box_template"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/program="blank"
|
||||
var/list/as_names = list()
|
||||
|
||||
/obj/item/device/integrated_electronics/prefab/attack_self(var/mob/user)
|
||||
if(program && program != "blank")
|
||||
assemble(program)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_electronics/prefab/Initialize()
|
||||
. = ..()
|
||||
var/list/assembly_list = list(
|
||||
/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone,
|
||||
)
|
||||
for(var/k in 1 to assembly_list.len)
|
||||
var/obj/item/I = assembly_list[k]
|
||||
as_names[initial(I.name)] = I
|
||||
addtimer(CALLBACK(src, .proc/attack_self), 2) //IDK, why it's need dely,but otherwise it doesn't work.
|
||||
|
||||
/obj/item/device/integrated_electronics/prefab/proc/assemble(var/program)
|
||||
var/list/all_circuits = SScircuit.all_circuits //cached lists = free performance
|
||||
var/list/chap = splittext( program ,"{{*}}")
|
||||
var/list/elements = list()
|
||||
var/list/elements_input = list()
|
||||
var/list/element = list()
|
||||
var/obj/item/AS
|
||||
var/PA
|
||||
var/i = 0
|
||||
|
||||
var/list/ioa = list()
|
||||
var/datum/integrated_io/IO
|
||||
var/datum/integrated_io/IO2
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>started successful</span>")
|
||||
if(chap[2] != "")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>assembly</span>")
|
||||
element = splittext( chap[2] ,"=-=")
|
||||
PA = as_names[element[1]]
|
||||
AS = new PA(null)
|
||||
AS.loc = src
|
||||
AS.name = element[2]
|
||||
else
|
||||
return //what's the point if there is no assembly?
|
||||
if(chap[3] != "components") //if there is only one word,there is no components.
|
||||
elements_input = splittext( chap[3] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements_input.len]</span>")
|
||||
i = 0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem) //I don't know,why Cut or copy don't works. If somebody can fix it, it should be fixed.
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements.len]</span>")
|
||||
if(!length(elements_input))
|
||||
return
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>inserting components[elements.len]</span>")
|
||||
var/obj/item/integrated_circuit/comp
|
||||
i=0
|
||||
for(var/E in elements)
|
||||
i=i+1
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
var/path_to_use = all_circuits[element[1]]
|
||||
comp = new path_to_use(null)
|
||||
comp.loc = AS
|
||||
comp.displayed_name = element[2]
|
||||
comp.assembly = AS
|
||||
if(comp.inputs && comp.inputs.len)
|
||||
for(var/j in 1 to comp.inputs.len)
|
||||
var/datum/integrated_io/IN = comp.inputs[j]
|
||||
ioa["[i]i[j]"] = IN
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]i[j]</span>")
|
||||
if(comp.outputs && comp.outputs.len)
|
||||
for(var/j in 1 to comp.outputs.len) //Also this block uses for setting all i/o id's
|
||||
var/datum/integrated_io/OUT = comp.outputs[j]
|
||||
ioa["[i]o[j]"] = OUT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]o[j]</span>")
|
||||
if(comp.activators && comp.activators.len)
|
||||
for(var/j in 1 to comp.activators.len)
|
||||
var/datum/integrated_io/ACT = comp.activators[j]
|
||||
ioa["[i]a[j]"] = ACT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]a[j]</span>")
|
||||
|
||||
else
|
||||
return
|
||||
if(!AS.contents.len)
|
||||
return
|
||||
if(chap[4] != "values") //if there is only one word,there is no values
|
||||
elements_input = splittext( chap[4] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements_input.len]</span>")
|
||||
i=0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting values[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,":+:")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
IO = ioa[element[1]]
|
||||
if(element[2]=="text")
|
||||
IO.write_data_to_pin(element[3])
|
||||
else if(element[2]=="num")
|
||||
IO.write_data_to_pin(text2num(element[3]))
|
||||
else if(element[2]=="list")
|
||||
IO.write_data_to_pin(params2list(element[3]))
|
||||
if(chap[5] != "wires") //if there is only one word,there is no wires
|
||||
elements_input = splittext( chap[5] ,"^%^")
|
||||
i=0
|
||||
elements = list()
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements_input.len]</span>")
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting wires[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
IO = ioa[element[1]]
|
||||
IO2 = ioa[element[2]]
|
||||
IO.linked |= IO2
|
||||
|
||||
AS.forceMove(loc)
|
||||
qdel(src)
|
||||
413
code/modules/integrated_electronics/core/printer.dm
Normal file
413
code/modules/integrated_electronics/core/printer.dm
Normal file
@@ -0,0 +1,413 @@
|
||||
/obj/item/device/integrated_circuit_printer
|
||||
name = "integrated circuit printer"
|
||||
desc = "A portable(ish) machine made to print tiny modular circuitry out of metal."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "circuit_printer"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/metal = 0
|
||||
var/init_max_metal = 100
|
||||
var/max_metal = 100
|
||||
var/metal_per_sheet = 10 // One sheet equals this much metal.
|
||||
var/debug = FALSE
|
||||
var/upgraded = FALSE // When hit with an upgrade disk, will turn true, allowing it to print the higher tier circuits.
|
||||
var/can_clone = FALSE // Same for above, but will allow the printer to duplicate a specific assembly.
|
||||
var/static/list/recipe_list //category = list(paths in category)
|
||||
var/current_category = null
|
||||
var/as_printing = FALSE
|
||||
var/as_needs = 0
|
||||
var/program ="blank"
|
||||
var/obj/item/device/integrated_electronics/prefab/PR = null
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/proc/check_interactivity(mob/user)
|
||||
return user.canUseTopic(src,be_close = TRUE)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/upgraded
|
||||
upgraded = TRUE
|
||||
can_clone = TRUE
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/Initialize()
|
||||
. = ..()
|
||||
if(!recipe_list)
|
||||
recipe_list = SScircuit.circuit_fabricator_recipe_list
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/attackby(var/obj/item/O, var/mob/user)
|
||||
if(istype(O,/obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/stack = O
|
||||
var/num = min((max_metal - metal) / metal_per_sheet, stack.amount)
|
||||
if(num < 1)
|
||||
to_chat(user, "<span class='warning'>\The [src] is too full to add more metal.</span>")
|
||||
return
|
||||
if(stack.use(num))
|
||||
to_chat(user, "<span class='notice'>You add [num] sheet\s to \the [src].</span>")
|
||||
metal += num * metal_per_sheet
|
||||
if(as_printing)
|
||||
if(as_needs <= metal)
|
||||
PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc))
|
||||
PR.program = program
|
||||
metal = metal - as_needs
|
||||
to_chat(user, "<span class='notice'>Assembly has been printed.</span>")
|
||||
as_printing = FALSE
|
||||
as_needs = 0
|
||||
max_metal = init_max_metal
|
||||
else
|
||||
to_chat(user, "<span class='notice'>Please insert [(as_needs-metal)/10] more metal!</span>")
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/integrated_circuit))
|
||||
to_chat(user, "<span class='notice'>You insert the circuit into \the [src]. </span>")
|
||||
user.temporarilyRemoveItemFromInventory(O)
|
||||
metal = min(metal + O.w_class, max_metal)
|
||||
qdel(O)
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/disk/integrated_circuit/upgrade/advanced))
|
||||
if(upgraded)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You install \the [O] into \the [src]. </span>")
|
||||
upgraded = TRUE
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
if(istype(O,/obj/item/disk/integrated_circuit/upgrade/clone))
|
||||
if(can_clone)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has this upgrade. </span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>You install \the [O] into \the [src]. </span>")
|
||||
can_clone = TRUE
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/attack_self(var/mob/user)
|
||||
interact(user)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/interact(mob/user)
|
||||
var/window_height = 600
|
||||
var/window_width = 500
|
||||
|
||||
if(isnull(current_category))
|
||||
current_category = recipe_list[1]
|
||||
|
||||
var/HTML = "<center><h2>Integrated Circuit Printer</h2></center><br>"
|
||||
HTML += "Metal: [metal/metal_per_sheet]/[max_metal/metal_per_sheet] sheets.<br>"
|
||||
HTML += "Circuits available: [upgraded ? "Advanced":"Regular"]."
|
||||
HTML += "Assembly Cloning: [can_clone ? "Available": "Unavailable"]."
|
||||
HTML += "Crossed out circuits mean that the printer is not sufficiently upgraded to create that circuit.<br>"
|
||||
HTML += "<hr>"
|
||||
if(can_clone)
|
||||
HTML += "Here you can load script for your assembly.<br>"
|
||||
if(as_printing)
|
||||
HTML += " {Load Program} "
|
||||
else
|
||||
HTML += " <A href='?src=[REF(src)];print=load'>{Load Program}</a> "
|
||||
if(program == "blank")
|
||||
HTML += " {Check Program} "
|
||||
else
|
||||
HTML += " <A href='?src=[REF(src)];print=check'>{Check Program}</a> "
|
||||
if((program == "blank")|as_printing)
|
||||
HTML += " {Print assembly} "
|
||||
else
|
||||
HTML += " <A href='?src=[REF(src)];print=print'>{Print assembly}</a> "
|
||||
if(as_printing)
|
||||
HTML += "<br> printing in process. Please insert more metal. "
|
||||
HTML += "<br><hr>"
|
||||
HTML += "Categories:"
|
||||
for(var/category in recipe_list)
|
||||
if(category != current_category)
|
||||
HTML += " <a href='?src=[REF(src)];category=[category]'>\[[category]\]</a> "
|
||||
else // Bold the button if it's already selected.
|
||||
HTML += " <b>\[[category]\]</b> "
|
||||
HTML += "<hr>"
|
||||
HTML += "<center><h4>[current_category]</h4></center>"
|
||||
|
||||
var/list/current_list = recipe_list[current_category]
|
||||
for(var/k in 1 to current_list.len)
|
||||
var/obj/O = current_list[k]
|
||||
var/can_build = TRUE
|
||||
if(istype(O, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = current_list[k]
|
||||
if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded)
|
||||
can_build = FALSE
|
||||
if(can_build)
|
||||
HTML += "<A href='?src=[REF(src)];build=[current_list[k]]'>\[[initial(O.name)]\]</A>: [initial(O.desc)]<br>"
|
||||
else
|
||||
HTML += "<s>\[[initial(O.name)]\]: [initial(O.desc)]</s><br>"
|
||||
|
||||
user << browse(jointext(HTML, null), "window=integrated_printer;size=[window_width]x[window_height];border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/Topic(href, href_list)
|
||||
if(!check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
var/sc = 0
|
||||
add_fingerprint(usr)
|
||||
|
||||
if(href_list["category"])
|
||||
current_category = href_list["category"]
|
||||
|
||||
if(href_list["build"])
|
||||
var/build_type = text2path(href_list["build"])
|
||||
if(!build_type || !ispath(build_type))
|
||||
return TRUE
|
||||
|
||||
var/cost = 1
|
||||
if(ispath(build_type, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/E = build_type
|
||||
cost = round( (initial(E.max_complexity) + initial(E.max_components) ) / 4)
|
||||
else if(ispath(build_type, /obj/item/integrated_circuit))
|
||||
var/obj/item/integrated_circuit/IC = build_type
|
||||
cost = initial(IC.w_class)
|
||||
|
||||
if(metal - cost < 0)
|
||||
to_chat(usr, "<span class='warning'>You need [cost] metal to build that!.</span>")
|
||||
return TRUE
|
||||
metal -= cost
|
||||
new build_type(get_turf(loc))
|
||||
|
||||
if(href_list["print"])
|
||||
if(!CONFIG_GET(flag/ic_printing))
|
||||
to_chat(usr, "<span class='warning'>CentCom has disabled printing of custom circuitry due to recent allegations of copyright infringement.</span>")
|
||||
return
|
||||
switch(href_list["print"])
|
||||
if("load")
|
||||
program = input("Put your code there:", "loading", null, null)
|
||||
if("check")
|
||||
sc = sanity_check(program,usr)
|
||||
if(sc == 0)
|
||||
to_chat(usr, "<span class='warning'>Invalid program.</span>")
|
||||
else if(sc == -1)
|
||||
to_chat(usr, "<span class='warning'>Unknown circuits found. Upgrades required to process this design.</span>")
|
||||
else if(sc == null)
|
||||
to_chat(usr, "<span class='warning'>Invalid program.</span>")
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>Program is correct.You'll need [sc/10] sheets of metal</span>")
|
||||
if("print")
|
||||
sc = sanity_check(program,usr)
|
||||
if(sc == 0 || sc == null)
|
||||
to_chat(usr, "<span class='warning'>Invalid program.</span>")
|
||||
else if(sc == -1)
|
||||
to_chat(usr, "<span class='warning'>Unknown circuits found. Upgrades required to process this design.</span>")
|
||||
else
|
||||
as_printing = TRUE
|
||||
if(sc <= metal)
|
||||
PR = new/obj/item/device/integrated_electronics/prefab(get_turf(loc))
|
||||
PR.program = program
|
||||
metal = metal - sc
|
||||
to_chat(usr, "<span class='notice'>Assembly has been printed.</span>")
|
||||
as_printing = FALSE
|
||||
as_needs = 0
|
||||
max_metal=init_max_metal
|
||||
else
|
||||
max_metal = sc + metal_per_sheet
|
||||
as_needs = sc
|
||||
to_chat(usr, "<span class='notice'>Please insert [(as_needs-metal)/10] more metal!</span>")
|
||||
interact(usr)
|
||||
|
||||
// FUKKEN UPGRADE DISKS
|
||||
/obj/item/disk/integrated_circuit/upgrade
|
||||
name = "integrated circuit printer upgrade disk"
|
||||
desc = "Install this into your integrated circuit printer to enhance it."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "upgrade_disk"
|
||||
item_state = "card-id"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4)
|
||||
|
||||
/obj/item/disk/integrated_circuit/upgrade/advanced
|
||||
name = "integrated circuit printer upgrade disk - advanced designs"
|
||||
desc = "Install this into your integrated circuit printer to enhance it. This one adds new, advanced designs to the printer."
|
||||
|
||||
// To be implemented later.
|
||||
/obj/item/disk/integrated_circuit/upgrade/clone
|
||||
name = "integrated circuit printer upgrade disk - circuit cloner"
|
||||
desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies."
|
||||
icon_state = "upgrade_disk_clone"
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
|
||||
|
||||
/obj/item/device/integrated_circuit_printer/proc/sanity_check(var/program,var/mob/user)
|
||||
var/list/chap = splittext( program ,"{{*}}")
|
||||
if(chap.len != 6)
|
||||
return 0 //splitting incorrect
|
||||
var/list/elements = list()
|
||||
var/list/elements_input = list()
|
||||
var/list/element = list()
|
||||
var/obj/item/PA
|
||||
var/obj/item/device/electronic_assembly/PF
|
||||
var/datum/integrated_io/IO
|
||||
var/datum/integrated_io/IO2
|
||||
var/i = 0
|
||||
var/obj/item/integrated_circuit/comp
|
||||
var/list/ioa = list()
|
||||
var/list/as_samp = list()
|
||||
var/list/all_circuits = SScircuit.all_circuits // It's free. Performance. We're giving you cpu time. It's free. We're giving you time. It's performance, free. It's free cpu time for you jim!
|
||||
var/list/assembly_list = list(
|
||||
/obj/item/device/electronic_assembly,
|
||||
/obj/item/device/electronic_assembly/medium,
|
||||
/obj/item/device/electronic_assembly/large,
|
||||
/obj/item/device/electronic_assembly/drone,
|
||||
)
|
||||
var/compl = 0
|
||||
var/maxcomp = 0
|
||||
var/cap = 0
|
||||
var/maxcap = 0
|
||||
var/metalcost = 0
|
||||
for(var/k in 1 to assembly_list.len)
|
||||
var/obj/item/I = assembly_list[k]
|
||||
as_samp[initial(I.name)] = I
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>started successful</span>")
|
||||
if(chap[2] != "")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>assembly</span>")
|
||||
element = splittext( chap[2] ,"=-=")
|
||||
PA = as_samp[element[1]]
|
||||
if(ispath(PA,/obj/item/device/electronic_assembly))
|
||||
PF = PA
|
||||
maxcap = initial(PF.max_components)
|
||||
maxcomp = initial(PF.max_complexity)
|
||||
metalcost = metalcost + round( (initial(PF.max_complexity) + initial(PF.max_components) ) / 4)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>maxcap[maxcap]maxcomp[maxcomp]</span>")
|
||||
else
|
||||
return 0
|
||||
to_chat(usr, "<span class='notice'>This is program for [element[2]]</span>")
|
||||
/*
|
||||
else if(istype(PA,/obj/item/weapon/implant/integrated_circuit))
|
||||
var/obj/item/weapon/implant/integrated_circuit/PI = PA
|
||||
var/obj/item/device/electronic_assembly/implant/PIC = PI.IC
|
||||
maxcap = PIC.max_components
|
||||
maxcomp = PIC.max_complexity
|
||||
metalcost = metalcost + round( (initial(PIC.max_complexity) + initial(PIC.max_components) ) / 4)*/
|
||||
else
|
||||
return 0 //what's the point if there is no assembly?
|
||||
if(chap[3] != "components") //if there is only one word,there is no components.
|
||||
elements_input = splittext( chap[3] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements_input.len]</span>")
|
||||
i = 0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>components[elements.len]</span>")
|
||||
if(elements_input.len<1)
|
||||
return 0
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>inserting components[elements.len]</span>")
|
||||
i=0
|
||||
for(var/E in elements)
|
||||
i=i+1
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
comp = all_circuits[element[1]]
|
||||
if(!comp)
|
||||
break
|
||||
if(!upgraded)
|
||||
var/obj/item/integrated_circuit/IC = comp
|
||||
if(!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT))
|
||||
return -1
|
||||
compl = compl + initial(comp.complexity)
|
||||
cap = cap + initial(comp.size)
|
||||
metalcost = metalcost + initial(initial(comp.w_class))
|
||||
var/obj/item/integrated_circuit/circuit = new comp
|
||||
var/list/ini = circuit.inputs
|
||||
if(length(ini))
|
||||
for(var/j in 1 to ini.len)
|
||||
var/datum/integrated_io/IN = ini[j]
|
||||
ioa["[i]i[j]"] = IN
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]i[j]</span>")
|
||||
ini = circuit.outputs
|
||||
if(length(ini))
|
||||
for(var/j in 1 to ini.len) //Also this block uses for setting all i/o id's
|
||||
var/datum/integrated_io/OUT = ini[j]
|
||||
ioa["[i]o[j]"] = OUT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]o[j]</span>")
|
||||
ini = circuit.activators
|
||||
if(length(ini))
|
||||
for(var/j in 1 to ini.len)
|
||||
var/datum/integrated_io/ACT = ini.[j]
|
||||
ioa["[i]a[j]"] = ACT
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[i]a[j]</span>")
|
||||
if(i<elements.len)
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>cap[cap]compl[compl]maxcompl[maxcomp]maxcap[maxcap]</span>")
|
||||
if(cap == 0)
|
||||
return 0
|
||||
if(cap>maxcap)
|
||||
return 0
|
||||
if(compl>maxcomp)
|
||||
return 0
|
||||
if(chap[4] != "values") //if there is only one word,there is no values
|
||||
elements_input = splittext( chap[4] ,"^%^")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements_input.len]</span>")
|
||||
i=0
|
||||
elements = list()
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>values[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting values[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,":+:")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
if(!ioa[element[1]])
|
||||
return 0
|
||||
if(element[2]=="text")
|
||||
continue
|
||||
else if(element[2]=="num")
|
||||
continue
|
||||
else if(element[2]=="list")
|
||||
continue
|
||||
else
|
||||
return 0
|
||||
|
||||
if(chap[5] != "wires") //if there is only one word,there is no wires
|
||||
elements_input = splittext( chap[5] ,"^%^")
|
||||
i=0
|
||||
elements = list()
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements_input.len]</span>")
|
||||
for(var/elem in elements_input)
|
||||
i=i+1
|
||||
if(i>1)
|
||||
elements.Add(elem)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>wires[elements.len]</span>")
|
||||
if(elements.len>0)
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>setting wires[elements.len]</span>")
|
||||
for(var/E in elements)
|
||||
element = splittext( E ,"=-=")
|
||||
if(debug)
|
||||
visible_message( "<span class='notice'>[E]</span>")
|
||||
IO = ioa[element[1]]
|
||||
IO2 = ioa[element[2]]
|
||||
if(!((element[2]+"=-="+element[1]) in elements))
|
||||
return 0
|
||||
if(!IO)
|
||||
return 0
|
||||
if(!IO2)
|
||||
return 0
|
||||
if(initial(IO.io_type) != initial(IO2.io_type))
|
||||
return 0
|
||||
return metalcost
|
||||
@@ -0,0 +1,26 @@
|
||||
// These pins only contain 0 or 1. Null is not allowed.
|
||||
/datum/integrated_io/boolean
|
||||
name = "boolean pin"
|
||||
data = FALSE
|
||||
|
||||
/datum/integrated_io/boolean/ask_for_pin_data(mob/user) // 'Ask' is a bit misleading, acts more like a toggle.
|
||||
var/new_data = !data
|
||||
to_chat(user, "<span class='notice'>You switch the data bit to [data? "true" : "false"].</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/boolean/write_data_to_pin(var/new_data)
|
||||
if(new_data == FALSE || new_data == TRUE)
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/boolean/scramble()
|
||||
write_data_to_pin(rand(FALSE,TRUE))
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/boolean/display_pin_type()
|
||||
return IC_FORMAT_BOOLEAN
|
||||
|
||||
/datum/integrated_io/boolean/display_data(var/input)
|
||||
if(data == TRUE)
|
||||
return "(True)"
|
||||
return "(False)"
|
||||
@@ -0,0 +1,27 @@
|
||||
// These pins can only contain a 1 character string or null.
|
||||
/datum/integrated_io/char
|
||||
name = "char pin"
|
||||
|
||||
/datum/integrated_io/char/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in one character.","[src] char writing") as null|text
|
||||
if(holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data ? "new_data" : "NULL"] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/char/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
if(length(new_data) > 1)
|
||||
return
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
// This makes the text go from "A" to "%".
|
||||
/datum/integrated_io/char/scramble()
|
||||
if(!is_valid())
|
||||
return
|
||||
var/list/options = list("!","@","#","$","%","^","&","*","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
|
||||
data = pick(options)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/char/display_pin_type()
|
||||
return IC_FORMAT_CHAR
|
||||
@@ -0,0 +1,49 @@
|
||||
// These pins can only contain a color (in the form of #FFFFFF) or null.
|
||||
/datum/integrated_io/color
|
||||
name = "color pin"
|
||||
|
||||
/datum/integrated_io/color/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please select a color.","[src] color writing") as null|color
|
||||
if(holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input a <font color='[new_data]'>new color</font> into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/color/write_data_to_pin(var/new_data)
|
||||
// Since this is storing the color as a string hex color code, we need to make sure it's actually one.
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
if(istext(new_data))
|
||||
new_data = uppertext(new_data)
|
||||
if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind
|
||||
return // Cause your strings don't hex and if they don't hex
|
||||
var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine
|
||||
// I say, we can go where we want to, a place where they will never find
|
||||
var/safety_dance = 1
|
||||
while(safety_dance >= 7) // And we can act like we come from out of this world.log
|
||||
var/hex = copytext(friends, safety_dance, safety_dance+1)
|
||||
if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")))
|
||||
return // Leave the fake one far behind,
|
||||
safety_dance++
|
||||
|
||||
data = new_data // And we can hex
|
||||
holder.on_data_written()
|
||||
|
||||
// This randomizes the color.
|
||||
/datum/integrated_io/color/scramble()
|
||||
if(!is_valid())
|
||||
return
|
||||
var/new_data
|
||||
for(var/i=1;i<=3;i++)
|
||||
var/temp_col = "[num2hex(rand(0,255))]"
|
||||
if(length(temp_col )<2)
|
||||
temp_col = "0[temp_col]"
|
||||
new_data += temp_col
|
||||
data = new_data
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/color/display_pin_type()
|
||||
return IC_FORMAT_COLOR
|
||||
|
||||
/datum/integrated_io/color/display_data(var/input)
|
||||
if(!isnull(data))
|
||||
return "(<font color='[data]'>[data]</font>)"
|
||||
return ..()
|
||||
@@ -0,0 +1,31 @@
|
||||
// These pins can only contain directions (1,2,4,8...) or null.
|
||||
/datum/integrated_io/dir
|
||||
name = "dir pin"
|
||||
|
||||
/datum/integrated_io/dir/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in a valid dir number. \
|
||||
Valid dirs are;\n\
|
||||
North/Fore = [NORTH],\n\
|
||||
South/Aft = [SOUTH],\n\
|
||||
East/Starboard = [EAST],\n\
|
||||
West/Port = [WEST],\n\
|
||||
Northeast = [NORTHEAST],\n\
|
||||
Northwest = [NORTHWEST],\n\
|
||||
Southeast = [SOUTHEAST],\n\
|
||||
Southwest = [SOUTHWEST]","[src] dir writing") as null|num
|
||||
if(isnum(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/dir/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || new_data in list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)/* + list(UP, DOWN)*/)
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/dir/display_pin_type()
|
||||
return IC_FORMAT_DIR
|
||||
|
||||
/datum/integrated_io/dir/display_data(var/input)
|
||||
if(!isnull(data))
|
||||
return "([dir2text(data)])"
|
||||
return ..()
|
||||
@@ -0,0 +1,148 @@
|
||||
// These pins contain a list. Null is not allowed.
|
||||
/datum/integrated_io/lists
|
||||
name = "list pin"
|
||||
data = list()
|
||||
|
||||
/datum/integrated_io/lists/ask_for_pin_data(mob/user)
|
||||
interact(user)
|
||||
|
||||
/datum/integrated_io/lists/proc/interact(mob/user)
|
||||
var/list/my_list = data
|
||||
var/t = "<h2>[src]</h2><br>"
|
||||
t += "List length: [my_list.len]<br>"
|
||||
t += "<a href='?src=[REF(src)]'>\[Refresh\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];add=1'>\[Add\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];swap=1'>\[Swap\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];clear=1'>\[Clear\]</a><br>"
|
||||
t += "<hr>"
|
||||
var/i = 0
|
||||
for(var/line in my_list)
|
||||
i++
|
||||
t += "#[i] | [display_data(line)] | "
|
||||
t += "<a href='?src=[REF(src)];edit=1;pos=[i]'>\[Edit\]</a> | "
|
||||
t += "<a href='?src=[REF(src)];remove=1;pos=[i]'>\[Remove\]</a><br>"
|
||||
user << browse(t, "window=list_pin_[REF(src)];size=500x400")
|
||||
|
||||
/datum/integrated_io/lists/proc/add_to_list(mob/user, var/new_entry)
|
||||
if(!new_entry && user)
|
||||
new_entry = ask_for_data_type(user)
|
||||
if(is_valid(new_entry))
|
||||
Add(new_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/Add(var/new_entry)
|
||||
var/list/my_list = data
|
||||
if(my_list.len > IC_MAX_LIST_LENGTH)
|
||||
my_list.Cut(Start=1,End=2)
|
||||
my_list.Add(new_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/remove_from_list_by_position(mob/user, var/position)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to remove.</span>")
|
||||
return
|
||||
if(!position)
|
||||
return
|
||||
var/target_entry = my_list.Find(position)
|
||||
if(target_entry)
|
||||
my_list.Remove(target_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/remove_from_list(mob/user, var/target_entry)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to remove.</span>")
|
||||
return
|
||||
if(!target_entry)
|
||||
target_entry = input(user, "Which piece of data do you want to remove?", "Remove") as null|anything in my_list
|
||||
if(holder.check_interactivity(user) && target_entry)
|
||||
my_list.Remove(target_entry)
|
||||
|
||||
/datum/integrated_io/lists/proc/edit_in_list(mob/user, var/target_entry)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to modify.</span>")
|
||||
return
|
||||
if(!target_entry)
|
||||
target_entry = input(user, "Which piece of data do you want to edit?", "Edit") as null|anything in my_list
|
||||
if(holder.check_interactivity(user) && target_entry)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry)
|
||||
if(edited_entry)
|
||||
target_entry = edited_entry
|
||||
|
||||
/datum/integrated_io/lists/proc/edit_in_list_by_position(mob/user, var/position)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
to_chat(user, "<span class='warning'>The list is empty, there's nothing to modify.</span>")
|
||||
return
|
||||
if(!position)
|
||||
return
|
||||
var/target_entry = my_list.Find(position)
|
||||
if(target_entry)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry)
|
||||
if(edited_entry)
|
||||
target_entry = edited_entry
|
||||
|
||||
/datum/integrated_io/lists/proc/swap_inside_list(mob/user, var/first_target, var/second_target)
|
||||
var/list/my_list = data
|
||||
if(my_list.len <= 1)
|
||||
to_chat(user, "<span class='warning'>The list is empty, or too small to do any meaningful swapping.</span>")
|
||||
return
|
||||
if(!first_target)
|
||||
first_target = input(user, "Which piece of data do you want to swap? (1)", "Swap") as null|anything in my_list
|
||||
|
||||
if(holder.check_interactivity(user) && first_target)
|
||||
if(!second_target)
|
||||
second_target = input(user, "Which piece of data do you want to swap? (2)", "Swap") as null|anything in my_list - first_target
|
||||
|
||||
if(holder.check_interactivity(user) && second_target)
|
||||
var/first_pos = my_list.Find(first_target)
|
||||
var/second_pos = my_list.Find(second_target)
|
||||
my_list.Swap(first_pos, second_pos)
|
||||
|
||||
/datum/integrated_io/lists/proc/clear_list(mob/user)
|
||||
var/list/my_list = data
|
||||
my_list.Cut()
|
||||
|
||||
/datum/integrated_io/lists/scramble()
|
||||
var/list/my_list = data
|
||||
my_list = shuffle(my_list)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/lists/write_data_to_pin(var/new_data)
|
||||
if(islist(new_data))
|
||||
var/list/new_list = new_data
|
||||
data = new_list.Copy(1,min( IC_MAX_LIST_LENGTH+1, new_list.len ))
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/lists/display_pin_type()
|
||||
return IC_FORMAT_LIST
|
||||
|
||||
/datum/integrated_io/lists/Topic(href, href_list)
|
||||
if(!holder.check_interactivity(usr))
|
||||
return
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(href_list["add"])
|
||||
add_to_list(usr)
|
||||
|
||||
if(href_list["swap"])
|
||||
swap_inside_list(usr)
|
||||
|
||||
if(href_list["clear"])
|
||||
clear_list(usr)
|
||||
|
||||
if(href_list["remove"])
|
||||
if(href_list["pos"])
|
||||
remove_from_list_by_position(usr, text2num(href_list["pos"]))
|
||||
else
|
||||
remove_from_list(usr)
|
||||
|
||||
if(href_list["edit"])
|
||||
if(href_list["pos"])
|
||||
edit_in_list_by_position(usr, text2num(href_list["pos"]))
|
||||
else
|
||||
edit_in_list(usr)
|
||||
|
||||
holder.interact(usr) // Refresh the main UI,
|
||||
interact(usr) // and the list UI.
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// These pins can only contain numbers (int and floating point) or null.
|
||||
/datum/integrated_io/number
|
||||
name = "number pin"
|
||||
// data = 0
|
||||
|
||||
/datum/integrated_io/number/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/number/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || isnum(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/number/display_pin_type()
|
||||
return IC_FORMAT_NUMBER
|
||||
@@ -0,0 +1,14 @@
|
||||
// These pins only contain weakrefs or null.
|
||||
/datum/integrated_io/ref
|
||||
name = "ref pin"
|
||||
|
||||
/datum/integrated_io/ref/ask_for_pin_data(mob/user) // This clears the pin.
|
||||
write_data_to_pin(null)
|
||||
|
||||
/datum/integrated_io/ref/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || isweakref(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/ref/display_pin_type()
|
||||
return IC_FORMAT_REF
|
||||
@@ -0,0 +1,27 @@
|
||||
// These pins can only contain text and null.
|
||||
/datum/integrated_io/string
|
||||
name = "string pin"
|
||||
|
||||
/datum/integrated_io/string/ask_for_pin_data(mob/user)
|
||||
var/new_data = input("Please type in a string.","[src] string writing") as null|text
|
||||
if(holder.check_interactivity(user) )
|
||||
to_chat(user, "<span class='notice'>You input [new_data ? "[new_data]" : "NULL"] into the pin.</span>")
|
||||
write_data_to_pin(new_data)
|
||||
|
||||
/datum/integrated_io/string/write_data_to_pin(var/new_data)
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
// This makes the text go "from this" to "#G&*!HD$%L"
|
||||
/datum/integrated_io/string/scramble()
|
||||
if(!is_valid())
|
||||
return
|
||||
var/list/options = list("!","@","#","$","%","^","&","*","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
|
||||
var/new_data = ""
|
||||
for(var/i in 1 to length(data))
|
||||
new_data += pick(options)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/string/display_pin_type()
|
||||
return IC_FORMAT_STRING
|
||||
102
code/modules/integrated_electronics/core/wirer.dm
Normal file
102
code/modules/integrated_electronics/core/wirer.dm
Normal file
@@ -0,0 +1,102 @@
|
||||
#define WIRE "wire"
|
||||
#define WIRING "wiring"
|
||||
#define UNWIRE "unwire"
|
||||
#define UNWIRING "unwiring"
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer
|
||||
name = "circuit wirer"
|
||||
desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \
|
||||
The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \
|
||||
used for power or data transmission."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "wirer-wire"
|
||||
flags_1 = CONDUCT_1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/datum/integrated_io/selected_io = null
|
||||
var/mode = WIRE
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/update_icon()
|
||||
icon_state = "wirer-[mode]"
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user)
|
||||
if(!io.holder.assembly)
|
||||
to_chat(user, "<span class='warning'>\The [io.holder] needs to be secured inside an assembly first.</span>")
|
||||
return
|
||||
if(mode == WIRE)
|
||||
selected_io = io
|
||||
to_chat(user, "<span class='notice'>You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel.</span>")
|
||||
mode = WIRING
|
||||
update_icon()
|
||||
else if(mode == WIRING)
|
||||
if(io == selected_io)
|
||||
to_chat(user, "<span class='warning'>Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless.</span>")
|
||||
return
|
||||
if(io.io_type != selected_io.io_type)
|
||||
to_chat(user, "<span class='warning'>Those two types of channels are incompatable. The first is a [selected_io.io_type], \
|
||||
while the second is a [io.io_type].</span>")
|
||||
return
|
||||
if(io.holder.assembly && io.holder.assembly != selected_io.holder.assembly)
|
||||
to_chat(user, "<span class='warning'>Both \the [io.holder] and \the [selected_io.holder] need to be inside the same assembly.</span>")
|
||||
return
|
||||
selected_io.linked |= io
|
||||
io.linked |= selected_io
|
||||
|
||||
to_chat(user, "<span class='notice'>You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name].</span>")
|
||||
mode = WIRE
|
||||
update_icon()
|
||||
selected_io.holder.interact(user) // This is to update the UI.
|
||||
selected_io = null
|
||||
|
||||
else if(mode == UNWIRE)
|
||||
selected_io = io
|
||||
if(!io.linked.len)
|
||||
to_chat(user, "<span class='warning'>There is nothing connected to \the [selected_io] data channel.</span>")
|
||||
selected_io = null
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel.</span>")
|
||||
mode = UNWIRING
|
||||
update_icon()
|
||||
return
|
||||
|
||||
else if(mode == UNWIRING)
|
||||
if(io == selected_io)
|
||||
to_chat(user, "<span class='warning'>You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \
|
||||
the same pin is rather moot.</span>")
|
||||
return
|
||||
if(selected_io in io.linked)
|
||||
io.linked.Remove(selected_io)
|
||||
selected_io.linked.Remove(io)
|
||||
to_chat(user, "<span class='notice'>You disconnect \the [selected_io.holder]'s [selected_io.name] from \
|
||||
\the [io.holder]'s [io.name].</span>")
|
||||
selected_io.holder.interact(user) // This is to update the UI.
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \
|
||||
[io.name] are not connected.</span>")
|
||||
return
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/attack_self(mob/user)
|
||||
switch(mode)
|
||||
if(WIRE)
|
||||
mode = UNWIRE
|
||||
if(WIRING)
|
||||
if(selected_io)
|
||||
to_chat(user, "<span class='notice'>You decide not to wire the data channel.</span>")
|
||||
selected_io = null
|
||||
mode = WIRE
|
||||
if(UNWIRE)
|
||||
mode = WIRE
|
||||
if(UNWIRING)
|
||||
if(selected_io)
|
||||
to_chat(user, "<span class='notice'>You decide not to disconnect the data channel.</span>")
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
update_icon()
|
||||
to_chat(user, "<span class='notice'>You set \the [src] to [mode].</span>")
|
||||
|
||||
#undef WIRE
|
||||
#undef WIRING
|
||||
#undef UNWIRE
|
||||
#undef UNWIRING
|
||||
7
code/modules/integrated_electronics/passive/passive.dm
Normal file
7
code/modules/integrated_electronics/passive/passive.dm
Normal file
@@ -0,0 +1,7 @@
|
||||
// 'Passive' components do not have any pins, and instead contribute in some form to the assembly holding them.
|
||||
/obj/item/integrated_circuit/passive
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list()
|
||||
power_draw_idle = 0
|
||||
power_draw_per_use = 0
|
||||
126
code/modules/integrated_electronics/passive/power.dm
Normal file
126
code/modules/integrated_electronics/passive/power.dm
Normal file
@@ -0,0 +1,126 @@
|
||||
|
||||
/obj/item/integrated_circuit/passive/power
|
||||
name = "power thingy"
|
||||
desc = "Does power stuff."
|
||||
complexity = 5
|
||||
origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_DATA = 2)
|
||||
category_text = "Power - Passive"
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/proc/make_energy()
|
||||
return
|
||||
|
||||
// For calculators.
|
||||
/obj/item/integrated_circuit/passive/power/solar_cell
|
||||
name = "tiny photovoltaic cell"
|
||||
desc = "It's a very tiny solar cell, generally used in calculators."
|
||||
extended_desc = "The cell generates 1W of energy per second in optimal lighting conditions. Less light will result in less power being generated."
|
||||
icon_state = "solar_cell"
|
||||
complexity = 8
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/max_power = 30
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/solar_cell/make_energy()
|
||||
var/turf/T = get_turf(src)
|
||||
var/light_amount = T ? T.get_lumcount() : 0
|
||||
var/adjusted_power = max(max_power * light_amount, 0)
|
||||
adjusted_power = round(adjusted_power, 0.1)
|
||||
if(adjusted_power)
|
||||
if(assembly)
|
||||
assembly.give_power(adjusted_power)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/starter
|
||||
name = "starter"
|
||||
desc = "This tiny circuit will send pulse right after device is turned on. Or when power is restored."
|
||||
icon_state = "led"
|
||||
complexity = 1
|
||||
activators = list("pulse out" = IC_PINTYPE_PULSE_OUT)
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/is_charge = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/starter/make_energy()
|
||||
if(assembly.battery)
|
||||
if(assembly.battery.charge)
|
||||
if(!is_charge)
|
||||
activate_pin(1)
|
||||
is_charge = TRUE
|
||||
else
|
||||
is_charge = FALSE
|
||||
else
|
||||
is_charge=FALSE
|
||||
return FALSE
|
||||
|
||||
// For fat machines that need fat power, like drones.
|
||||
/obj/item/integrated_circuit/passive/power/relay
|
||||
name = "tesla power relay"
|
||||
desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
extended_desc = "The siphon generates 250W of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \
|
||||
from the 'equipment' power channel."
|
||||
icon_state = "power_relay"
|
||||
complexity = 7
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
var/power_amount = 150
|
||||
//fuel cell
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell
|
||||
name = "fuel cell"
|
||||
desc = "Produces electricity from chemicals."
|
||||
icon_state = "chemical_cell"
|
||||
extended_desc = "This is effectively an internal beaker.It will consume and produce power from phoron, slime jelly, welding fuel, carbon,\
|
||||
ethanol, nutriments and blood , in order of decreasing efficiency. It will consume fuel only if the battery can take more energy."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/volume = 60
|
||||
var/list/fuel = list("plasma" = 10000, "welding_fuel" = 3000, "carbon" = 2000, "ethanol"= 2000, "nutriment" =1600, "blood" = 1000)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/New()
|
||||
..()
|
||||
create_reagents(volume)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/make_energy()
|
||||
if(assembly)
|
||||
if(assembly.battery)
|
||||
for(var/I in fuel)
|
||||
if((assembly.battery.maxcharge-assembly.battery.charge) / GLOB.CELLRATE > fuel[I])
|
||||
if(reagents.remove_reagent(I, 1))
|
||||
assembly.give_power(fuel[I])
|
||||
|
||||
|
||||
// For really fat machines.
|
||||
/obj/item/integrated_circuit/passive/power/relay/large
|
||||
name = "large tesla power relay"
|
||||
desc = "A seemingly enigmatic device which connects to nearby APCs wirelessly and draws power from them, now in industiral size!"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
extended_desc = "The siphon generates 2 kW of energy, so long as an APC is in the same room, with a cell that has energy. It will always drain \
|
||||
from the 'equipment' power channel."
|
||||
icon_state = "power_relay"
|
||||
complexity = 15
|
||||
origin_tech = list(TECH_POWER = 6, TECH_ENGINEERING = 5, TECH_DATA = 4)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_amount = 1000
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/relay/make_energy()
|
||||
if(!assembly)
|
||||
return
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
if(A.powered(EQUIP) && assembly.give_power(power_amount))
|
||||
A.use_power(power_amount, EQUIP)
|
||||
// give_power() handles CELLRATE on its own.
|
||||
319
code/modules/integrated_electronics/subtypes/arithmetic.dm
Normal file
319
code/modules/integrated_electronics/subtypes/arithmetic.dm
Normal file
@@ -0,0 +1,319 @@
|
||||
//These circuits do simple math.
|
||||
/obj/item/integrated_circuit/arithmetic
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_NUMBER,
|
||||
"B" = IC_PINTYPE_NUMBER,
|
||||
"C" = IC_PINTYPE_NUMBER,
|
||||
"D" = IC_PINTYPE_NUMBER,
|
||||
"E" = IC_PINTYPE_NUMBER,
|
||||
"F" = IC_PINTYPE_NUMBER,
|
||||
"G" = IC_PINTYPE_NUMBER,
|
||||
"H" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_NUMBER)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Arithmetic"
|
||||
power_draw_per_use = 5 // Math is pretty cheap.
|
||||
|
||||
// +Adding+ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/addition
|
||||
name = "addition circuit"
|
||||
desc = "This circuit can add numbers together."
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A + B) + C) + D) ... ) and so on, until all pins have been added. \
|
||||
Null pins are ignored."
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/addition/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result + I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// -Subtracting- //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction
|
||||
name = "subtraction circuit"
|
||||
desc = "This circuit can subtract numbers."
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A - B) - C) - D) ... ) and so on, until all pins have been subtracted. \
|
||||
Null pins are ignored. Pin A <b>must</b> be a number or the circuit will not function."
|
||||
icon_state = "subtraction"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction/do_work()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result - I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// *Multiply* //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/multiplication
|
||||
name = "multiplication circuit"
|
||||
desc = "This circuit can multiply numbers."
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A * B) * C) * D) ... ) and so on, until all pins have been multiplied. \
|
||||
Null pins are ignored. Pin A <b>must</b> be a number or the circuit will not function."
|
||||
icon_state = "multiplication"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/multiplication/do_work()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result * I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// /Division/ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/division
|
||||
name = "division circuit"
|
||||
desc = "This circuit can divide numbers, just don't think about trying to divide by zero!"
|
||||
extended_desc = "The order that the calculation goes is;<br>\
|
||||
result = ((((A / B) / C) / D) ... ) and so on, until all pins have been divided. \
|
||||
Null pins, and pins containing 0, are ignored. Pin A <b>must</b> be a number or the circuit will not function."
|
||||
icon_state = "division"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/division/do_work()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(!isnum(A.data))
|
||||
return
|
||||
var/result = A.data
|
||||
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
if(I == A)
|
||||
continue
|
||||
I.pull_data()
|
||||
if(isnum(I.data) && I.data != 0) //No runtimes here.
|
||||
result = result / I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
//^ Exponent ^//
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/exponent
|
||||
name = "exponent circuit"
|
||||
desc = "Outputs A to the power of B."
|
||||
icon_state = "exponent"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/exponent/do_work()
|
||||
var/result = 0
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
if(isnum(A.data) && isnum(B.data))
|
||||
result = A.data ** B.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// +-Sign-+ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/sign
|
||||
name = "sign circuit"
|
||||
desc = "This will say if a number is positive, negative, or zero."
|
||||
extended_desc = "Will output 1, -1, or 0, depending on if A is a postive number, a negative number, or zero, respectively."
|
||||
icon_state = "sign"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/sign/do_work()
|
||||
var/result = 0
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
if(isnum(A.data))
|
||||
if(A.data > 0)
|
||||
result = 1
|
||||
else if (A.data < 0)
|
||||
result = -1
|
||||
else
|
||||
result = 0
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Round //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/round
|
||||
name = "round circuit"
|
||||
desc = "Rounds A to the nearest B multiple of A."
|
||||
extended_desc = "If B is not given a number, it will output the floor of A instead."
|
||||
icon_state = "round"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/round/do_work()
|
||||
var/result = 0
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
if(isnum(A.data))
|
||||
if(isnum(B.data) && B.data != 0)
|
||||
result = round(A.data, B.data)
|
||||
else
|
||||
result = round(A.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Absolute //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/absolute
|
||||
name = "absolute circuit"
|
||||
desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero."
|
||||
icon_state = "absolute"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/absolute/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = abs(I.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Averaging //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/average
|
||||
name = "average circuit"
|
||||
desc = "This circuit is of average quality, however it will compute the average for numbers you give it."
|
||||
extended_desc = "Note that null pins are ignored, where as a pin containing 0 is included in the averaging calculation."
|
||||
icon_state = "average"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/average/do_work()
|
||||
var/result = 0
|
||||
var/inputs_used = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
inputs_used++
|
||||
result = result + I.data
|
||||
|
||||
if(inputs_used)
|
||||
result = result / inputs_used
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Pi, because why the hell not? //
|
||||
/obj/item/integrated_circuit/arithmetic/pi
|
||||
name = "pi constant circuit"
|
||||
desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse."
|
||||
icon_state = "pi"
|
||||
inputs = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/pi/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, 3.14159)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Random //
|
||||
/obj/item/integrated_circuit/arithmetic/random
|
||||
name = "random number generator circuit"
|
||||
desc = "This gives a random (integer) number between values A and B inclusive."
|
||||
extended_desc = "'Inclusive' means that the upper bound is included in the range of numbers, e.g. L = 1 and H = 3 will allow \
|
||||
for outputs of 1, 2, or 3. H being the higher number is not <i>strictly</i> required."
|
||||
icon_state = "random"
|
||||
inputs = list("L" = IC_PINTYPE_NUMBER,"H" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/random/do_work()
|
||||
var/result = 0
|
||||
var/L = get_pin_data(IC_INPUT, 1)
|
||||
var/H = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(isnum(L) && isnum(H))
|
||||
result = rand(L, H)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Square Root //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/square_root
|
||||
name = "square root circuit"
|
||||
desc = "This outputs the square root of a number you put in."
|
||||
icon_state = "square_root"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/square_root/do_work()
|
||||
var/result = 0
|
||||
for(var/k in 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[k]
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = sqrt(I.data)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// % Modulo % //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/modulo
|
||||
name = "modulo circuit"
|
||||
desc = "Gets the remainder of A / B."
|
||||
icon_state = "modulo"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER, "B" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/modulo/do_work()
|
||||
var/result = 0
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
var/B = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(A) && isnum(B) && B != 0)
|
||||
result = A % B
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
320
code/modules/integrated_electronics/subtypes/converters.dm
Normal file
320
code/modules/integrated_electronics/subtypes/converters.dm
Normal file
@@ -0,0 +1,320 @@
|
||||
//These circuits convert one variable to another.
|
||||
/obj/item/integrated_circuit/converter
|
||||
complexity = 2
|
||||
inputs = list("input")
|
||||
outputs = list("output")
|
||||
activators = list("convert" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Converter"
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/converter/num2text
|
||||
name = "number to string"
|
||||
desc = "This circuit can convert a number variable into a string."
|
||||
extended_desc = "Because of game limitations null/false variables will output a '0' string."
|
||||
icon_state = "num-string"
|
||||
inputs = list("input" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/num2text/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = num2text(incoming)
|
||||
else if(!incoming)
|
||||
result = "0"
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/text2num
|
||||
name = "string to number"
|
||||
desc = "This circuit can convert a string variable into a number."
|
||||
icon_state = "string-num"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/text2num/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = text2num(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/ref2text
|
||||
name = "reference to string"
|
||||
desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference."
|
||||
icon_state = "ref-string"
|
||||
inputs = list("input" = IC_PINTYPE_REF)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/ref2text/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/atom/A = get_pin_data(IC_INPUT, 1)
|
||||
if(A && istype(A))
|
||||
result = A.name
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/refcode
|
||||
name = "reference encoder"
|
||||
desc = "This circuit can encode a reference into a string, which can then be read by an EPV2 circuit."
|
||||
icon_state = "ref-string"
|
||||
inputs = list("input" = IC_PINTYPE_REF)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/refcode/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/atom/A = get_pin_data(IC_INPUT, 1)
|
||||
if(A && istype(A))
|
||||
result = strtohex(XorEncrypt(REF(A),SScircuit.cipherkey))
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/refdecode
|
||||
name = "reference decoder"
|
||||
desc = "This circuit can convert a encoded reference to actual reference."
|
||||
icon_state = "ref-string"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_REF)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/dec
|
||||
|
||||
/obj/item/integrated_circuit/converter/refdecode/do_work()
|
||||
pull_data()
|
||||
dec=XorEncrypt(hextostr(get_pin_data(IC_INPUT, 1)),SScircuit.cipherkey)
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(locate( dec )))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/lowercase
|
||||
name = "lowercase string converter"
|
||||
desc = "this will cause a string to come out in all lowercase."
|
||||
icon_state = "lowercase"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/lowercase/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = lowertext(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/uppercase
|
||||
name = "uppercase string converter"
|
||||
desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE."
|
||||
icon_state = "uppercase"
|
||||
inputs = list("input" = IC_PINTYPE_STRING)
|
||||
outputs = list("output" = IC_PINTYPE_STRING)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/uppercase/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = uppertext(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator
|
||||
name = "concatenator"
|
||||
desc = "This joins many strings together to get one big string."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_STRING,
|
||||
"B" = IC_PINTYPE_STRING,
|
||||
"C" = IC_PINTYPE_STRING,
|
||||
"D" = IC_PINTYPE_STRING,
|
||||
"E" = IC_PINTYPE_STRING,
|
||||
"F" = IC_PINTYPE_STRING,
|
||||
"G" = IC_PINTYPE_STRING,
|
||||
"H" = IC_PINTYPE_STRING
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_STRING)
|
||||
activators = list("concatenate" = IC_PINTYPE_PULSE_IN, "on concatenated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenator/do_work()
|
||||
var/result = null
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
I.pull_data()
|
||||
if(!isnull(I.data))
|
||||
result = result + I.data
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/separator
|
||||
name = "separator"
|
||||
desc = "This splits as single string into two at the relative split point."
|
||||
extended_desc = "This circuits splits a given string into two, based on the string, and the index value. \
|
||||
The index splits the string <b>after</b> the given index, including spaces. So 'a person' with an index of '3' \
|
||||
will split into 'a p' and 'erson'."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string to split" = IC_PINTYPE_STRING,
|
||||
"index" = IC_PINTYPE_NUMBER,
|
||||
)
|
||||
outputs = list(
|
||||
"before split" = IC_PINTYPE_STRING,
|
||||
"after split" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/separator/do_work()
|
||||
var/text = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
var/split = min(index+1, length(text))
|
||||
|
||||
var/before_text = copytext(text, 1, split)
|
||||
var/after_text = copytext(text, split, 0)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, before_text)
|
||||
set_pin_data(IC_OUTPUT, 2, after_text)
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring
|
||||
name = "find text"
|
||||
desc = "This gives position of sample in the string. Or returns 0."
|
||||
extended_desc = "The first pin is the string to be examined. The second pin is the sample to be found. \
|
||||
For example, 'eat this burger',' ' will give you position 4. This circuit isn't case sensitive."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string" = IC_PINTYPE_STRING,
|
||||
"sample" = IC_PINTYPE_STRING,
|
||||
)
|
||||
outputs = list(
|
||||
"position" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring/do_work()
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/exploders
|
||||
name = "string exploder"
|
||||
desc = "This splits a single string into a list of strings."
|
||||
extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
|
||||
For example, 'eat this burger',' ' will be converted to list('eat','this','burger')."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string to split" = IC_PINTYPE_STRING,
|
||||
"delimiter" = IC_PINTYPE_STRING,
|
||||
)
|
||||
outputs = list(
|
||||
"list" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/exploders/do_work()
|
||||
var/strin = get_pin_data(IC_INPUT, 1)
|
||||
var/sample = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample ))
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/radians2degrees
|
||||
name = "radians to degrees converter"
|
||||
desc = "Converts radians to degrees."
|
||||
inputs = list("radian" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("degrees" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/radians2degrees/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = ToDegrees(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/degrees2radians
|
||||
name = "degrees to radians converter"
|
||||
desc = "Converts degrees to radians."
|
||||
inputs = list("degrees" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("radians" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/degrees2radians/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/incoming = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(incoming))
|
||||
result = ToRadians(incoming)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/converter/abs_to_rel_coords
|
||||
name = "abs to rel coordinate converter"
|
||||
desc = "Easily convert absolute coordinates to relative coordinates with this."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"X1" = IC_PINTYPE_NUMBER,
|
||||
"Y1" = IC_PINTYPE_NUMBER,
|
||||
"X2" = IC_PINTYPE_NUMBER,
|
||||
"Y2" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list(
|
||||
"X" = IC_PINTYPE_NUMBER,
|
||||
"Y" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("compute rel coordinates" = IC_PINTYPE_PULSE_IN, "on convert" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/abs_to_rel_coords/do_work()
|
||||
var/x1 = get_pin_data(IC_INPUT, 1)
|
||||
var/y1 = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
var/x2 = get_pin_data(IC_INPUT, 3)
|
||||
var/y2 = get_pin_data(IC_INPUT, 4)
|
||||
|
||||
if(!isnull(x1) && !isnull(y1) && !isnull(x2) && !isnull(y2))
|
||||
set_pin_data(IC_OUTPUT, 1, x1 - x2)
|
||||
set_pin_data(IC_OUTPUT, 2, y1 - y2)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
146
code/modules/integrated_electronics/subtypes/data_transfer.dm
Normal file
146
code/modules/integrated_electronics/subtypes/data_transfer.dm
Normal file
@@ -0,0 +1,146 @@
|
||||
/obj/item/integrated_circuit/transfer
|
||||
category_text = "Data Transfer"
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer
|
||||
name = "two multiplexer"
|
||||
desc = "This is what those in the business tend to refer to as a 'mux' or data selector. It moves data from one of the selected inputs to the output."
|
||||
extended_desc = "The first input pin is used to select which of the other input pins which has its data moved to the output. \
|
||||
If the input selection is outside the valid range then no output is given."
|
||||
complexity = 2
|
||||
icon_state = "mux2"
|
||||
inputs = list("input selection" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("output" = IC_PINTYPE_ANY)
|
||||
activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
var/number_of_inputs = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/New()
|
||||
for(var/i = 1 to number_of_inputs)
|
||||
inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called.
|
||||
// inputs += "input [i]"
|
||||
complexity = number_of_inputs
|
||||
..()
|
||||
desc += " It has [number_of_inputs] input pins."
|
||||
extended_desc += " This multiplexer has a range from 1 to [inputs.len - 1]."
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/do_work()
|
||||
var/input_index = get_pin_data(IC_INPUT, 1)
|
||||
|
||||
if(!isnull(input_index) && (input_index >= 1 && input_index < inputs.len))
|
||||
set_pin_data(IC_OUTPUT, 1,get_pin_data(IC_INPUT, input_index + 1))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/medium
|
||||
name = "four multiplexer"
|
||||
number_of_inputs = 4
|
||||
icon_state = "mux4"
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/large
|
||||
name = "eight multiplexer"
|
||||
number_of_inputs = 8
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon_state = "mux8"
|
||||
|
||||
/obj/item/integrated_circuit/transfer/multiplexer/huge
|
||||
name = "sixteen multiplexer"
|
||||
icon_state = "mux16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_inputs = 16
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer
|
||||
name = "two demultiplexer"
|
||||
desc = "This is what those in the business tend to refer to as a 'demux'. It moves data from the input to one of the selected outputs."
|
||||
extended_desc = "The first input pin is used to select which of the output pins is given the data from the second input pin. \
|
||||
If the output selection is outside the valid range then no output is given."
|
||||
complexity = 2
|
||||
icon_state = "dmux2"
|
||||
inputs = list("output selection" = IC_PINTYPE_NUMBER, "input" = IC_PINTYPE_ANY)
|
||||
outputs = list()
|
||||
activators = list("select" = IC_PINTYPE_PULSE_IN, "on select" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
var/number_of_outputs = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/New()
|
||||
for(var/i = 1 to number_of_outputs)
|
||||
// outputs += "output [i]"
|
||||
outputs["output [i]"] = IC_PINTYPE_ANY
|
||||
complexity = number_of_outputs
|
||||
|
||||
..()
|
||||
desc += " It has [number_of_outputs] output pins."
|
||||
extended_desc += " This demultiplexer has a range from 1 to [outputs.len]."
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/do_work()
|
||||
var/output_index = get_pin_data(IC_INPUT, 1)
|
||||
for(var/i = 1 to outputs.len)
|
||||
set_pin_data(IC_OUTPUT, i, i == output_index ? get_pin_data(IC_INPUT, 2) : null)
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/medium
|
||||
name = "four demultiplexer"
|
||||
icon_state = "dmux4"
|
||||
number_of_outputs = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/large
|
||||
name = "eight demultiplexer"
|
||||
icon_state = "dmux8"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/demultiplexer/huge
|
||||
name = "sixteen demultiplexer"
|
||||
icon_state = "dmux16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 16
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer
|
||||
name = "two pulse demultiplexer"
|
||||
desc = "Selector switch to choose the pin to be activated by number."
|
||||
extended_desc = "The first input pin is used to select which of the pulse out pins will be activated after activation of the circuit. \
|
||||
If the output selection is outside the valid range then no output is given."
|
||||
complexity = 2
|
||||
icon_state = "dmux2"
|
||||
inputs = list("output selection" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("select" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
var/number_of_outputs = 2
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/New()
|
||||
for(var/i = 1 to number_of_outputs)
|
||||
// outputs += "output [i]"
|
||||
activators["output [i]"] = IC_PINTYPE_PULSE_OUT
|
||||
complexity = number_of_outputs
|
||||
|
||||
..()
|
||||
desc += " It has [number_of_outputs] output pins."
|
||||
extended_desc += " This pulse demultiplexer has a range from 1 to [activators.len - 1]."
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/do_work()
|
||||
var/output_index = get_pin_data(IC_INPUT, 1)
|
||||
|
||||
if(output_index == Clamp(output_index, 1, number_of_outputs))
|
||||
activate_pin(round(output_index + 1 ,1))
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/medium
|
||||
name = "four pulse demultiplexer"
|
||||
icon_state = "dmux4"
|
||||
number_of_outputs = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/large
|
||||
name = "eight pulse demultiplexer"
|
||||
icon_state = "dmux8"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/pulsedemultiplexer/huge
|
||||
name = "sixteen pulse demultiplexer"
|
||||
icon_state = "dmux16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
number_of_outputs = 16
|
||||
806
code/modules/integrated_electronics/subtypes/input.dm
Normal file
806
code/modules/integrated_electronics/subtypes/input.dm
Normal file
@@ -0,0 +1,806 @@
|
||||
/obj/item/integrated_circuit/input
|
||||
var/can_be_asked_input = 0
|
||||
category_text = "Input"
|
||||
power_draw_per_use = 5
|
||||
|
||||
/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/input/button
|
||||
name = "button"
|
||||
desc = "This tiny button must do something, right?"
|
||||
icon_state = "button"
|
||||
complexity = 1
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list("on pressed" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use.
|
||||
to_chat(user, "<span class='notice'>You press the button labeled '[src]'.</span>")
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/toggle_button
|
||||
name = "toggle button"
|
||||
desc = "It toggles on, off, on, off..."
|
||||
icon_state = "toggle_button"
|
||||
complexity = 1
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("on" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("on toggle" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/input/toggle_button/ask_for_input(mob/user) // Ditto.
|
||||
set_pin_data(IC_OUTPUT, 1, !get_pin_data(IC_OUTPUT, 1))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
to_chat(user, "<span class='notice'>You toggle the button labeled '[src]' [get_pin_data(IC_OUTPUT, 1) ? "on" : "off"].</span>")
|
||||
|
||||
/obj/item/integrated_circuit/input/numberpad
|
||||
name = "number pad"
|
||||
desc = "This small number pad allows someone to input a number into the system."
|
||||
icon_state = "numberpad"
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("number entered" = IC_PINTYPE_NUMBER)
|
||||
activators = list("on entered" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user)
|
||||
var/new_input = input(user, "Enter a number, please.","Number pad") as null|num
|
||||
if(isnum(new_input) && user.IsAdvancedToolUser())
|
||||
set_pin_data(IC_OUTPUT, 1, new_input)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/textpad
|
||||
name = "text pad"
|
||||
desc = "This small text pad allows someone to input a string into the system."
|
||||
icon_state = "textpad"
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("string entered" = IC_PINTYPE_STRING)
|
||||
activators = list("on entered" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user)
|
||||
var/new_input = input(user, "Enter some words, please.","Number pad") as null|text
|
||||
if(istext(new_input) && user.IsAdvancedToolUser())
|
||||
set_pin_data(IC_OUTPUT, 1, new_input)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/med_scanner
|
||||
name = "integrated medical analyser"
|
||||
desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is."
|
||||
icon_state = "medscan"
|
||||
complexity = 4
|
||||
inputs = list("\<REF\> target")
|
||||
outputs = list(
|
||||
"total health %" = IC_PINTYPE_NUMBER,
|
||||
"total missing health" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/input/med_scanner/do_work()
|
||||
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
|
||||
var/missing_health = H.getMaxHealth() - H.health
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, total_health)
|
||||
set_pin_data(IC_OUTPUT, 2, missing_health)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
/*
|
||||
/obj/item/integrated_circuit/input/pressure_plate
|
||||
name = "pressure plate"
|
||||
desc = "Electronic plate with a scanner, that could retrieve references to things,that was put onto the machine"
|
||||
icon_state = "pressure_plate"
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("laid" = IC_PINTYPE_REF, "removed" = IC_PINTYPE_REF)
|
||||
activators = list("laid" = IC_PINTYPE_PULSE_OUT, "removed" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
power_draw_per_use = 40
|
||||
var/list/cont
|
||||
|
||||
/obj/item/integrated_circuit/input/pressure_plate/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/integrated_circuit/input/pressure_plate/Destroy()
|
||||
processing_objects -= src
|
||||
|
||||
/obj/item/integrated_circuit/input/pressure_plate/process()
|
||||
var/list/newcont
|
||||
var/turf/T = get_turf(src)
|
||||
newcont = T.contents
|
||||
var/list/U = cont & newcont
|
||||
for(var/laid in U)
|
||||
if(!(laid in cont))
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = WEAKREF(laid)
|
||||
O.push_data()
|
||||
activate_pin(1)
|
||||
break
|
||||
for(var/removed in U)
|
||||
if(!(removed in newcont))
|
||||
var/datum/integrated_io/O = outputs[2]
|
||||
O.data = WEAKREF(removed)
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
break
|
||||
cont = newcont
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/adv_med_scanner
|
||||
name = "integrated advanced medical analyser"
|
||||
desc = "A very small version of the medbot's medical analyser. This allows the machine to know how healthy someone is. \
|
||||
This type is much more precise, allowing the machine to know much more about the target than a normal analyzer."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 12
|
||||
inputs = list("\<REF\> target")
|
||||
outputs = list(
|
||||
"total health %" = IC_PINTYPE_NUMBER,
|
||||
"total missing health" = IC_PINTYPE_NUMBER,
|
||||
"brute damage" = IC_PINTYPE_NUMBER,
|
||||
"burn damage" = IC_PINTYPE_NUMBER,
|
||||
"tox damage" = IC_PINTYPE_NUMBER,
|
||||
"oxy damage" = IC_PINTYPE_NUMBER,
|
||||
"clone damage" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
|
||||
power_draw_per_use = 80
|
||||
|
||||
/obj/item/integrated_circuit/input/adv_med_scanner/do_work()
|
||||
var/mob/living/carbon/human/H = get_pin_data_as_type(IC_INPUT, 1, /mob/living/carbon/human)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
var/total_health = round(H.health/H.getMaxHealth(), 0.01)*100
|
||||
var/missing_health = H.getMaxHealth() - H.health
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, total_health)
|
||||
set_pin_data(IC_OUTPUT, 2, missing_health)
|
||||
set_pin_data(IC_OUTPUT, 3, H.getBruteLoss())
|
||||
set_pin_data(IC_OUTPUT, 4, H.getFireLoss())
|
||||
set_pin_data(IC_OUTPUT, 5, H.getToxLoss())
|
||||
set_pin_data(IC_OUTPUT, 6, H.getOxyLoss())
|
||||
set_pin_data(IC_OUTPUT, 7, H.getCloneLoss())
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/plant_scanner
|
||||
name = "integrated plant analyzer"
|
||||
desc = "A very small version of the plant analyser. This allows the machine to know all valuable params of plants in trays. \
|
||||
it can't scan seeds and fruits.only plants."
|
||||
icon_state = "medscan_adv"
|
||||
complexity = 12
|
||||
inputs = list("\<REF\> target")
|
||||
outputs = list(
|
||||
"plant type" = IC_PINTYPE_STRING,
|
||||
"age" = IC_PINTYPE_NUMBER,
|
||||
"potency" = IC_PINTYPE_NUMBER,
|
||||
"yield" = IC_PINTYPE_NUMBER,
|
||||
"Maturation speed" = IC_PINTYPE_NUMBER,
|
||||
"Production speed" = IC_PINTYPE_NUMBER,
|
||||
"Endurance" = IC_PINTYPE_NUMBER,
|
||||
"Lifespan" = IC_PINTYPE_NUMBER,
|
||||
"Weed Growth Rate" = IC_PINTYPE_NUMBER,
|
||||
"Weed Vulnerability" = IC_PINTYPE_NUMBER,
|
||||
"Weed level" = IC_PINTYPE_NUMBER,
|
||||
"Pest level" = IC_PINTYPE_NUMBER,
|
||||
"Toxicity level" = IC_PINTYPE_NUMBER,
|
||||
"Water level" = IC_PINTYPE_NUMBER,
|
||||
"Nutrition level" = IC_PINTYPE_NUMBER,
|
||||
"harvest" = IC_PINTYPE_NUMBER,
|
||||
"dead" = IC_PINTYPE_NUMBER ,
|
||||
"plant health" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/input/plant_scanner/do_work()
|
||||
var/obj/machinery/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
for(var/i=1, i<=outputs.len, i++)
|
||||
set_pin_data(IC_OUTPUT, i, null)
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H.myseed)
|
||||
set_pin_data(IC_OUTPUT, 1, H.myseed.plantname)
|
||||
set_pin_data(IC_OUTPUT, 2, H.age)
|
||||
set_pin_data(IC_OUTPUT, 3, H.myseed.potency)
|
||||
set_pin_data(IC_OUTPUT, 4, H.myseed.yield)
|
||||
set_pin_data(IC_OUTPUT, 5, H.myseed.maturation)
|
||||
set_pin_data(IC_OUTPUT, 6, H.myseed.production)
|
||||
set_pin_data(IC_OUTPUT, 7, H.myseed.endurance)
|
||||
set_pin_data(IC_OUTPUT, 8, H.myseed.lifespan)
|
||||
set_pin_data(IC_OUTPUT, 9, H.myseed.weed_rate)
|
||||
set_pin_data(IC_OUTPUT, 10, H.myseed.weed_chance)
|
||||
set_pin_data(IC_OUTPUT, 11, H.weedlevel)
|
||||
set_pin_data(IC_OUTPUT, 12, H.pestlevel)
|
||||
set_pin_data(IC_OUTPUT, 13, H.toxic)
|
||||
set_pin_data(IC_OUTPUT, 14, H.waterlevel)
|
||||
set_pin_data(IC_OUTPUT, 15, H.nutrilevel)
|
||||
set_pin_data(IC_OUTPUT, 16, H.harvest)
|
||||
set_pin_data(IC_OUTPUT, 17, H.dead)
|
||||
set_pin_data(IC_OUTPUT, 18, H.plant_health)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/gene_scanner
|
||||
name = "gene scanner"
|
||||
desc = "This circuit will scan plant for traits and reagent genes."
|
||||
extended_desc = "This allows the machine to scan plants in trays for reagent and trait genes. \
|
||||
it can't scan seeds and fruits.only plants."
|
||||
inputs = list(
|
||||
"\<REF\> target" = IC_PINTYPE_REF
|
||||
)
|
||||
outputs = list(
|
||||
"traits" = IC_PINTYPE_LIST,
|
||||
"reagents" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
icon_state = "medscan_adv"
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/input/gene_scanner/do_work()
|
||||
var/list/gtraits = list()
|
||||
var/list/greagents = list()
|
||||
var/obj/machinery/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
for(var/i=1, i<=outputs.len, i++)
|
||||
set_pin_data(IC_OUTPUT, i, null)
|
||||
if(H in view(get_turf(H))) // Like medbot's analyzer it can be used in range..
|
||||
if(H.myseed)
|
||||
for(var/datum/plant_gene/reagent/G in H.myseed.genes)
|
||||
greagents.Add(G.get_name())
|
||||
|
||||
for(var/datum/plant_gene/trait/G in H.myseed.genes)
|
||||
gtraits.Add(G.get_name())
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, gtraits)
|
||||
set_pin_data(IC_OUTPUT, 2, greagents)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/examiner
|
||||
name = "examiner"
|
||||
desc = "It' s a little machine vision system. It can return the name, description, distance, \
|
||||
relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object."
|
||||
icon_state = "video_camera"
|
||||
complexity = 6
|
||||
inputs = list("\<REF\> target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"name" = IC_PINTYPE_STRING,
|
||||
"description" = IC_PINTYPE_STRING,
|
||||
"X" = IC_PINTYPE_NUMBER,
|
||||
"Y" = IC_PINTYPE_NUMBER,
|
||||
"distance" = IC_PINTYPE_NUMBER,
|
||||
"max reagents" = IC_PINTYPE_NUMBER,
|
||||
"amount of reagents" = IC_PINTYPE_NUMBER,
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
|
||||
power_draw_per_use = 80
|
||||
|
||||
/obj/item/integrated_circuit/input/examiner/do_work()
|
||||
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
|
||||
if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see.
|
||||
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, H.name)
|
||||
set_pin_data(IC_OUTPUT, 2, H.desc)
|
||||
set_pin_data(IC_OUTPUT, 3, H.x-T.x)
|
||||
set_pin_data(IC_OUTPUT, 4, H.y-T.y)
|
||||
set_pin_data(IC_OUTPUT, 5, sqrt((H.x-T.x)*(H.x-T.x)+ (H.y-T.y)*(H.y-T.y)))
|
||||
var/mr = 0
|
||||
var/tr = 0
|
||||
if(H.reagents)
|
||||
mr = H.reagents.maximum_volume
|
||||
tr = H.reagents.total_volume
|
||||
set_pin_data(IC_OUTPUT, 6, mr)
|
||||
set_pin_data(IC_OUTPUT, 7, tr)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/local_locator
|
||||
name = "local locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \
|
||||
that is holding the machine containing it."
|
||||
inputs = list()
|
||||
outputs = list("located ref")
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/input/local_locator/do_work()
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
if(assembly)
|
||||
if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us.
|
||||
O.data = WEAKREF(assembly.loc)
|
||||
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/adjacent_locator
|
||||
name = "adjacent locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \
|
||||
that is standing a meter away from the machine."
|
||||
extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. This means that it will \
|
||||
give refs to nearby objects that are similar. If more than one valid object is found nearby, it will choose one of them at \
|
||||
random."
|
||||
inputs = list("desired type ref")
|
||||
outputs = list("located ref")
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,
|
||||
"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
|
||||
/obj/item/integrated_circuit/input/adjacent_locator/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
|
||||
if(!isweakref(I.data))
|
||||
return
|
||||
var/atom/A = I.data.resolve()
|
||||
if(!A)
|
||||
return
|
||||
var/desired_type = A.type
|
||||
|
||||
var/list/nearby_things = range(1, get_turf(src))
|
||||
var/list/valid_things = list()
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type != desired_type)
|
||||
continue
|
||||
valid_things.Add(thing)
|
||||
if(valid_things.len)
|
||||
O.data = WEAKREF(pick(valid_things))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list
|
||||
complexity = 6
|
||||
name = "list advanced locator"
|
||||
desc = "This is needed for certain devices that demand list of names for a targets to act upon. This type locates something \
|
||||
that is standing in given radius up to 8 meters"
|
||||
extended_desc = "The first pin requires list a kinds of object that you want the locator to acquire. If This means that it will \
|
||||
give refs to nearby objects that are similar. It will locate objects by given names and description,given in list. It will give list of all found objects.\
|
||||
.The second pin is a radius"
|
||||
inputs = list("desired type ref" = IC_PINTYPE_LIST, "radius" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("located ref" = IC_PINTYPE_LIST)
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
var/radius = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/nearby_things = view(radius,T)
|
||||
var/list/valid_things = list()
|
||||
var/list/GI = list()
|
||||
GI = I.data
|
||||
for(var/G in GI)
|
||||
if(isweakref(G)) //It should search by refs. But don't want.will fix it later.
|
||||
var/datum/integrated_io/G1
|
||||
G1.data = G
|
||||
var/atom/A = G1.data.resolve()
|
||||
var/desired_type = A.type
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type != desired_type)
|
||||
continue
|
||||
valid_things.Add(WEAKREF(thing))
|
||||
else if(istext(G))
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(findtext(addtext(thing.name," ",thing.desc), G, 1, 0) )
|
||||
valid_things.Add(WEAKREF(thing))
|
||||
if(valid_things.len)
|
||||
O.data = valid_things
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
O.push_data()
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator
|
||||
complexity = 6
|
||||
name = "advanced locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type locates something \
|
||||
that is standing in given radius up to 8 meters"
|
||||
extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. If This means that it will \
|
||||
give refs to nearby objects that are similar. If this pin is string, locator will search\
|
||||
item by matching desired text in name + description. If more than one valid object is found nearby, it will choose one of them at \
|
||||
random. The second pin is a radius."
|
||||
inputs = list("desired type" = IC_PINTYPE_ANY, "radius" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("located ref")
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
var/radius = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/nearby_things = view(radius,T)
|
||||
var/list/valid_things = list()
|
||||
if(isweakref(I.data))
|
||||
var/atom/A = I.data.resolve()
|
||||
var/desired_type = A.type
|
||||
if(desired_type)
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type == desired_type)
|
||||
valid_things.Add(thing)
|
||||
else if(istext(I.data))
|
||||
var/DT = I.data
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(findtext(addtext(thing.name," ",thing.desc), DT, 1, 0) )
|
||||
valid_things.Add(thing)
|
||||
if(valid_things.len)
|
||||
O.data = WEAKREF(pick(valid_things))
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
O.push_data()
|
||||
activate_pin(3)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler
|
||||
name = "integrated signaler"
|
||||
desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well."
|
||||
extended_desc = "When a signal is received from another signaler, the 'on signal received' activator pin will be pulsed. \
|
||||
The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it. \
|
||||
Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin."
|
||||
icon_state = "signal"
|
||||
complexity = 4
|
||||
inputs = list("frequency" = IC_PINTYPE_NUMBER,"code" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list(
|
||||
"send signal" = IC_PINTYPE_PULSE_IN,
|
||||
"on signal sent" = IC_PINTYPE_PULSE_OUT,
|
||||
"on signal received" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2)
|
||||
power_draw_idle = 5
|
||||
power_draw_per_use = 40
|
||||
|
||||
var/frequency = 1457
|
||||
var/code = 30
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/Initialize()
|
||||
..()
|
||||
spawn(40)
|
||||
set_frequency(frequency)
|
||||
// Set the pins so when someone sees them, they won't show as null
|
||||
set_pin_data(IC_INPUT, 1, frequency)
|
||||
set_pin_data(IC_INPUT, 2, code)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/Destroy()
|
||||
SSradio.remove_object(src,frequency)
|
||||
|
||||
frequency = 0
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/on_data_written()
|
||||
var/new_freq = get_pin_data(IC_INPUT, 1)
|
||||
var/new_code = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(new_freq) && new_freq > 0)
|
||||
set_frequency(new_freq)
|
||||
if(isnum(new_code))
|
||||
code = new_code
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/do_work() // Sends a signal.
|
||||
if(!radio_connection)
|
||||
return
|
||||
|
||||
var/datum/signal/signal = new
|
||||
signal.source = src
|
||||
signal.encryption = code
|
||||
signal.data["message"] = "ACTIVATE"
|
||||
radio_connection.post_signal(src, signal)
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency)
|
||||
if(!frequency)
|
||||
return
|
||||
if(!SSradio)
|
||||
sleep(20)
|
||||
if(!SSradio)
|
||||
return
|
||||
SSradio.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_CHAT)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal)
|
||||
var/new_code = get_pin_data(IC_INPUT, 2)
|
||||
var/code = 0
|
||||
|
||||
if(isnum(new_code))
|
||||
code = new_code
|
||||
if(!signal)
|
||||
return 0
|
||||
if(signal.encryption != code)
|
||||
return 0
|
||||
if(signal.source == src) // Don't trigger ourselves.
|
||||
return 0
|
||||
|
||||
activate_pin(3)
|
||||
|
||||
for(var/mob/O in hearers(1, get_turf(src)))
|
||||
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 1)
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2
|
||||
name = "EPv2 circuit"
|
||||
desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol."
|
||||
extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be send or received using the \
|
||||
second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activation pin \
|
||||
will pulse whatever's connected to it. Pulsing the first activation pin will send a message."
|
||||
icon_state = "signal"
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"target EPv2 address" = IC_PINTYPE_STRING,
|
||||
"data to send" = IC_PINTYPE_STRING,
|
||||
"secondary text" = IC_PINTYPE_STRING
|
||||
)
|
||||
outputs = list(
|
||||
"address received" = IC_PINTYPE_STRING,
|
||||
"data received" = IC_PINTYPE_STRING,
|
||||
"secondary text received" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2)
|
||||
power_draw_per_use = 50
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/New()
|
||||
..()
|
||||
exonet = new(src)
|
||||
exonet.make_address("EPv2_circuit-[REF(src)]")
|
||||
desc += "<br>This circuit's EPv2 address is: [exonet.address]"
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/Destroy()
|
||||
if(exonet)
|
||||
exonet.remove_address()
|
||||
qdel(exonet)
|
||||
exonet = null
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/do_work()
|
||||
var/target_address = get_pin_data(IC_INPUT, 1)
|
||||
var/message = get_pin_data(IC_INPUT, 2)
|
||||
var/text = get_pin_data(IC_INPUT, 3)
|
||||
|
||||
if(target_address && istext(target_address))
|
||||
exonet.send_message(target_address, message, text)
|
||||
|
||||
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
set_pin_data(IC_OUTPUT, 1, origin_address)
|
||||
set_pin_data(IC_OUTPUT, 2, message)
|
||||
set_pin_data(IC_OUTPUT, 3, text)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
//This circuit gives information on where the machine is.
|
||||
/obj/item/integrated_circuit/input/gps
|
||||
name = "global positioning system"
|
||||
desc = "This allows you to easily know the position of a machine containing this device."
|
||||
extended_desc = "The GPS's coordinates it gives is absolute, not relative."
|
||||
icon_state = "gps"
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("X"= IC_PINTYPE_NUMBER, "Y" = IC_PINTYPE_NUMBER, "Z" = IC_PINTYPE_NUMBER)
|
||||
activators = list("get coordinates" = IC_PINTYPE_PULSE_IN, "on get coordinates" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
|
||||
/obj/item/integrated_circuit/input/gps/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
if(!T)
|
||||
return
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, T.x)
|
||||
set_pin_data(IC_OUTPUT, 2, T.y)
|
||||
set_pin_data(IC_OUTPUT, 3, T.z)
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone
|
||||
name = "microphone"
|
||||
desc = "Useful for spying on people or for voice activated machines."
|
||||
extended_desc = "This will automatically translate most languages it hears to Galactic Common. \
|
||||
The first activation pin is always pulsed when the circuit hears someone talk, while the second one \
|
||||
is only triggered if it hears someone speaking a language other than Galactic Common."
|
||||
icon_state = "recorder"
|
||||
complexity = 8
|
||||
inputs = list()
|
||||
flags_1 = CONDUCT_1 | HEAR_1
|
||||
outputs = list(
|
||||
"speaker" = IC_PINTYPE_STRING,
|
||||
"message" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list("on message received" = IC_PINTYPE_PULSE_OUT, "on translation" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 5
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
|
||||
var/translated = FALSE
|
||||
if(speaker && message)
|
||||
if(raw_message)
|
||||
if(message_langs != get_default_language())
|
||||
translated = TRUE
|
||||
set_pin_data(IC_OUTPUT, 1, speaker.GetVoice())
|
||||
set_pin_data(IC_OUTPUT, 2, raw_message)
|
||||
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
if(translated)
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor
|
||||
name = "sensor"
|
||||
desc = "Scans and obtains a reference for any objects or persons near you. All you need to do is shove the machine in their face."
|
||||
extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
|
||||
icon_state = "recorder"
|
||||
complexity = 12
|
||||
inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
|
||||
var/ignore_bags = get_pin_data(IC_INPUT, 1)
|
||||
if(ignore_bags)
|
||||
if(istype(A, /obj/item/storage))
|
||||
return FALSE
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/ranged
|
||||
name = "Ranged sensor"
|
||||
desc = "Scans and obtains a reference for any objects or persons in range. All you need to do is point the machine towards target."
|
||||
extended_desc = "If 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
|
||||
icon_state = "recorder"
|
||||
complexity = 36
|
||||
inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm
|
||||
name = "internal battery monitor"
|
||||
desc = "This monitors the charge level of an internal battery."
|
||||
icon_state = "internalbm"
|
||||
extended_desc = "This circuit will give you values of charge, max charge and percentage of the internal battery on demand."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 1
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"cell charge" = IC_PINTYPE_NUMBER,
|
||||
"max charge" = IC_PINTYPE_NUMBER,
|
||||
"percentage" = IC_PINTYPE_NUMBER,
|
||||
"refference to assembly" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
set_pin_data(IC_OUTPUT, 4, WEAKREF(assembly))
|
||||
if(assembly)
|
||||
if(assembly.battery)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, assembly.battery.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/externalbm
|
||||
name = "external battery monitor"
|
||||
desc = "This can help to watch battery state of any device in view"
|
||||
icon_state = "externalbm"
|
||||
extended_desc = "This circuit will give you values of charge, max charge and percentage of any device or battery in view"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 2
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"cell charge" = IC_PINTYPE_NUMBER,
|
||||
"max charge" = IC_PINTYPE_NUMBER,
|
||||
"percentage" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/externalbm/do_work()
|
||||
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
if(AM)
|
||||
var/obj/item/stock_parts/cell/cell = get_cell(AM)
|
||||
if(cell)
|
||||
var/turf/A = get_turf(src)
|
||||
if(AM in view(A))
|
||||
push_data()
|
||||
set_pin_data(IC_OUTPUT, 1, cell.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, cell.percent())
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
200
code/modules/integrated_electronics/subtypes/lists.dm
Normal file
200
code/modules/integrated_electronics/subtypes/lists.dm
Normal file
@@ -0,0 +1,200 @@
|
||||
//These circuits do things with lists, and use special list pins for stability.
|
||||
/obj/item/integrated_circuit/lists
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"input" = IC_PINTYPE_LIST
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_STRING)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Lists"
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/lists/pick
|
||||
name = "pick circuit"
|
||||
desc = "This circuit will randomly 'pick' an element from a list that is inputted."
|
||||
extended_desc = "Will output null if the list is empty. Input list is unmodified."
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/pick/do_work()
|
||||
var/result = null
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1) // List pins guarantee that there is a list inside, even if just an empty one.
|
||||
if(input_list.len)
|
||||
result = pick(input_list)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/lists/append
|
||||
name = "append circuit"
|
||||
desc = "This circuit will add an element to a list."
|
||||
extended_desc = "The new element will always be at the bottom of the list."
|
||||
inputs = list(
|
||||
"list to append" = IC_PINTYPE_LIST,
|
||||
"input" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"appended list" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/append/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/list/output_list = list()
|
||||
var/new_entry = get_pin_data(IC_INPUT, 2)
|
||||
output_list = input_list.Copy()
|
||||
output_list.Add(new_entry)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, output_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/search
|
||||
name = "search circuit"
|
||||
desc = "This circuit will give index of desired element in the list."
|
||||
extended_desc = "Search will start at 1 position and will return first matching position."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"item" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/search/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/item = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, input_list.Find(item))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/at
|
||||
name = "at circuit"
|
||||
desc = "This circuit will pick an element from a list by index."
|
||||
extended_desc = "If there is no element with such index, result will be null."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("item" = IC_PINTYPE_ANY)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/at/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/item = input_list[index]
|
||||
set_pin_data(IC_OUTPUT, 1, item)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/delete
|
||||
name = "delete circuit"
|
||||
desc = "This circuit will delete the element from a list by index."
|
||||
extended_desc = "If there is no element with such index, result list will be unchanged."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list(
|
||||
"item" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/delete/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/list/red_list = list()
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
for(var/j in 1 to input_list.len)
|
||||
var/I = input_list[j]
|
||||
if(j != index)
|
||||
red_list.Add(I)
|
||||
set_pin_data(IC_OUTPUT, 1, red_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/lists/write
|
||||
name = "write circuit"
|
||||
desc = "This circuit will write element in list with given index."
|
||||
extended_desc = "If there is no element with such index, it will give the same list, as before."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER,
|
||||
"item" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"redacted list" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/write/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/item = get_pin_data(IC_INPUT, 3)
|
||||
if(!islist(item)) //crh proof
|
||||
input_list[index] = item
|
||||
set_pin_data(IC_OUTPUT, 1, input_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
obj/item/integrated_circuit/lists/len
|
||||
name = "len circuit"
|
||||
desc = "This circuit will give lenght of the list."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
)
|
||||
outputs = list(
|
||||
"item" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/len/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
set_pin_data(IC_OUTPUT, 1, input_list.len)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/lists/jointext
|
||||
name = "join text circuit"
|
||||
desc = "This circuit will add all elements of a list into one string, seperated by a character."
|
||||
extended_desc = "Default settings will encode the entire list into a string."
|
||||
inputs = list(
|
||||
"list to join" = IC_PINTYPE_LIST,//
|
||||
"delimiter" = IC_PINTYPE_CHAR,
|
||||
"start" = IC_PINTYPE_NUMBER,
|
||||
"end" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
inputs_default = list(
|
||||
"2" = ",",
|
||||
"3" = 1,
|
||||
"4" = 0
|
||||
)
|
||||
outputs = list(
|
||||
"joined text" = IC_PINTYPE_STRING
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/lists/jointext/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/delimiter = get_pin_data(IC_INPUT, 2)
|
||||
var/start = get_pin_data(IC_INPUT, 3)
|
||||
var/end = get_pin_data(IC_INPUT, 4)
|
||||
|
||||
var/result = null
|
||||
|
||||
if(input_list.len && delimiter && !isnull(start) && !isnull(end))
|
||||
result = jointext(input_list, delimiter, start, end)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
221
code/modules/integrated_electronics/subtypes/logic.dm
Normal file
221
code/modules/integrated_electronics/subtypes/logic.dm
Normal file
@@ -0,0 +1,221 @@
|
||||
/obj/item/integrated_circuit/logic
|
||||
name = "logic gate"
|
||||
desc = "This tiny chip will decide for you!"
|
||||
extended_desc = "Logic circuits will treat a null, 0, and a \"\" string value as FALSE and anything else as TRUE."
|
||||
complexity = 3
|
||||
outputs = list("result")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN)
|
||||
category_text = "Logic"
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/logic/do_work()
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary
|
||||
inputs = list("A","B")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN, "on true result" = IC_PINTYPE_PULSE_OUT, "on false result" = IC_PINTYPE_PULSE_OUT)
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = do_compare(A, B) ? TRUE : FALSE
|
||||
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/proc/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary
|
||||
inputs = list("A")
|
||||
activators = list("compare" = IC_PINTYPE_PULSE_IN, "on compare" = IC_PINTYPE_PULSE_OUT)
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = do_check(A) ? TRUE : FALSE
|
||||
..()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/proc/do_check(var/datum/integrated_io/A)
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/equals
|
||||
name = "equal gate"
|
||||
desc = "This gate compares two values, and outputs the number one if both are the same."
|
||||
icon_state = "equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data == B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/jklatch
|
||||
name = "JK latch"
|
||||
desc = "This gate is synchronysed JK latch."
|
||||
icon_state = "jklatch"
|
||||
inputs = list("J","K")
|
||||
outputs = list("Q","!Q")
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/jklatch/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/Q = outputs[2]
|
||||
if(A.data)
|
||||
if(B.data)
|
||||
lstate=!lstate
|
||||
else
|
||||
lstate = TRUE
|
||||
else
|
||||
if(B.data)
|
||||
lstate=FALSE
|
||||
O.data = lstate ? TRUE : FALSE
|
||||
Q.data = !lstate ? TRUE : FALSE
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/rslatch
|
||||
name = "RS latch"
|
||||
desc = "This gate is synchronysed RS latch. If both R and S are true, state will not change."
|
||||
icon_state = "sr_nor"
|
||||
inputs = list("S","R")
|
||||
outputs = list("Q","!Q")
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/rslatch/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/Q = outputs[2]
|
||||
if(A.data)
|
||||
if(!B.data)
|
||||
lstate=TRUE
|
||||
else
|
||||
if(B.data)
|
||||
lstate=FALSE
|
||||
O.data = lstate ? TRUE : FALSE
|
||||
Q.data = !lstate ? TRUE : FALSE
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/gdlatch
|
||||
name = "gated D latch"
|
||||
desc = "This gate is synchronysed gated D latch."
|
||||
icon_state = "gated_d"
|
||||
inputs = list("D","E")
|
||||
outputs = list("Q","!Q")
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/gdlatch/do_work()
|
||||
pull_data()
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/B = inputs[2]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
var/datum/integrated_io/Q = outputs[2]
|
||||
if(B.data)
|
||||
if(A.data)
|
||||
lstate=TRUE
|
||||
else
|
||||
lstate=FALSE
|
||||
|
||||
O.data = lstate ? TRUE : FALSE
|
||||
Q.data = !lstate ? TRUE : FALSE
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/not_equals
|
||||
name = "not equal gate"
|
||||
desc = "This gate compares two values, and outputs the number one if both are different."
|
||||
icon_state = "not_equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/not_equals/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data != B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/and
|
||||
name = "and gate"
|
||||
desc = "This gate will output 'one' if both inputs evaluate to true."
|
||||
icon_state = "and"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/and/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data && B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/or
|
||||
name = "or gate"
|
||||
desc = "This gate will output 'one' if one of the inputs evaluate to true."
|
||||
icon_state = "or"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/or/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data || B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than
|
||||
name = "less than gate"
|
||||
desc = "This will output 'one' if the first input is less than the second input."
|
||||
icon_state = "less_than"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data < B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than_or_equal
|
||||
name = "less than or equal gate"
|
||||
desc = "This will output 'one' if the first input is less than, or equal to the second input."
|
||||
icon_state = "less_than_or_equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/less_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data <= B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than
|
||||
name = "greater than gate"
|
||||
desc = "This will output 'one' if the first input is greater than the second input."
|
||||
icon_state = "greater_than"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data > B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than_or_equal
|
||||
name = "greater_than or equal gate"
|
||||
desc = "This will output 'one' if the first input is greater than, or equal to the second input."
|
||||
icon_state = "greater_than_or_equal"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/greater_than_or_equal/do_compare(var/datum/integrated_io/A, var/datum/integrated_io/B)
|
||||
return A.data >= B.data
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/not
|
||||
name = "not gate"
|
||||
desc = "This gate inverts what's fed into it."
|
||||
icon_state = "not"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
activators = list("invert" = IC_PINTYPE_PULSE_IN, "on inverted" = IC_PINTYPE_PULSE_OUT)
|
||||
|
||||
/obj/item/integrated_circuit/logic/unary/not/do_check(var/datum/integrated_io/A)
|
||||
return !A.data
|
||||
443
code/modules/integrated_electronics/subtypes/manipulation.dm
Normal file
443
code/modules/integrated_electronics/subtypes/manipulation.dm
Normal file
@@ -0,0 +1,443 @@
|
||||
/obj/item/integrated_circuit/manipulation
|
||||
category_text = "Manipulation"
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing
|
||||
name = "weapon firing mechanism"
|
||||
desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it."
|
||||
extended_desc = "The firing mechanism can slot in any energy weapon. \
|
||||
The first and second inputs need to be numbers. They are coordinates for the gun to fire at, relative to the machine itself. \
|
||||
The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Mode is switch between\
|
||||
letal(TRUE) or stun(FALSE) modes.It uses internal battery of weapon."
|
||||
complexity = 20
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 3
|
||||
inputs = list(
|
||||
"target X rel" = IC_PINTYPE_NUMBER,
|
||||
"target Y rel" = IC_PINTYPE_NUMBER,
|
||||
"mode" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
outputs = list("reference to gun" = IC_PINTYPE_REF)
|
||||
activators = list(
|
||||
"fire" = IC_PINTYPE_PULSE_IN
|
||||
|
||||
)
|
||||
var/obj/item/gun/energy/installed_gun = null
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
power_draw_per_use = 0
|
||||
var/mode = FALSE
|
||||
|
||||
var/stun_projectile = null //stun mode projectile type
|
||||
var/stun_projectile_sound
|
||||
var/lethal_projectile = null //lethal mode projectile type
|
||||
var/lethal_projectile_sound
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy()
|
||||
qdel(installed_gun)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user)
|
||||
if(istype(O, /obj/item/gun/energy))
|
||||
var/obj/item/gun/gun = O
|
||||
if(installed_gun)
|
||||
to_chat(user, "<span class='warning'>There's already a weapon installed.</span>")
|
||||
return
|
||||
|
||||
user.transferItemToLoc(gun,src)
|
||||
installed_gun = gun
|
||||
var/list/gun_properties = gun.get_turret_properties()
|
||||
to_chat(user, "<span class='notice'>You slide \the [gun] into the firing mechanism.</span>")
|
||||
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
stun_projectile = gun_properties["stun_projectile"]
|
||||
stun_projectile_sound = gun_properties["stun_projectile_sound"]
|
||||
lethal_projectile = gun_properties["lethal_projectile"]
|
||||
lethal_projectile_sound = gun_properties["lethal_projectile_sound"]
|
||||
if(gun_properties["shot_delay"])
|
||||
cooldown_per_use = gun_properties["shot_delay"]*10
|
||||
if(cooldown_per_use<30)
|
||||
cooldown_per_use = 40
|
||||
if(gun_properties["reqpower"])
|
||||
power_draw_per_use = gun_properties["reqpower"]
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun))
|
||||
push_data()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user)
|
||||
if(installed_gun)
|
||||
installed_gun.forceMove(drop_location())
|
||||
to_chat(user, "<span class='notice'>You slide \the [installed_gun] out of the firing mechanism.</span>")
|
||||
size = initial(size)
|
||||
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
installed_gun = null
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(null))
|
||||
push_data()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There's no weapon to remove from the mechanism.</span>")
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/do_work()
|
||||
if(!installed_gun)
|
||||
return
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(installed_gun))
|
||||
push_data()
|
||||
var/datum/integrated_io/xo = inputs[1]
|
||||
var/datum/integrated_io/yo = inputs[2]
|
||||
var/datum/integrated_io/mode1 = inputs[3]
|
||||
|
||||
mode = mode1.data
|
||||
if(assembly)
|
||||
if(isnum(xo.data))
|
||||
xo.data = round(xo.data, 1)
|
||||
if(isnum(yo.data))
|
||||
yo.data = round(yo.data, 1)
|
||||
|
||||
var/turf/T = get_turf(assembly)
|
||||
var/target_x = Clamp(T.x + xo.data, 0, world.maxx)
|
||||
var/target_y = Clamp(T.y + yo.data, 0, world.maxy)
|
||||
|
||||
shootAt(locate(target_x, target_y, T.z))
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/proc/shootAt(turf/target)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
var/turf/U = target
|
||||
if(!istype(T) || !istype(U))
|
||||
return
|
||||
if(!installed_gun.cell)
|
||||
return
|
||||
if(!installed_gun.cell.charge)
|
||||
return
|
||||
var/obj/item/ammo_casing/energy/shot = installed_gun.ammo_type[mode?2:1]
|
||||
if(installed_gun.cell.charge < shot.e_cost)
|
||||
return
|
||||
if(!shot)
|
||||
return
|
||||
update_icon()
|
||||
var/obj/item/projectile/A
|
||||
if(!mode)
|
||||
A = new stun_projectile(T)
|
||||
playsound(loc, stun_projectile_sound, 75, 1)
|
||||
else
|
||||
A = new lethal_projectile(T)
|
||||
playsound(loc, lethal_projectile_sound, 75, 1)
|
||||
|
||||
|
||||
installed_gun.cell.use(shot.e_cost)
|
||||
//Shooting Code:
|
||||
A.preparePixelProjectile(target, src)
|
||||
A.fire()
|
||||
return A
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/locomotion
|
||||
name = "locomotion circuit"
|
||||
desc = "This allows a machine to move in a given direction."
|
||||
icon_state = "locomotion"
|
||||
extended_desc = "The circuit accepts a 'dir' number as a direction to move towards.<br>\
|
||||
Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \
|
||||
being held, or anchored in some way. It should be noted that the ability to move is dependant on the type of assembly that this circuit inhabits."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 20
|
||||
// size = 5
|
||||
inputs = list("direction" = IC_PINTYPE_DIR)
|
||||
outputs = list()
|
||||
activators = list("step towards dir" = IC_PINTYPE_PULSE_IN,"on step"=IC_PINTYPE_PULSE_OUT,"blocked"=IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 100
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/locomotion/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && assembly)
|
||||
if(assembly.anchored || !assembly.can_move())
|
||||
return
|
||||
if(assembly.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held.
|
||||
var/datum/integrated_io/wanted_dir = inputs[1]
|
||||
if(isnum(wanted_dir.data))
|
||||
if(step(assembly, wanted_dir.data))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade
|
||||
name = "grenade primer"
|
||||
desc = "This circuit comes with the ability to attach most types of grenades at prime them at will."
|
||||
extended_desc = "Time between priming and detonation is limited to between 1 to 12 seconds but is optional. \
|
||||
If unset, not a number, or a number less than 1 then the grenade's built-in timing will be used. \
|
||||
Beware: Once primed there is no aborting the process!"
|
||||
icon_state = "grenade"
|
||||
complexity = 30
|
||||
inputs = list("detonation time" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("prime grenade" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
var/obj/item/grenade/attached_grenade
|
||||
var/pre_attached_grenade_type
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/Initialize()
|
||||
. = ..()
|
||||
if(pre_attached_grenade_type)
|
||||
var/grenade = new pre_attached_grenade_type(src)
|
||||
attach_grenade(grenade)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/Destroy()
|
||||
if(attached_grenade && !attached_grenade.active)
|
||||
attached_grenade.forceMove(loc)
|
||||
detach_grenade()
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/grenade/G, var/mob/user)
|
||||
if(istype(G))
|
||||
if(attached_grenade)
|
||||
to_chat(user, "<span class='warning'>There is already a grenade attached!</span>")
|
||||
else if(user.transferItemToLoc(G,src))
|
||||
user.visible_message("<span class='warning'>\The [user] attaches \a [G] to \the [src]!</span>", "<span class='notice'>You attach \the [G] to \the [src].</span>")
|
||||
attach_grenade(G)
|
||||
G.forceMove(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/attack_self(var/mob/user)
|
||||
if(attached_grenade)
|
||||
user.visible_message("<span class='warning'>\The [user] removes \an [attached_grenade] from \the [src]!</span>", "<span class='notice'>You remove \the [attached_grenade] from \the [src].</span>")
|
||||
user.put_in_hands(attached_grenade)
|
||||
detach_grenade()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/do_work()
|
||||
if(attached_grenade && !attached_grenade.active)
|
||||
var/datum/integrated_io/detonation_time = inputs[1]
|
||||
var/dt
|
||||
if(isnum(detonation_time.data) && detonation_time.data > 0)
|
||||
dt = Clamp(detonation_time.data, 1, 12)*10
|
||||
else
|
||||
dt = 15
|
||||
addtimer(CALLBACK(attached_grenade, /obj/item/grenade.proc/prime), dt)
|
||||
var/atom/holder = loc
|
||||
message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]")
|
||||
|
||||
// These procs do not relocate the grenade, that's the callers responsibility
|
||||
/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/grenade/G)
|
||||
attached_grenade = G
|
||||
G.forceMove(src)
|
||||
desc += " \An [attached_grenade] is attached to it!"
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade()
|
||||
if(!attached_grenade)
|
||||
return
|
||||
attached_grenade.forceMove(drop_location())
|
||||
attached_grenade = null
|
||||
desc = initial(desc)
|
||||
/*
|
||||
/obj/item/integrated_circuit/manipulation/grenade/frag
|
||||
pre_attached_grenade_type = /obj/item/weapon/grenade/explosive
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 10)
|
||||
spawn_flags = null // Used for world initializing, see the #defines above.
|
||||
*/
|
||||
/obj/item/integrated_circuit/manipulation/shocker
|
||||
name = "shocker circuit"
|
||||
desc = "Used to shock adjacent creatures with electricity."
|
||||
icon_state = "shocker"
|
||||
extended_desc = "The circuit accepts a reference to creature,who needs to be shocked. It can shock target on adjacent tiles. \
|
||||
Severity determines hardness of shock and it's power consumption. It's given between 0 and 60."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"severity" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("shock" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 0
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/on_data_written()
|
||||
var/s = get_pin_data(IC_INPUT, 2)
|
||||
power_draw_per_use = Clamp(s,0,60)*1200/60
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
if(!istype(AM,/mob/living)) //Invalid input
|
||||
return
|
||||
var/mob/living/M = AM
|
||||
if(!M.Adjacent(T))
|
||||
return //Can't reach
|
||||
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(12, 1, src)
|
||||
s.start()
|
||||
var/stf=Clamp(get_pin_data(IC_INPUT, 2),0,60)
|
||||
M.Knockdown(stf)
|
||||
M.apply_effect(STUTTER, stf)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/plant_module
|
||||
name = "plant manipulation module"
|
||||
desc = "Used to uproot weeds or harvest plants in trays."
|
||||
icon_state = "plant_m"
|
||||
extended_desc = "The circuit accepts a reference to hydroponic tray. It work from adjacent tiles. \
|
||||
Mode(0- harvest, 1-uproot weeds, 2-uproot plant) determinies action."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out"=IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 50
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/plant_module/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/machinery/hydroponics/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/hydroponics)
|
||||
if(!istype(AM)) //Invalid input
|
||||
return
|
||||
var/mob/living/M = get_turf(AM)
|
||||
if(!M.Adjacent(T))
|
||||
return //Can't reach
|
||||
switch(get_pin_data(IC_INPUT, 2))
|
||||
if(0)
|
||||
if(AM.myseed)
|
||||
if(AM.harvest)
|
||||
AM.myseed.harvest()
|
||||
AM.harvest = 0
|
||||
AM.lastproduce = AM.age
|
||||
if(!AM.myseed.get_gene(/datum/plant_gene/trait/repeated_harvest))
|
||||
qdel(AM.myseed)
|
||||
AM.myseed = null
|
||||
AM.dead = 0
|
||||
AM.update_icon()
|
||||
if(1)
|
||||
AM.weedlevel = 0
|
||||
if(2)
|
||||
if(AM.myseed) //Could be that they're just using it as a de-weeder
|
||||
AM.age = 0
|
||||
AM.plant_health = 0
|
||||
if(AM.harvest)
|
||||
AM.harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it
|
||||
qdel(AM.myseed)
|
||||
AM.myseed = null
|
||||
AM.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds
|
||||
AM.update_icon()
|
||||
else
|
||||
activate_pin(2)
|
||||
return FALSE
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber
|
||||
name = "grabber"
|
||||
desc = "A circuit with it's own inventory for small/medium items, used to grab and store things."
|
||||
icon_state = "grabber"
|
||||
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 3
|
||||
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("first" = IC_PINTYPE_REF, "last" = IC_PINTYPE_REF, "amount" = IC_PINTYPE_NUMBER,"contents" = IC_PINTYPE_LIST)
|
||||
activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 50
|
||||
var/max_w_class = WEIGHT_CLASS_NORMAL
|
||||
var/max_items = 10
|
||||
/*
|
||||
/obj/item/integrated_circuit/manipulation/thrower/New()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/Destroy()
|
||||
processing_objects -= src
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/process()
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(contents[1]))
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(contents[contents.len]))
|
||||
set_pin_data(IC_OUTPUT, 3, contents.len)
|
||||
push_data()
|
||||
*/
|
||||
/obj/item/integrated_circuit/manipulation/grabber/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
|
||||
if(AM)
|
||||
var/turf/P = get_turf(AM)
|
||||
var/mode = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(mode == 1)
|
||||
if(P.Adjacent(T))
|
||||
if((contents.len < max_items) && AM && (AM.w_class <= max_w_class))
|
||||
AM.forceMove(src)
|
||||
if(mode == 0)
|
||||
if(contents.len)
|
||||
var/obj/item/U = contents[1]
|
||||
U.forceMove(T)
|
||||
if(mode == -1)
|
||||
if(contents.len)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
if(contents.len)
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(contents[1]))
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(contents[contents.len]))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, contents.len)
|
||||
set_pin_data(IC_OUTPUT, 4, contents)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/attack_self(var/mob/user)
|
||||
if(contents.len)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, contents.len)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower
|
||||
name = "thrower"
|
||||
desc = "A compact launcher to throw things from inside or nearby tiles"
|
||||
extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \
|
||||
The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \
|
||||
projectile need to be inside the machine, or to be on an adjacent tile, and to be up to medium size."
|
||||
complexity = 15
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 2
|
||||
inputs = list(
|
||||
"target X rel" = IC_PINTYPE_NUMBER,
|
||||
"target Y rel" = IC_PINTYPE_NUMBER,
|
||||
"projectile" = IC_PINTYPE_REF
|
||||
)
|
||||
outputs = list()
|
||||
activators = list(
|
||||
"fire" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
power_draw_per_use = 50
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/do_work()
|
||||
var/datum/integrated_io/target_x = inputs[1]
|
||||
var/datum/integrated_io/target_y = inputs[2]
|
||||
var/datum/integrated_io/projectile = inputs[3]
|
||||
if(!isweakref(projectile.data))
|
||||
return
|
||||
var/obj/item/A = projectile.data.resolve()
|
||||
if(A.anchored || (A.w_class > WEIGHT_CLASS_NORMAL))
|
||||
return
|
||||
var/turf/T = get_turf(assembly)
|
||||
if(!(A.Adjacent(T) || (A in assembly.GetAllContents())))
|
||||
return
|
||||
if(assembly)
|
||||
if(isnum(target_x.data))
|
||||
target_x.data = round(target_x.data, 1)
|
||||
if(isnum(target_y.data))
|
||||
target_y.data = round(target_y.data, 1)
|
||||
var/_x = Clamp(T.x + target_x.data, 0, world.maxx)
|
||||
var/_y = Clamp(T.y + target_y.data, 0, world.maxy)
|
||||
|
||||
A.forceMove(drop_location())
|
||||
A.throw_at(locate(_x, _y, T.z), round(Clamp(sqrt(target_x.data*target_x.data+target_y.data*target_y.data),0,8),1), 3)
|
||||
124
code/modules/integrated_electronics/subtypes/memory.dm
Normal file
124
code/modules/integrated_electronics/subtypes/memory.dm
Normal file
@@ -0,0 +1,124 @@
|
||||
/obj/item/integrated_circuit/memory
|
||||
name = "memory chip"
|
||||
desc = "This tiny chip can store one piece of data."
|
||||
icon_state = "memory"
|
||||
complexity = 1
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list("set" = IC_PINTYPE_PULSE_IN, "on set" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Memory"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 1
|
||||
var/number_of_pins = 1
|
||||
|
||||
/obj/item/integrated_circuit/memory/New()
|
||||
for(var/i = 1 to number_of_pins)
|
||||
inputs["input [i]"] = IC_PINTYPE_ANY // This is just a string since pins don't get built until ..() is called.
|
||||
outputs["output [i]"] = IC_PINTYPE_ANY
|
||||
complexity = number_of_pins
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/memory/examine(mob/user)
|
||||
..()
|
||||
var/i
|
||||
for(i = 1, i <= outputs.len, i++)
|
||||
var/datum/integrated_io/O = outputs[i]
|
||||
var/data = "nothing"
|
||||
if(isweakref(O.data))
|
||||
var/datum/d = O.data_as_type(/datum)
|
||||
if(d)
|
||||
data = "[d]"
|
||||
else if(!isnull(O.data))
|
||||
data = O.data
|
||||
to_chat(user, "\The [src] has [data] saved to address [i].")
|
||||
|
||||
/obj/item/integrated_circuit/memory/do_work()
|
||||
for(var/i = 1 to inputs.len)
|
||||
var/datum/integrated_io/I = inputs[i]
|
||||
var/datum/integrated_io/O = outputs[i]
|
||||
O.data = I.data
|
||||
O.push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/memory/tiny
|
||||
name = "small memory circuit"
|
||||
desc = "This circuit can store two pieces of data."
|
||||
icon_state = "memory4"
|
||||
power_draw_per_use = 2
|
||||
number_of_pins = 2
|
||||
|
||||
/obj/item/integrated_circuit/memory/medium
|
||||
name = "medium memory circuit"
|
||||
desc = "This circuit can store four pieces of data."
|
||||
icon_state = "memory4"
|
||||
power_draw_per_use = 2
|
||||
number_of_pins = 4
|
||||
|
||||
/obj/item/integrated_circuit/memory/large
|
||||
name = "large memory circuit"
|
||||
desc = "This big circuit can hold eight pieces of data."
|
||||
icon_state = "memory8"
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
power_draw_per_use = 4
|
||||
number_of_pins = 8
|
||||
|
||||
/obj/item/integrated_circuit/memory/huge
|
||||
name = "large memory stick"
|
||||
desc = "This stick of memory can hold up up to sixteen pieces of data."
|
||||
icon_state = "memory16"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4)
|
||||
power_draw_per_use = 8
|
||||
number_of_pins = 16
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant
|
||||
name = "constant chip"
|
||||
desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly."
|
||||
icon_state = "memory"
|
||||
inputs = list()
|
||||
outputs = list("output pin" = IC_PINTYPE_ANY)
|
||||
activators = list("push data" = IC_PINTYPE_PULSE_IN)
|
||||
var/accepting_refs = FALSE
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/do_work()
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/attack_self(mob/user)
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null")
|
||||
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data) && user.IsAdvancedToolUser())
|
||||
O.data = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [O.display_data(O.data)].</span>")
|
||||
if("number")
|
||||
accepting_refs = FALSE
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data) && user.IsAdvancedToolUser())
|
||||
O.data = new_data
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to [O.display_data(O.data)].</span>")
|
||||
if("ref")
|
||||
accepting_refs = TRUE
|
||||
to_chat(user, "<span class='notice'>You turn \the [src]'s ref scanner on. Slide it across \
|
||||
an object for a ref of that object to save it in memory.</span>")
|
||||
if("null")
|
||||
O.data = null
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to absolutely nothing.</span>")
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity)
|
||||
if(accepting_refs && proximity)
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = WEAKREF(target)
|
||||
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
|
||||
to_chat(user, "<span class='notice'>You set \the [src]'s memory to a reference to [O.display_data(O.data)]. The ref scanner is \
|
||||
now off.</span>")
|
||||
accepting_refs = FALSE
|
||||
359
code/modules/integrated_electronics/subtypes/output.dm
Normal file
359
code/modules/integrated_electronics/subtypes/output.dm
Normal file
@@ -0,0 +1,359 @@
|
||||
/obj/item/integrated_circuit/output
|
||||
category_text = "Output"
|
||||
|
||||
/obj/item/integrated_circuit/output/screen
|
||||
name = "small screen"
|
||||
desc = "This small screen can display a single piece of data, when the machine is examined closely."
|
||||
icon_state = "screen"
|
||||
inputs = list("displayed data" = IC_PINTYPE_ANY)
|
||||
outputs = list()
|
||||
activators = list("load data" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 10
|
||||
var/stuff_to_display = null
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/disconnect_all()
|
||||
..()
|
||||
stuff_to_display = null
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/any_examine(mob/user)
|
||||
to_chat(user, "There is a little screen labeled '[name]', which displays [!isnull(stuff_to_display) ? "'[stuff_to_display]'" : "nothing"].")
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
if(isweakref(I.data))
|
||||
var/datum/d = I.data_as_type(/datum)
|
||||
if(d)
|
||||
stuff_to_display = "[d]"
|
||||
else
|
||||
stuff_to_display = I.data
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/medium
|
||||
name = "screen"
|
||||
desc = "This screen allows for people holding the device to see a piece of data."
|
||||
icon_state = "screen_medium"
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/medium/do_work()
|
||||
..()
|
||||
var/list/nearby_things = range(0, get_turf(src))
|
||||
for(var/mob/M in nearby_things)
|
||||
var/obj/O = assembly ? assembly : src
|
||||
to_chat(M, "<span class='notice'>[icon2html(O.icon, world, O.icon_state)] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/large
|
||||
name = "large screen"
|
||||
desc = "This screen allows for people able to see the device to see a piece of data."
|
||||
icon_state = "screen_large"
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/large/do_work()
|
||||
..()
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
O.visible_message("<span class='notice'>[icon2html(O.icon, world, O.icon_state)] [stuff_to_display]</span>")
|
||||
|
||||
/obj/item/integrated_circuit/output/light
|
||||
name = "light"
|
||||
desc = "This light can turn on and off on command."
|
||||
icon_state = "light"
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
activators = list("toggle light" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/light_toggled = 0
|
||||
var/light_brightness = 3
|
||||
var/light_rgb = "#FFFFFF"
|
||||
power_draw_idle = 0 // Adjusted based on brightness.
|
||||
|
||||
/obj/item/integrated_circuit/output/light/do_work()
|
||||
light_toggled = !light_toggled
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/proc/update_lighting()
|
||||
if(light_toggled)
|
||||
if(assembly)
|
||||
assembly.set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb)
|
||||
else
|
||||
if(assembly)
|
||||
assembly.set_light(0)
|
||||
power_draw_idle = light_toggled ? light_brightness * 2 : 0
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced/update_lighting()
|
||||
var/new_color = get_pin_data(IC_INPUT, 1)
|
||||
var/brightness = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(new_color && isnum(brightness))
|
||||
brightness = Clamp(brightness, 0, 6)
|
||||
light_rgb = new_color
|
||||
light_brightness = brightness
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left.
|
||||
light_toggled = FALSE
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced
|
||||
name = "advanced light"
|
||||
desc = "This light can turn on and off on command, in any color, and in various brightness levels."
|
||||
icon_state = "light_adv"
|
||||
complexity = 8
|
||||
inputs = list(
|
||||
"color" = IC_PINTYPE_COLOR,
|
||||
"brightness" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced/on_data_written()
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/sound
|
||||
name = "speaker circuit"
|
||||
desc = "A miniature speaker is attached to this component."
|
||||
icon_state = "speaker"
|
||||
complexity = 8
|
||||
cooldown_per_use = 4 SECONDS
|
||||
inputs = list(
|
||||
"sound ID" = IC_PINTYPE_STRING,
|
||||
"volume" = IC_PINTYPE_NUMBER,
|
||||
"frequency" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
outputs = list()
|
||||
activators = list("play sound" = IC_PINTYPE_PULSE_IN)
|
||||
power_draw_per_use = 10
|
||||
var/list/sounds = list()
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech
|
||||
name = "text-to-speech circuit"
|
||||
desc = "A miniature speaker is attached to this component."
|
||||
extended_desc = "This unit is more advanced than the plain speaker circuit, able to transpose any valid text to speech."
|
||||
icon_state = "speaker"
|
||||
complexity = 12
|
||||
inputs = list("text" = IC_PINTYPE_STRING)
|
||||
outputs = list()
|
||||
activators = list("to speech" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 60
|
||||
|
||||
/obj/item/integrated_circuit/output/text_to_speech/do_work()
|
||||
text = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(text))
|
||||
var/obj/O = assembly ? loc : assembly
|
||||
O.say(strip_html_simple(text))
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/Initialize()
|
||||
.= ..()
|
||||
extended_desc = list()
|
||||
extended_desc += "The first input pin determines which sound is used. The choices are; "
|
||||
extended_desc += jointext(sounds, ", ")
|
||||
extended_desc += ". The second pin determines the volume of sound that is played"
|
||||
extended_desc += ", and the third determines if the frequency of the sound will vary with each activation."
|
||||
extended_desc = jointext(extended_desc, null)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/do_work()
|
||||
var/ID = get_pin_data(IC_INPUT, 1)
|
||||
var/vol = get_pin_data(IC_INPUT, 2)
|
||||
var/freq = get_pin_data(IC_INPUT, 3)
|
||||
if(!isnull(ID) && !isnull(vol))
|
||||
var/selected_sound = sounds[ID]
|
||||
if(!selected_sound)
|
||||
return
|
||||
vol = Clamp(vol ,0 , 100)
|
||||
playsound(get_turf(src), selected_sound, vol, freq, -1)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/on_data_written()
|
||||
power_draw_per_use = get_pin_data(IC_INPUT, 2) * 15
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/beeper
|
||||
name = "beeper circuit"
|
||||
desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \
|
||||
the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \
|
||||
as buzzing, pinging, chiming, and more."
|
||||
sounds = list(
|
||||
"beep" = 'sound/machines/twobeep.ogg',
|
||||
"chime" = 'sound/machines/chime.ogg',
|
||||
"buzz sigh" = 'sound/machines/buzz-sigh.ogg',
|
||||
"buzz twice" = 'sound/machines/buzz-two.ogg',
|
||||
"ping" = 'sound/machines/ping.ogg',
|
||||
"synth yes" = 'sound/machines/synth_yes.ogg',
|
||||
"synth no" = 'sound/machines/synth_no.ogg',
|
||||
"warning buzz" = 'sound/machines/warning-buzzer.ogg'
|
||||
)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/beepsky
|
||||
name = "securitron sound circuit"
|
||||
desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron."
|
||||
sounds = list(
|
||||
"creep" = 'sound/voice/bcreep.ogg',
|
||||
"criminal" = 'sound/voice/bcriminal.ogg',
|
||||
"freeze" = 'sound/voice/bfreeze.ogg',
|
||||
"god" = 'sound/voice/bgod.ogg',
|
||||
"i am the law" = 'sound/voice/biamthelaw.ogg',
|
||||
"insult" = 'sound/voice/binsult.ogg',
|
||||
"radio" = 'sound/voice/bradio.ogg',
|
||||
"secure day" = 'sound/voice/bsecureday.ogg',
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/medbot
|
||||
name = "medbot sound circuit"
|
||||
desc = "A miniature speaker is attached to this component, used to annoy patients while they get pricked by a medbot."
|
||||
sounds = list(
|
||||
"surgeon" = 'sound/voice/msurgeon.ogg',
|
||||
"radar" = 'sound/voice/mradar.ogg',
|
||||
"feel better" = 'sound/voice/mfeelbetter.ogg',
|
||||
"patched up" = 'sound/voice/mpatchedup.ogg',
|
||||
"injured" = 'sound/voice/minjured.ogg',
|
||||
"insult" = 'sound/voice/minsult.ogg',
|
||||
"coming" = 'sound/voice/mcoming.ogg',
|
||||
"help" = 'sound/voice/mhelp.ogg',
|
||||
"live" = 'sound/voice/mlive.ogg',
|
||||
"lost" = 'sound/voice/mlost.ogg',
|
||||
"flies" = 'sound/voice/mflies.ogg',
|
||||
"catch" = 'sound/voice/mcatch.ogg',
|
||||
"delicious" = 'sound/voice/mdelicious.ogg',
|
||||
"apple" = 'sound/voice/mapple.ogg',
|
||||
"no" = 'sound/voice/mno.ogg',
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 1)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera
|
||||
name = "video camera circuit"
|
||||
desc = "This small camera allows a remote viewer to see what it sees."
|
||||
extended_desc = "The camera is linked to the Research camera network."
|
||||
icon_state = "video_camera"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 10
|
||||
inputs = list(
|
||||
"camera name" = IC_PINTYPE_STRING,
|
||||
"camera active" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
inputs_default = list("1" = "video camera circuit")
|
||||
outputs = list()
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_idle = 0 // Raises to 20 when on.
|
||||
var/obj/machinery/camera/camera
|
||||
var/updating = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/New()
|
||||
..()
|
||||
camera = new(src)
|
||||
camera.network = list("RD")
|
||||
on_data_written()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/Destroy()
|
||||
QDEL_NULL(camera)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/set_camera_status(var/status)
|
||||
if(camera)
|
||||
camera.status = status
|
||||
GLOB.cameranet.updatePortableCamera(camera)
|
||||
power_draw_idle = camera.status ? 20 : 0
|
||||
if(camera.status) // Ensure that there's actually power.
|
||||
if(!draw_idle_power())
|
||||
power_fail()
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/on_data_written()
|
||||
if(camera)
|
||||
var/cam_name = get_pin_data(IC_INPUT, 1)
|
||||
var/cam_active = get_pin_data(IC_INPUT, 2)
|
||||
if(!isnull(cam_name))
|
||||
camera.c_tag = cam_name
|
||||
set_camera_status(cam_active)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/power_fail()
|
||||
if(camera)
|
||||
set_camera_status(0)
|
||||
set_pin_data(IC_INPUT, 2, FALSE)
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/ext_moved(oldLoc, dir)
|
||||
. = ..()
|
||||
update_camera_location(oldLoc)
|
||||
|
||||
#define VIDEO_CAMERA_BUFFER 10
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/update_camera_location(oldLoc)
|
||||
oldLoc = get_turf(oldLoc)
|
||||
if(!QDELETED(camera) && !updating && oldLoc != get_turf(src))
|
||||
updating = TRUE
|
||||
addtimer(CALLBACK(src, .proc/do_camera_update, oldLoc), VIDEO_CAMERA_BUFFER)
|
||||
#undef VIDEO_CAMERA_BUFFER
|
||||
|
||||
/obj/item/integrated_circuit/output/video_camera/proc/do_camera_update(oldLoc)
|
||||
if(!QDELETED(camera) && oldLoc != get_turf(src))
|
||||
GLOB.cameranet.updatePortableCamera(camera)
|
||||
updating = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/output/led
|
||||
name = "light-emitting diode"
|
||||
desc = "This a LED that is lit whenever there is TRUE-equivalent data on its input."
|
||||
extended_desc = "TRUE-equivalent values are: Non-empty strings, non-zero numbers, and valid refs."
|
||||
complexity = 0.1
|
||||
icon_state = "led"
|
||||
inputs = list("lit" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list()
|
||||
activators = list()
|
||||
power_draw_idle = 0 // Raises to 1 when lit.
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/led_color
|
||||
|
||||
/obj/item/integrated_circuit/output/led/on_data_written()
|
||||
power_draw_idle = get_pin_data(IC_INPUT, 1) ? 1 : 0
|
||||
|
||||
/obj/item/integrated_circuit/output/led/power_fail()
|
||||
set_pin_data(IC_INPUT, 1, FALSE)
|
||||
|
||||
/obj/item/integrated_circuit/output/led/external_examine(mob/user)
|
||||
var/text_output = list()
|
||||
|
||||
// Doing all this work just to have a color-blind friendly output.
|
||||
text_output += "There is "
|
||||
if(name == displayed_name )
|
||||
text_output += "\an [name]"
|
||||
else
|
||||
text_output += "\an ["\improper[name]"] labeled '[displayed_name ]'"
|
||||
text_output += " which is currently [(get_pin_data(IC_INPUT, 1)==1) ? "lit <font color=[led_color]>*</font>" : "unlit."]"
|
||||
to_chat(user,jointext(text_output,null))
|
||||
|
||||
/obj/item/integrated_circuit/output/led/red
|
||||
name = "red LED"
|
||||
led_color = "#FF0000"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/orange
|
||||
name = "orange LED"
|
||||
led_color = "#FF9900"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/yellow
|
||||
name = "yellow LED"
|
||||
led_color = "#FFFF00"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/green
|
||||
name = "green LED"
|
||||
led_color = "#008000"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/blue
|
||||
name = "blue LED"
|
||||
led_color = "#0000FF"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/purple
|
||||
name = "purple LED"
|
||||
led_color = "#800080"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/cyan
|
||||
name = "cyan LED"
|
||||
led_color = "#00FFFF"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/white
|
||||
name = "white LED"
|
||||
led_color = "#FFFFFF"
|
||||
|
||||
/obj/item/integrated_circuit/output/led/pink
|
||||
name = "pink LED"
|
||||
led_color = "#FF00FF"
|
||||
81
code/modules/integrated_electronics/subtypes/power.dm
Normal file
81
code/modules/integrated_electronics/subtypes/power.dm
Normal file
@@ -0,0 +1,81 @@
|
||||
/obj/item/integrated_circuit/power/
|
||||
category_text = "Power - Active"
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter
|
||||
name = "power transmission circuit"
|
||||
desc = "This can wirelessly transmit electricity from an assembly's battery towards a nearby machine."
|
||||
icon_state = "power_transmitter"
|
||||
extended_desc = "This circuit transmits 5 kJ of electricity every time the activator pin is pulsed. The input pin must be \
|
||||
a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \
|
||||
inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \
|
||||
some power is lost due to ineffiency."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
complexity = 16
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"target cell charge" = IC_PINTYPE_NUMBER,
|
||||
"target cell max charge" = IC_PINTYPE_NUMBER,
|
||||
"target cell percentage" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("transmit" = IC_PINTYPE_PULSE_IN, "on transmit" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 500 // Inefficency has to come from somewhere.
|
||||
var/amount_to_move = 5000
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/large
|
||||
name = "large power transmission circuit"
|
||||
desc = "This can wirelessly transmit a lot of electricity from an assembly's battery towards a nearby machine. Warning: Do not operate in flammable enviroments."
|
||||
extended_desc = "This circuit transmits 20 kJ of electricity every time the activator pin is pulsed. The input pin must be \
|
||||
a reference to a machine to send electricity to. This can be a battery, or anything containing a battery. The machine can exist \
|
||||
inside the assembly, or adjacent to it. The power is sourced from the assembly's power cell. If the target is outside of the assembly, \
|
||||
some power is lost due to ineffiency."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
complexity = 32
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 6, TECH_MAGNET = 5)
|
||||
power_draw_per_use = 2000
|
||||
amount_to_move = 20000
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/do_work()
|
||||
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
if(AM)
|
||||
if(!assembly)
|
||||
return FALSE // Pointless to do everything else if there's no battery to draw from.
|
||||
|
||||
var/obj/item/stock_parts/cell/cell = AM.get_cell()
|
||||
if(cell)
|
||||
var/transfer_amount = amount_to_move
|
||||
var/turf/A = get_turf(src)
|
||||
var/turf/B = get_turf(AM)
|
||||
if(A.Adjacent(B))
|
||||
if(AM.loc != assembly)
|
||||
transfer_amount *= 0.8 // Losses due to distance.
|
||||
|
||||
if(cell.charge == cell.maxcharge)
|
||||
return FALSE
|
||||
|
||||
if(transfer_amount && assembly.draw_power(amount_to_move)) // CELLRATE is already handled in draw_power()
|
||||
cell.give(transfer_amount * GLOB.CELLRATE)
|
||||
set_pin_data(IC_OUTPUT, 1, cell.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, cell.percent())
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
return TRUE
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/obj/item/integrated_circuit/power/transmitter/large/do_work()
|
||||
if(..()) // If the above code succeeds, do this below.
|
||||
if(prob(20))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(12, 1, src)
|
||||
s.start()
|
||||
visible_message("<span class='warning'>\The [assembly] makes some sparks!</span>")
|
||||
365
code/modules/integrated_electronics/subtypes/reagents.dm
Normal file
365
code/modules/integrated_electronics/subtypes/reagents.dm
Normal file
@@ -0,0 +1,365 @@
|
||||
/obj/item/integrated_circuit/reagent
|
||||
category_text = "Reagent"
|
||||
var/volume = 0
|
||||
resistance_flags = UNACIDABLE | FIRE_PROOF
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/New()
|
||||
..()
|
||||
if(volume)
|
||||
create_reagents(volume)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke
|
||||
name = "smoke generator"
|
||||
desc = "Unlike most electronics, creating smoke is completely intentional."
|
||||
icon_state = "smoke"
|
||||
extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \
|
||||
into the smoke clouds when activated. The reagents are consumed when smoke is made."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 20
|
||||
cooldown_per_use = 1 SECONDS
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list("create smoke" = IC_PINTYPE_PULSE_IN,"on smoked" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3)
|
||||
volume = 100
|
||||
power_draw_per_use = 20
|
||||
var/smoke_radius = 5
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/do_work()
|
||||
var/location = get_turf(src)
|
||||
var/datum/effect_system/smoke_spread/chem/S = new
|
||||
S.attach(location)
|
||||
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
if(S)
|
||||
S.set_up(reagents, smoke_radius, location, 0)
|
||||
S.start()
|
||||
if(reagents)
|
||||
reagents.clear_reagents()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector
|
||||
name = "integrated hypo-injector"
|
||||
desc = "This scary looking thing is able to pump liquids into whatever it's pointed at."
|
||||
icon_state = "injector"
|
||||
extended_desc = "This autoinjector can push reagents into another container or someone else outside of the machine. The target \
|
||||
must be adjacent to the machine, and if it is a person, they cannot be wearing thick clothing. Negative given amount makes injector suck out reagents."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 20
|
||||
cooldown_per_use = 6 SECONDS
|
||||
inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
|
||||
inputs_default = list("2" = 5)
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
volume = 30
|
||||
power_draw_per_use = 15
|
||||
var/direction_mode = SYRINGE_INJECT
|
||||
var/transfer_amount = 10
|
||||
var/busy = FALSE
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 2)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direction_mode = SYRINGE_DRAW
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, volume)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/proc/inject_tray(var/obj/machinery/hydroponics/H,var/atom/movable/SO,var/A)
|
||||
var/datum/reagents/S = new /datum/reagents() //This is a strange way, but I don't know of a better one so I can't fix it at the moment...
|
||||
S.my_atom = H
|
||||
SO.reagents.trans_to(S,A)
|
||||
H.applyChemicals(S)
|
||||
S.clear_reagents()
|
||||
qdel(S)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/do_work()
|
||||
set waitfor = FALSE // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
if(!istype(AM)||!Adjacent(AM)||busy)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(istype(AM,/obj/machinery/hydroponics)&&(direction_mode==SYRINGE_INJECT)&&(reagents.total_volume))//injection into tray.
|
||||
inject_tray(AM,src,transfer_amount)
|
||||
activate_pin(2)
|
||||
return
|
||||
if(!AM.reagents)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(direction_mode == SYRINGE_INJECT)
|
||||
if(!reagents.total_volume) // Empty
|
||||
activate_pin(3)
|
||||
return
|
||||
if(AM.is_injectable())
|
||||
if(AM.reagents.total_volume>=AM.reagents.maximum_volume)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(!L.can_inject(null, 0))
|
||||
activate_pin(3)
|
||||
return
|
||||
//Always log attemped injections for admins
|
||||
var/list/rinject = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
rinject += R.name
|
||||
var/contained = english_list(rinject)
|
||||
add_logs(src, L, "attemped to inject", addition="which had [contained]") //TODO: proper logging (maybe last touched and assembled)
|
||||
L.visible_message("<span class='danger'>[src] is trying to inject [L]!</span>", \
|
||||
"<span class='userdanger'>[src] is trying to inject you!</span>")
|
||||
busy = TRUE
|
||||
if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0)))
|
||||
var/fraction = min(transfer_amount/reagents.total_volume, 1)
|
||||
reagents.reaction(L, INJECT, fraction)
|
||||
reagents.trans_to(L, transfer_amount)
|
||||
L.visible_message("<span class='danger'>[src] injects [L] with it's needle!</span>", \
|
||||
"<span class='userdanger'>[src] injects you with it's needle!</span>")
|
||||
else
|
||||
busy = FALSE
|
||||
activate_pin(3)
|
||||
return
|
||||
busy = FALSE
|
||||
else
|
||||
reagents.trans_to(AM, transfer_amount)
|
||||
else
|
||||
activate_pin(3)
|
||||
return
|
||||
else
|
||||
if(reagents.total_volume >= reagents.maximum_volume) // Full
|
||||
activate_pin(3)
|
||||
return
|
||||
var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
L.visible_message("<span class='danger'>[src] is trying to take a blood sample from [L]!</span>", \
|
||||
"<span class='userdanger'>[src] is trying to take a blood sample from you!</span>")
|
||||
busy = TRUE
|
||||
if(do_atom(src, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject,null,0)))
|
||||
if(L.transfer_blood_to(src, tramount))
|
||||
L.visible_message("[src] takes a blood sample from [L].")
|
||||
else
|
||||
busy = FALSE
|
||||
activate_pin(3)
|
||||
return
|
||||
busy = FALSE
|
||||
else
|
||||
if(!AM.reagents.total_volume || !AM.is_drawable())
|
||||
activate_pin(3)
|
||||
return
|
||||
AM.reagents.trans_to(src, tramount)
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump
|
||||
name = "reagent pump"
|
||||
desc = "Moves liquids safely inside a machine, or even nearby it."
|
||||
icon_state = "reagent_pump"
|
||||
extended_desc = "This is a pump, which will move liquids from the source ref to the target ref. The third pin determines \
|
||||
how much liquid is moved per pulse, between 0 and 50. The pump can move reagents to any open container inside the machine, or \
|
||||
outside the machine if it is next to the machine. Note that this cannot be used on entities."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
|
||||
inputs_default = list("3" = 5)
|
||||
outputs = list()
|
||||
activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
var/direction_mode = SYRINGE_INJECT
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 3)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direction_mode = SYRINGE_DRAW
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/do_work()
|
||||
var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
|
||||
|
||||
if(!istype(source) || !istype(target) || !source.reagents) //Invalid input
|
||||
return
|
||||
if(Adjacent(source) && Adjacent(target))
|
||||
if(istype(target,/obj/machinery/hydroponics)&&(source.reagents.total_volume))//injection into tray.
|
||||
inject_tray(target,source,transfer_amount)
|
||||
activate_pin(2)
|
||||
return
|
||||
|
||||
if(!target.reagents)
|
||||
return
|
||||
if(ismob(source) || ismob(target))
|
||||
return
|
||||
if(!source.is_open_container() || !target.is_open_container())
|
||||
return
|
||||
if(direction_mode)
|
||||
if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) //full
|
||||
return
|
||||
source.reagents.trans_to(target, transfer_amount)
|
||||
else
|
||||
if(source.reagents.maximum_volume - source.reagents.total_volume <= 0)
|
||||
return
|
||||
target.reagents.trans_to(source, transfer_amount)
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage
|
||||
name = "reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u."
|
||||
icon_state = "reagent_storage"
|
||||
extended_desc = "This is effectively an internal beaker."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
volume = 60
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, WEAKREF(src))
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/cryo
|
||||
name = "cryo reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions."
|
||||
icon_state = "reagent_storage_cryo"
|
||||
extended_desc = "This is effectively an internal cryo beaker."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 4, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/cryo/New()
|
||||
. = ..()
|
||||
reagents.set_reacting(FALSE)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/big
|
||||
name = "big reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
|
||||
icon_state = "reagent_storage_big"
|
||||
extended_desc = "This is effectively an internal beaker."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 16
|
||||
volume = 180
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan
|
||||
name = "reagent scanner"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents."
|
||||
icon_state = "reagent_scan"
|
||||
extended_desc = "Mostly useful for reagent filter."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"list of reagents" = IC_PINTYPE_LIST)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan/do_work()
|
||||
var/cont[0]
|
||||
for(var/datum/reagent/RE in reagents.reagent_list)
|
||||
cont += RE.id
|
||||
set_pin_data(IC_OUTPUT, 3, cont)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter
|
||||
name = "reagent filter"
|
||||
desc = "Filtering liquids by list of desired or unwanted reagents."
|
||||
icon_state = "reagent_filter"
|
||||
extended_desc = "This is a filter, which will move liquids from the source ref to the target ref. \
|
||||
It will move all reagents, except list, given in fourth pin if amount value is positive.\
|
||||
Or it will move only desired reagents if amount is negative, The third pin determines \
|
||||
how much reagent is moved per pulse, between 0 and 50. Amount is given for each separate reagent."
|
||||
container_type = OPENCONTAINER_1
|
||||
complexity = 8
|
||||
inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER, "list of reagents" = IC_PINTYPE_LIST)
|
||||
inputs_default = list("3" = 5)
|
||||
outputs = list()
|
||||
activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
var/direction_mode = SYRINGE_INJECT
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 3)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direction_mode = SYRINGE_DRAW
|
||||
else
|
||||
direction_mode = SYRINGE_INJECT
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/do_work()
|
||||
var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
|
||||
var/list/demand = get_pin_data(IC_INPUT, 4)
|
||||
if(!istype(source) || !istype(target)) //Invalid input
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
if(source.Adjacent(T) && target.Adjacent(T))
|
||||
if(!source.reagents || !target.reagents)
|
||||
return
|
||||
if(ismob(source) || ismob(target))
|
||||
return
|
||||
if(!source.is_open_container() || !target.is_open_container())
|
||||
return
|
||||
if(target.reagents.maximum_volume - target.reagents.total_volume <= 0)
|
||||
return
|
||||
for(var/datum/reagent/G in source.reagents.reagent_list)
|
||||
if (!direction_mode)
|
||||
if(G.id in demand)
|
||||
source.reagents.trans_id_to(target, G.id, transfer_amount)
|
||||
else
|
||||
if(!(G.id in demand))
|
||||
source.reagents.trans_id_to(target, G.id, transfer_amount)
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
|
||||
|
||||
|
||||
33
code/modules/integrated_electronics/subtypes/smart.dm
Normal file
33
code/modules/integrated_electronics/subtypes/smart.dm
Normal file
@@ -0,0 +1,33 @@
|
||||
/obj/item/integrated_circuit/smart
|
||||
category_text = "Smart"
|
||||
|
||||
/obj/item/integrated_circuit/smart/basic_pathfinder
|
||||
name = "basic pathfinder"
|
||||
desc = "This complex circuit is able to determine what direction a given target is."
|
||||
extended_desc = "This circuit uses a miniturized, integrated camera to determine where the target is. If the machine \
|
||||
cannot see the target, it will not be able to calculate the correct direction."
|
||||
icon_state = "numberpad"
|
||||
complexity = 25
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list("dir" = IC_PINTYPE_DIR)
|
||||
activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/smart/basic_pathfinder/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
|
||||
if(!isweakref(I.data))
|
||||
return
|
||||
var/atom/A = I.data.resolve()
|
||||
if(!A)
|
||||
return
|
||||
if(!(A in view(get_turf(src))))
|
||||
push_data()
|
||||
return // Can't see the target.
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
145
code/modules/integrated_electronics/subtypes/time.dm
Normal file
145
code/modules/integrated_electronics/subtypes/time.dm
Normal file
@@ -0,0 +1,145 @@
|
||||
/obj/item/integrated_circuit/time
|
||||
name = "time circuit"
|
||||
desc = "Now you can build your own clock!"
|
||||
complexity = 2
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
category_text = "Time"
|
||||
|
||||
/obj/item/integrated_circuit/time/delay
|
||||
name = "two-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of two seconds."
|
||||
icon_state = "delay-20"
|
||||
var/delay = 20
|
||||
activators = list("incoming"= IC_PINTYPE_PULSE_IN,"outgoing" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/do_work()
|
||||
addtimer(CALLBACK(src, .proc/activate_pin, 2), delay)
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/five_sec
|
||||
name = "five-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of five seconds."
|
||||
icon_state = "delay-50"
|
||||
delay = 50
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/one_sec
|
||||
name = "one-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of one second."
|
||||
icon_state = "delay-10"
|
||||
delay = 10
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/half_sec
|
||||
name = "half-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of half a second."
|
||||
icon_state = "delay-5"
|
||||
delay = 5
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/tenth_sec
|
||||
name = "tenth-sec delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit is set to send a pulse after a delay of 1/10th of a second."
|
||||
icon_state = "delay-1"
|
||||
delay = 1
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/custom
|
||||
name = "custom delay circuit"
|
||||
desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \
|
||||
This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse."
|
||||
icon_state = "delay"
|
||||
inputs = list("delay time" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/custom/do_work()
|
||||
var/delay_input = get_pin_data(IC_INPUT, 1)
|
||||
if(delay_input && isnum(delay_input) )
|
||||
var/new_delay = Clamp(delay_input ,1 ,36000) //An hour.
|
||||
delay = new_delay
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker
|
||||
name = "ticker circuit"
|
||||
desc = "This circuit sends an automatic pulse every four seconds."
|
||||
icon_state = "tick-m"
|
||||
complexity = 8
|
||||
var/delay = 4 SECONDS
|
||||
var/next_fire = 0
|
||||
var/is_running = FALSE
|
||||
inputs = list("enable ticking" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("outgoing pulse" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/Destroy()
|
||||
if(is_running)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/on_data_written()
|
||||
var/do_tick = get_pin_data(IC_INPUT, 1)
|
||||
if(do_tick && !is_running)
|
||||
is_running = TRUE
|
||||
tick()
|
||||
else if(is_running)
|
||||
is_running = FALSE
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/proc/tick()
|
||||
if(is_running)
|
||||
addtimer(CALLBACK(src, .proc/tick), delay)
|
||||
if(world.time > next_fire)
|
||||
next_fire = world.time + delay
|
||||
activate_pin(1)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/fast
|
||||
name = "fast ticker"
|
||||
desc = "This advanced circuit sends an automatic pulse every two seconds."
|
||||
icon_state = "tick-f"
|
||||
complexity = 12
|
||||
delay = 2 SECONDS
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 8
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/slow
|
||||
name = "slow ticker"
|
||||
desc = "This simple circuit sends an automatic pulse every six seconds."
|
||||
icon_state = "tick-s"
|
||||
complexity = 4
|
||||
delay = 6 SECONDS
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 2
|
||||
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
name = "integrated clock"
|
||||
desc = "Tells you what the local time is, specific to your station or planet."
|
||||
icon_state = "clock"
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"time" = IC_PINTYPE_STRING,
|
||||
"hours" = IC_PINTYPE_NUMBER,
|
||||
"minutes" = IC_PINTYPE_NUMBER,
|
||||
"seconds" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("get time" = IC_PINTYPE_PULSE_IN, "on time got" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/time/clock/do_work()
|
||||
var/wtime = world.time
|
||||
set_pin_data(IC_OUTPUT, 1, time2text(wtime, "hh:mm:ss") )
|
||||
set_pin_data(IC_OUTPUT, 2, text2num(time2text(wtime, "hh") ) )
|
||||
set_pin_data(IC_OUTPUT, 3, text2num(time2text(wtime, "mm") ) )
|
||||
set_pin_data(IC_OUTPUT, 4, text2num(time2text(wtime, "ss") ) )
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
138
code/modules/integrated_electronics/subtypes/trig.dm
Normal file
138
code/modules/integrated_electronics/subtypes/trig.dm
Normal file
@@ -0,0 +1,138 @@
|
||||
//These circuits do not-so-simple math.
|
||||
/obj/item/integrated_circuit/trig
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"A" = IC_PINTYPE_NUMBER,
|
||||
"B" = IC_PINTYPE_NUMBER,
|
||||
"C" = IC_PINTYPE_NUMBER,
|
||||
"D" = IC_PINTYPE_NUMBER,
|
||||
"E" = IC_PINTYPE_NUMBER,
|
||||
"F" = IC_PINTYPE_NUMBER,
|
||||
"G" = IC_PINTYPE_NUMBER,
|
||||
"H" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("result" = IC_PINTYPE_NUMBER)
|
||||
activators = list("compute" = IC_PINTYPE_PULSE_IN, "on computed" = IC_PINTYPE_PULSE_OUT)
|
||||
category_text = "Trig"
|
||||
extended_desc = "Input and output are in degrees."
|
||||
power_draw_per_use = 1 // Still cheap math.
|
||||
|
||||
// Sine //
|
||||
|
||||
/obj/item/integrated_circuit/trig/sine
|
||||
name = "sin circuit"
|
||||
desc = "Has nothing to do with evil, unless you consider trigonometry to be evil. Outputs the sine of A."
|
||||
icon_state = "sine"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/sine/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = sin(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Cosine //
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosine
|
||||
name = "cos circuit"
|
||||
desc = "Outputs the cosine of A."
|
||||
icon_state = "cosine"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosine/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = cos(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Tangent //
|
||||
|
||||
/obj/item/integrated_circuit/trig/tangent
|
||||
name = "tan circuit"
|
||||
desc = "Outputs the tangent of A. Guaranteed to not go on a tangent about its existance."
|
||||
icon_state = "tangent"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/tangent/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Tan(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Cosecant //
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosecant
|
||||
name = "csc circuit"
|
||||
desc = "Outputs the cosecant of A."
|
||||
icon_state = "cosecant"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/cosecant/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Csc(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Secant //
|
||||
|
||||
/obj/item/integrated_circuit/trig/secant
|
||||
name = "sec circuit"
|
||||
desc = "Outputs the secant of A. Has nothing to do with the security department."
|
||||
icon_state = "secant"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/secant/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Sec(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
// Cotangent //
|
||||
|
||||
/obj/item/integrated_circuit/trig/cotangent
|
||||
name = "cot circuit"
|
||||
desc = "Outputs the cotangent of A."
|
||||
icon_state = "cotangent"
|
||||
inputs = list("A" = IC_PINTYPE_NUMBER)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/trig/cotangent/do_work()
|
||||
pull_data()
|
||||
var/result = null
|
||||
var/A = get_pin_data(IC_INPUT, 1)
|
||||
if(!isnull(A))
|
||||
result = Cot(A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -1,6 +1,3 @@
|
||||
#define SYRINGE_DRAW 0
|
||||
#define SYRINGE_INJECT 1
|
||||
|
||||
/obj/item/reagent_containers/syringe
|
||||
name = "syringe"
|
||||
desc = "A syringe that can hold up to 15 units."
|
||||
|
||||
@@ -91,6 +91,35 @@ other types of metals and chemistry for reagents).
|
||||
build_path = /obj/item/device/paicard
|
||||
category = list("Electronics")
|
||||
|
||||
/datum/design/integrated_printer
|
||||
name = "Integrated circuits printer"
|
||||
desc = "This machine provides all neccesary things for circuitry."
|
||||
id = "icprinter"
|
||||
req_tech = list("programming" = 2,"materials" = 2, "engineering" = 3)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_GLASS = 5000, MAT_METAL = 5000)
|
||||
build_path = /obj/item/device/integrated_circuit_printer
|
||||
category = list("Electronics")
|
||||
|
||||
/datum/design/advupdisk
|
||||
name = "Upgrade disk-advanced circuits"
|
||||
desc = "Upgrade disk for integrated circuits printer.Allows advanced designs."
|
||||
id = "udiskadv"
|
||||
req_tech = list("programming" = 3, "engineering" = 3)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_GLASS = 500, MAT_METAL = 500)
|
||||
build_path = /obj/item/disk/integrated_circuit/upgrade/advanced
|
||||
category = list("Electronics")
|
||||
|
||||
/datum/design/cloneupisk
|
||||
name = "Upgrade disk-assembly cloning"
|
||||
desc = "Upgrade disk for integrated circuits printer.Allows assembly cloning."
|
||||
id = "udiskclone"
|
||||
req_tech = list("programming" = 4, "engineering" = 4)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_GLASS = 500, MAT_METAL = 500)
|
||||
build_path = /obj/item/disk/integrated_circuit/upgrade/clone
|
||||
category = list("Electronics")
|
||||
|
||||
////////////////////////////////////////
|
||||
//////////Disk Construction Disks///////
|
||||
|
||||
@@ -10,6 +10,14 @@
|
||||
build_path = /obj/item/circuitboard/machine/telecomms/receiver
|
||||
category = list("Subspace Telecomms")
|
||||
|
||||
/datum/design/board/exonet_node
|
||||
name = "Machine Design (Exonet Node)"
|
||||
desc = "Allows for the construction of Exonet Node."
|
||||
id = "e-node"
|
||||
req_tech = list("programming" = 2, "engineering" = 3, "bluespace" = 1)
|
||||
build_path = /obj/item/circuitboard/machine/exonet_node
|
||||
category = list("Subspace Telecomms")
|
||||
|
||||
/datum/design/board/telecomms_bus
|
||||
name = "Machine Design (Bus Mainframe)"
|
||||
desc = "Allows for the construction of Telecommunications Bus Mainframes."
|
||||
|
||||
@@ -7,5 +7,133 @@
|
||||
# NOTE: if the rank-name cannot be found in admin_ranks.txt, they will not be adminned! ~Carn #
|
||||
# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. #
|
||||
###############################################################################################
|
||||
<<<<<<< HEAD
|
||||
|
||||
Jayehh = Host
|
||||
Jayehh = Host
|
||||
=======
|
||||
Optimumtact = Host
|
||||
NewSta = Game Master
|
||||
Expletives = Game Master
|
||||
kingofkosmos = Game Master
|
||||
MrStonedOne = Game Master
|
||||
microscopics = Game Master
|
||||
Gun Hog = Game Master
|
||||
KorPhaeron = Game Master
|
||||
razharas = Game Master
|
||||
Lordpidey = Game Master
|
||||
Niknakflak = Game Master
|
||||
rolan7 = Game Master
|
||||
quarxink = Game Master
|
||||
adrix89 = Game Master
|
||||
tle = Game Master
|
||||
xsi = Game Master
|
||||
scaredofshadows = Game Master
|
||||
neofite = Game Master
|
||||
trubblebass = Game Master
|
||||
mport2004 = Game Master
|
||||
deuryn = Game Master
|
||||
agouri = Game Master
|
||||
errorage = Game Master
|
||||
superxpdude = Game Master
|
||||
petethegoat = Game Master
|
||||
korphaeron = Game Master
|
||||
nodrak = Game Master
|
||||
carnwennan = Game Master
|
||||
ikarrus = Game Master
|
||||
cheridan = Game Master
|
||||
giacomand = Game Master
|
||||
rockdtben = Game Master
|
||||
sieve = Game Master
|
||||
aranclanos = Game Master
|
||||
intigracy = Game Master
|
||||
dumpdavidson = Game Master
|
||||
kazeespada = Game Master
|
||||
malkevin = Game Master
|
||||
incoming = Game Master
|
||||
demas = Game Master
|
||||
fleure = Game Master
|
||||
ricotez = Game Master
|
||||
misterperson = Game Master
|
||||
crimsonvision = Game Master
|
||||
iamgoofball = Game Master
|
||||
zelacks = Game Master
|
||||
androidsfv = Game Master
|
||||
miggles = Game Master
|
||||
jordie0608 = Game Master
|
||||
s0ldi3rkr4s0 = Game Master
|
||||
ergovisavi = Game Master
|
||||
vistapowa = Game Master
|
||||
miauw62 = Game Master
|
||||
kazeespada = Game Master
|
||||
rumia29 = Game Master
|
||||
bobylein = Game Master
|
||||
sirbayer = Game Master
|
||||
hornygranny = Game Master
|
||||
yota = Game Master
|
||||
firecage = Game Master
|
||||
donkieyo = Game Master
|
||||
argoneus = Game Master
|
||||
paprka = Game Master
|
||||
cookingboy3 = Game Master
|
||||
limeliz = Game Master
|
||||
steelpoint = Game Master
|
||||
phil235 = Game Master
|
||||
CorruptComputer = Game Master
|
||||
xxnoob = Game Master
|
||||
tkdrg = Game Master
|
||||
Cuboos = Game Master
|
||||
thunder12345 = Game Master
|
||||
wjohnston = Game Master
|
||||
mandurrh = Game Master
|
||||
thurgatar = Game Master
|
||||
xerux = Game Master
|
||||
dannno = Game Master
|
||||
lo6a4evskiy = Game Master
|
||||
vekter = Game Master
|
||||
Ahammer18 = Game Master
|
||||
ACCount12 = Game Master
|
||||
fayrik = Game Master
|
||||
shadowlight213 = Game Master
|
||||
drovidicorv = Game Master
|
||||
Dunc = Game Master
|
||||
MMMiracles = Game Master
|
||||
bear1ake = Game Master
|
||||
CoreOverload = Game Master
|
||||
Jalleo = Game Master
|
||||
ChangelingRain = Game Master
|
||||
FoxPMcCloud = Game Master
|
||||
Xhuis = Game Master
|
||||
Astralenigma = Game Master
|
||||
Tokiko1 = Game Master
|
||||
SuperSayu = Game Master
|
||||
Lzimann = Game Master
|
||||
As334 = Game Master
|
||||
neersighted = Game Master
|
||||
Swankcookie = Game Master
|
||||
Ressler = Game Master
|
||||
Folix = Game Master
|
||||
Bawhoppennn = Game Master
|
||||
Anturke = Host
|
||||
Lumipharon = Game Master
|
||||
bgobandit = Game Master
|
||||
coiax = Game Master
|
||||
RandomMarine = Game Master
|
||||
PKPenguin321 = Game Master
|
||||
TechnoAlchemist = Game Master
|
||||
Aloraydrel = Game Master
|
||||
Quiltyquilty = Game Master
|
||||
SnipeDragon = Game Master
|
||||
Fjeld = Game Master
|
||||
kevinz000 = Game Master
|
||||
Tacolizard = Game Master
|
||||
TrustyGun = Game Master
|
||||
Cyberboss = Game Master
|
||||
PJB3005 = Game Master
|
||||
Sweaterkittens = Game Master
|
||||
Feemjmeem = Game Master
|
||||
JStheguy = Game Master
|
||||
excessiveuseofcobby = Game Master
|
||||
Plizzard = Game Master
|
||||
octareenroon91 = Game Master
|
||||
Serpentarium = Game Master
|
||||
>>>>>>> bdfbafd... [READY]integrated circuitry port+upgrade. (#32481)
|
||||
|
||||
@@ -504,6 +504,7 @@ MICE_ROUNDSTART 10
|
||||
## If the percentage of players alive (doesn't count conversions) drops below this threshold the emergency shuttle will be forcefully called (provided it can be)
|
||||
#EMERGENCY_SHUTTLE_AUTOCALL_THRESHOLD 0.2
|
||||
|
||||
<<<<<<< HEAD
|
||||
## CREW OBJECTIVES ##
|
||||
## Comment to disable objectives for innocent crew members.
|
||||
ALLOW_CREW_OBJECTIVES
|
||||
@@ -514,3 +515,7 @@ ALLOW_MISCREANTS
|
||||
|
||||
## Uncomment to let miscreants spawn during Extended. I hold no responsibility for fun that may occur while this is enabled.
|
||||
#ALLOW_EXTENDED_MISCREANTS
|
||||
=======
|
||||
## Determines if players are allowed to print integrated circuits, uncomment to allow.
|
||||
#IC_PRINTING
|
||||
>>>>>>> bdfbafd... [READY]integrated circuitry port+upgrade. (#32481)
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
BIN
icons/obj/electronic_assemblies.dmi
Normal file
BIN
icons/obj/electronic_assemblies.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
BIN
icons/obj/electronic_assemblies2.dmi
Normal file
BIN
icons/obj/electronic_assemblies2.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 59 KiB |
BIN
sound/machines/synth_no.ogg
Normal file
BIN
sound/machines/synth_no.ogg
Normal file
Binary file not shown.
BIN
sound/machines/synth_yes.ogg
Normal file
BIN
sound/machines/synth_yes.ogg
Normal file
Binary file not shown.
@@ -44,6 +44,7 @@
|
||||
#include "code\__DEFINES\flags.dm"
|
||||
#include "code\__DEFINES\food.dm"
|
||||
#include "code\__DEFINES\hud.dm"
|
||||
#include "code\__DEFINES\integrated_electronics.dm"
|
||||
#include "code\__DEFINES\inventory.dm"
|
||||
#include "code\__DEFINES\is_helpers.dm"
|
||||
#include "code\__DEFINES\jobs.dm"
|
||||
@@ -265,6 +266,7 @@
|
||||
#include "code\controllers\subsystem\title.dm"
|
||||
#include "code\controllers\subsystem\vote.dm"
|
||||
#include "code\controllers\subsystem\weather.dm"
|
||||
#include "code\controllers\subsystem\processing\circuit.dm"
|
||||
#include "code\controllers\subsystem\processing\fastprocess.dm"
|
||||
#include "code\controllers\subsystem\processing\fields.dm"
|
||||
#include "code\controllers\subsystem\processing\flightpacks.dm"
|
||||
@@ -285,6 +287,7 @@
|
||||
#include "code\datums\dna.dm"
|
||||
#include "code\datums\dog_fashion.dm"
|
||||
#include "code\datums\emotes.dm"
|
||||
#include "code\datums\EPv2.dm"
|
||||
#include "code\datums\explosion.dm"
|
||||
#include "code\datums\forced_movement.dm"
|
||||
#include "code\datums\holocall.dm"
|
||||
@@ -628,6 +631,7 @@
|
||||
#include "code\game\machinery\dna_scanner.dm"
|
||||
#include "code\game\machinery\doppler_array.dm"
|
||||
#include "code\game\machinery\droneDispenser.dm"
|
||||
#include "code\game\machinery\exonet_node.dm"
|
||||
#include "code\game\machinery\firealarm.dm"
|
||||
#include "code\game\machinery\flasher.dm"
|
||||
#include "code\game\machinery\gulag_item_reclaimer.dm"
|
||||
@@ -1538,6 +1542,39 @@
|
||||
#include "code\modules\hydroponics\grown\tobacco.dm"
|
||||
#include "code\modules\hydroponics\grown\tomato.dm"
|
||||
#include "code\modules\hydroponics\grown\towercap.dm"
|
||||
#include "code\modules\integrated_electronics\core\analyzer.dm"
|
||||
#include "code\modules\integrated_electronics\core\assemblies.dm"
|
||||
#include "code\modules\integrated_electronics\core\debugger.dm"
|
||||
#include "code\modules\integrated_electronics\core\helpers.dm"
|
||||
#include "code\modules\integrated_electronics\core\integrated_circuit.dm"
|
||||
#include "code\modules\integrated_electronics\core\pins.dm"
|
||||
#include "code\modules\integrated_electronics\core\prefab.dm"
|
||||
#include "code\modules\integrated_electronics\core\printer.dm"
|
||||
#include "code\modules\integrated_electronics\core\wirer.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\boolean_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\char_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\color_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\dir_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\list_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\number_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\ref_pin.dm"
|
||||
#include "code\modules\integrated_electronics\core\special_pins\string_pin.dm"
|
||||
#include "code\modules\integrated_electronics\passive\passive.dm"
|
||||
#include "code\modules\integrated_electronics\passive\power.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\arithmetic.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\converters.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\data_transfer.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\input.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\lists.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\logic.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\manipulation.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\memory.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\output.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\power.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\reagents.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\smart.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\time.dm"
|
||||
#include "code\modules\integrated_electronics\subtypes\trig.dm"
|
||||
#include "code\modules\jobs\access.dm"
|
||||
#include "code\modules\jobs\job_exp.dm"
|
||||
#include "code\modules\jobs\jobs.dm"
|
||||
|
||||
14
tgui/src/interfaces/exonet_node.ract
Normal file
14
tgui/src/interfaces/exonet_node.ract
Normal file
@@ -0,0 +1,14 @@
|
||||
<ui-display>
|
||||
<ui-section label='Status'>
|
||||
<ui-button
|
||||
action='toggle_power'
|
||||
style='{{data.toggle ? "selected" : null}}' >
|
||||
Turn {{data.toggle ? "off" : "on"}}
|
||||
</ui-button>
|
||||
</ui-section>
|
||||
<ui-display title='Logging'>
|
||||
{{#each data.logs}}
|
||||
<ui-section label='>'>{{.}}<ui-section>
|
||||
{{/each}}
|
||||
</ui-display>
|
||||
</ui-display>
|
||||
Reference in New Issue
Block a user