mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-15 20:52:41 +00:00
Late September Sync (#579)
* Elevators aren't bottomless voids!
* Updates changelog
* Sombrero Code
* Fixes #2365
* Adds changelog
* Sleeper is evil.
* no message
* Changelog
* Stops observers from leaving prints on the ground.
No more spooking the mortals, ghosts.
* Allows autotraitor in secret to start with 0 players
* Adds changelog
* Makes diona slightly less slow
* Adds changelog
* Bowling Shirts
* Updates changelog
* Adds a missing description
* Flat Cap Changes and Hair Bow
* Fixed Error
* Adds an in-hand
* Lower Torso cannot be amputated
* Smoke works, adds changelog
* Updates changelog
* Makes Unathi Voidsuits Less Fat
* Medical related fixes
* Fuzzy Cuffs
* Tube Top
* Made Icons for Security Suit Less Gaunt
* Revert "Medical related fixes"
This reverts commit d7c59520e6.
* Just the fix to random med item now
* Adds organ fixing
* Fixes Evening Glove Coloring
* HAZMAT Suits
* Changes Unathi sprite slightly
* Tweaks skirt pathing
* Corrects changelog
* Adds changelog
* Construction Voidsuits
* makes people bleed real good
* adderino changeling
* Biohazard Voidsuit
* Revert "Revert "Adds hub passwordu""
* Explosive implants should no longer gib on limbs.
* Adds space penguins and space geese.
* Revert "Revert "Revert "Adds hub passwordu"""
* Makes flash rounds respect eye protection
* Water > Fire
* There's plenty lying around, I think
* Naming inconsistencies fixed
The short naming of central command has been really inconsistent across
the game's files. This has always annoyed the shit out of me.
CentComm and Centcomm and Centcom are now all CentCom, specifically with
that capitalization. Why one M instead of two M's? Because Comm with two
'M's = Communications. Hence, Telecomms, NOT Telecoms. Telecoms is
incorrect. CentCom was also chosen because CentCom with one M and this
casing is most found throughout the game's files.
Speaking of Telecomms, I corrected one instance in the game where it's
Telecom. Like I said, this is not correct. There was only one
inconsistency.
Likewise, Nanotrasen has been changed to NanoTrasen. Nanotrasen only
appears 20 times, where NanoTrasen appears 62. NanoTrasen is clearly the
preferred, correct naming.
* Almost forgot plural of Telecomm
* Finalizes work, adds designs to research.
* Press Vest
* Removes Mags/Shells, Adds Recorder and Flashlight
* Fixes spans.
* Raises the number of players needed to start Ninja
* Still needs to fix internal bleeding
* Allows Wirer To Attach to Toolbelts
* Fixes #393
* Tweaks FBP temperature
* Corrects Changelog
* Fixes some Advanced Egun oversights
* Embiggens the laser carbine and the lasercannon.
* Messenger Bags
* Health analyzers detect appendicitis
* Custom Circuit Additions & Fixes
Adds Med Scanner and Advanced Med Scanner circuits.
Clock circuit is now functional.
Five second delay will delay for five seconds and not one second.
Renaming circuitry now respects ability to do so (e.g. being alive).
Firing circuit can now be obtained by science normally.
Examining inside assembly cases now requires adjacency.
* More Additions
You can now cancel inputting on a text or numberpad.
Zero is now displayed properly on the UI and not be shown as null.
The small and medium assemblies now have real sprites.
Total health percentage for med scanners and advanced med scanners now reports a proper percentage and not 1 or 0.
The constant memory chip now can be set by using it in hand, making it usable.
The constant memory chip now accepts refs as data to store. To use, select 'ref' when using inhand, then hit it against the thing you want to store.
* Allows Chemists to View Medical Records on their PDA
* Refactors splinting
* Refactors the forceMove() drop.
Makes dropping a its proc instead, cleaning up forceMove() handling.
* Replaces ORGAN_SPLINTED
* Supportive suits now only loop through bad organs
* Adds changelog
* Lasercannon tweaks
* Bloodloss tweak
* Adds hawaii shirt
Attachable to any uniform, works like suit jackets.
* Changelog cause why not
At this rate I'll forget how to do those otherwise
* Adds randomized alohas
Also some color matrix helpers from TG
* Appendicitis doesn't cancel itself out.
* Removes debug stuff
* Radsuit Sprite Changes
* Allows us to actually use the messenger bags
* Fixes spelling mistake
* Ported ventcrawling from vg.
* Fixes changelog errors
* Updates changelog
* Tweaks vent crawling.
The ability to ventcrawl is now checked by the /handle_ventcrawl() proc, making it possible to properly check before and after the do_after() call.
Moves various checks into the base can_ventcrawl proc.
Now lists the first object that prevents a mob from ventcrawling, making it easier to correct the exception list.
Removes the issmall() check, instead checks if the crawling mob has the relevant verb. Fixes #14081.
* Suit Storage Items
* Adds in IB removal
* More Circuit Things
Adds Locomotion circuit, which makes the machine move in a given direction.
Adds Signaler circuit, which can send and receive signals from a signaler.
Adds a new tool, the Debugger, which lets one directly set data in a specific pin. It can also pulse activation pins.
Adds ability to define custom cooldown times for each component.
Smoke generator now has a 30 second cooldown.
Cleans up some code somewhat.
* Adds design for locomotion circuit.
* Cleans up code
* Even more sprites by Mechoid.
Fixes abs to rel converter.
* Black Messenger Bag
* Powersink fix
* Even More Sodding Circuits
Adds new RNG circuit, to make random numbers each time.
Adds new Concatenating circuit, so you can make lots of small strings into one big one.
Adds new light and advanced light circuit. Basic just has a normal light that can be toggled. Advanced allows it to be any color using RGB, and a brightness between 0 and 6.
New sprites for the debugger and wirer, by Mechoid.
Hopefully finally fixes smoke generator from being unobtainable.
* Adds basic circuit kit and spare circuit tools to Tech Storage.
* Part the first
* Changelog
* Allows robots to be constructed with prosthetic limbs as well as borg limbs.
* Map change
* Secbelt can hold stun revolvers and eguns
* Voidsuit Sprite Changes
* Tweaks burst laser
* Lasers, energy projectiles, and muzzle flashes now produce light.
It's a bit wonky due to lighting only updating once every half-second,
but it's very much functional, at least on my desktop.
* Adds bridge bunnies
* Slightly cleans up the occupation screen, adds uniform to locker
* Map Changes
* Adds Changelog
* Fixes stuff
* Allows jobbanning of cargo department jobs
* Re-adds balance changes to heavy lasers.
They got changed by accident when I did the laser light show.
Also, adds changelogs for my last couple changes, because I'm an
idiot and forgot them.
* Fixed missing sprite
* Dress Loadout Additions
* I Can't Believe It's Not Circuits (it is)
Fixes numberpad and letterpad pulsing.
Debugger and Constant chip can now have null written to it.
Adds new sound output, with two types so far. One being the 'beeper' type, which can do things like buzz, ping, beep, etc. The second type is a securitron speaker, which allows us to get closer to building a functioning Beepsky.
* Adds EPv2 Circuit
Adds a circuit that allows it to send and receive EPv2 messages, allowing for a more robust transmission of data that signalers cannot deliver. Bonus: Communicators can send text messages to custom machines using this.
* Updates changelog
* Fixes not being able to put things in medkits.
* Technomancer Tweaks
Cost for various spells and equipment adjusted greatly. In general, things are cheaper, and everything should now be in multiples of 25, so no points are wasted.
The default jumpsuit for Technomancers is now heavily insulated, protecting them from tasers, batons, and perhaps unfortunate lightning strikes.
Instability between 31 and 50 made less harsh.
Wards made with a scepter of enhancement will break the cloak of anyone invisible that it can see.
Fire aura buffed, increased rate of heating as well as temperature cap for both non-scepter and scepter effects.
Reflect spell made more forgiving for the Technomancer, lasting longer before expiring.
Projectile spells should be able to hit people more reliably.
* Shotgun Reloading Tweak
Adds ability to hit a shotgun or similar weapon with a container containing ammo, to load said ammo into the shotgun one at a time automatically, instead of having to play inventory tetris, as requested by some people.
* Use sanitizeName for the guest pass terminal name input to prevent excessively long names.
* Circuit UI and Assembly Tweaks
Adds new drone assembly, which has stats between the medium and large assembly. Sprites by Mechoid.
Assemblies now have a light UI when examined while opened, which displays what's inside, as well as how close to the cap for parts or complexity you are getting. Click the names of a component to open the wiring interface for that component. You can also rename each component from the UI. Bonus: Having multiple components of the same name will no longer appear as one component.
Adds ability to rename the assembly, using the new UI.
* Revert "Ported ventcrawling from vg."
* Re-adds a nice, useful macro
* Fixes #2431
* Tweaks Riot armor
* Fixes a typo in the DNA Modifier
* Ripped Jeans (And White Shorts)
* Adds shanking
* Adds changelog
* Removes a stray world <<
* Ported ventcrawling from vg.
* Tweaks vent crawling.
The ability to ventcrawl is now checked by the /handle_ventcrawl() proc, making it possible to properly check before and after the do_after() call.
Moves various checks into the base can_ventcrawl proc.
Now lists the first object that prevents a mob from ventcrawling, making it easier to correct the exception list.
Removes the issmall() check, instead checks if the crawling mob has the relevant verb. Fixes #14081.
* Long, time-consuming not one-line fix
* Makes cigs branded too
Description of cig/cigbutt would reveal its brand for dastardly murdersolving revelations.
* Adding a article
* The door hacker now only pings the user
* Removes implants from Deathsquad
* Adds the ability to apply pressure to bleeding wounds
* Shoes
* EVA rigs should use their default sprites on Taj and Unathi
* Fixing some errors
* Update loadout_xeno.dm
* Delete back_vr.dmi
* Add files via upload
This commit is contained in:
387
code/modules/integrated_electronics/_defines.dm
Normal file
387
code/modules/integrated_electronics/_defines.dm
Normal file
@@ -0,0 +1,387 @@
|
||||
#define DATA_CHANNEL "data channel"
|
||||
#define PULSE_CHANNEL "pulse channel"
|
||||
|
||||
/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 = 1
|
||||
var/extended_desc = null
|
||||
var/list/inputs = list()
|
||||
var/list/outputs = list()
|
||||
var/list/activators = list()
|
||||
var/number_of_inputs = 0 //This is how many input pins are created
|
||||
var/number_of_outputs = 0 //Likewise for output
|
||||
var/number_of_activators = 0 //Guess
|
||||
var/list/input_names = list()
|
||||
var/list/output_names = list()
|
||||
var/list/activator_names = list()
|
||||
var/last_used = 0 //Uses world.time
|
||||
var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'.
|
||||
var/cooldown_per_use = 2 SECONDS
|
||||
|
||||
/obj/item/integrated_circuit/examine(mob/user)
|
||||
..()
|
||||
user << "This board has [inputs.len] input [inputs.len != 1 ? "pins" : "pin"] and \
|
||||
[outputs.len] output [outputs.len != 1 ? "pins" : "pin"]."
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
if(I.linked.len)
|
||||
user << "\The [I.name] is connected to [I.get_linked_to_desc()]."
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
if(O.linked.len)
|
||||
user << "\The [O.name] is connected to [O.get_linked_to_desc()]."
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
if(A.linked.len)
|
||||
user << "\The [A.name] is connected to [A.get_linked_to_desc()]."
|
||||
|
||||
interact(user)
|
||||
|
||||
/obj/item/integrated_circuit/New()
|
||||
..()
|
||||
var/i = 0
|
||||
if(number_of_inputs)
|
||||
for(i = number_of_inputs, i > 0, i--)
|
||||
inputs.Add(new /datum/integrated_io/input(src))
|
||||
|
||||
if(number_of_outputs)
|
||||
for(i = number_of_outputs, i > 0, i--)
|
||||
outputs.Add(new /datum/integrated_io/output(src))
|
||||
|
||||
if(number_of_activators)
|
||||
for(i = number_of_activators, i > 0, i--)
|
||||
activators.Add(new /datum/integrated_io/activate(src))
|
||||
|
||||
apply_names_to_io()
|
||||
|
||||
/obj/item/integrated_circuit/proc/apply_names_to_io()
|
||||
var/i = 1
|
||||
if(input_names.len)
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.name = "[input_names[i]]"
|
||||
i++
|
||||
i = 1
|
||||
if(output_names.len)
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.name = "[output_names[i]]"
|
||||
i++
|
||||
|
||||
i = 1
|
||||
if(activator_names.len)
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
A.name = "[activator_names[i]]"
|
||||
i++
|
||||
|
||||
/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()
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
qdel(I)
|
||||
for(var/datum/integrated_io/O in outputs)
|
||||
qdel(O)
|
||||
for(var/datum/integrated_io/A in activators)
|
||||
qdel(A)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/emp_act(severity)
|
||||
for(var/datum/integrated_io/io in inputs + outputs + activators)
|
||||
io.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(!M.canmove || M.stat || M.restrained())
|
||||
return
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name the circuit?", "Rename", src.name), MAX_NAME_LEN)
|
||||
|
||||
if(src && input)
|
||||
M << "<span class='notice'>The circuit '[src.name]' is now labeled '[input]'.</span>"
|
||||
name = input
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number)
|
||||
switch(pin_type)
|
||||
if("input")
|
||||
if(pin_number > inputs.len)
|
||||
return null
|
||||
return inputs[pin_number]
|
||||
if("output")
|
||||
if(pin_number > outputs.len)
|
||||
return null
|
||||
return outputs[pin_number]
|
||||
if("activator")
|
||||
if(pin_number > activators.len)
|
||||
return null
|
||||
return activators[pin_number]
|
||||
return null
|
||||
|
||||
/obj/item/integrated_circuit/interact(mob/user)
|
||||
if(get_dist(get_turf(src), user) > 1)
|
||||
user.unset_machine(src)
|
||||
return
|
||||
var/HTML = "<html><head><title>[src.name]</title></head><body>"
|
||||
HTML += "<div align='center'>"
|
||||
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 424px'>"
|
||||
|
||||
HTML += "<br><a href='?src=\ref[src];user=\ref[user]'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=\ref[src];user=\ref[user];rename=1'>\[Rename\]</a><br>"
|
||||
|
||||
HTML += "<colgroup>"
|
||||
HTML += "<col style='width: 121px'>"
|
||||
HTML += "<col style='width: 181px'>"
|
||||
HTML += "<col style='width: 122px'>"
|
||||
HTML += "</colgroup>"
|
||||
|
||||
var/column_width = 3
|
||||
var/row_height = max(inputs.len, outputs.len, 1)
|
||||
var/i
|
||||
var/j
|
||||
for(i = 1, i < row_height+1, i++)
|
||||
HTML += "<tr>"
|
||||
for(j = 1, j < column_width+1, j++)
|
||||
var/datum/integrated_io/io = null
|
||||
var/words = null
|
||||
var/height = 1
|
||||
switch(j)
|
||||
if(1)
|
||||
io = get_pin_ref("input",i)
|
||||
if(io)
|
||||
if(io.linked.len)
|
||||
words = "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]><b>[io.name] [io.display_data()]</b></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else // "Click <a href=?src=\ref[src];action=start>here</a>!"
|
||||
words = "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>[io.name] [io.display_data()]</a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
if(outputs.len > inputs.len)
|
||||
// height = Floor(outputs.len / inputs.len)
|
||||
height = 1 // Because of bugs, if there's more outputs than inputs, it causes the output side to be hidden.
|
||||
//world << "I wrote [words] at ([i],[j]). Height = [height]."
|
||||
if(2)
|
||||
if(i == 1)
|
||||
words = "[src.name]<br><br>[src.desc]"
|
||||
height = row_height
|
||||
//world << "I wrote the center piece because i was equal to 1, at ([i],[j]). Height = [height]."
|
||||
else
|
||||
continue
|
||||
if(3)
|
||||
io = get_pin_ref("output",i)
|
||||
if(io)
|
||||
if(io.linked.len)
|
||||
words = "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]><b>[io.name] [io.display_data()]</b></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else
|
||||
words = "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>[io.name] [io.display_data()]</a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
if(inputs.len > outputs.len)
|
||||
// height = Floor(inputs.len / outputs.len)
|
||||
height = 1 // See above.
|
||||
//world << "I wrote [words] at ([i],[j]). Height = [height]."
|
||||
HTML += "<td align='center' rowspan='[height]'>[words]</td>"
|
||||
//HTML += "<td align='center'>[words]</td>"
|
||||
//world << "Writing to ([i],[j])."
|
||||
HTML += "</tr>"
|
||||
|
||||
if(activators.len)
|
||||
for(i = 1, i < activators.len+1, i++)
|
||||
var/datum/integrated_io/io = null
|
||||
var/words = null
|
||||
io = get_pin_ref("activator",i)
|
||||
if(io)
|
||||
if(io.linked.len)
|
||||
words = "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]><font color='FF0000'><b>[io.name]</b></font></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src[src];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
else // "Click <a href=?src=\ref[src];action=start>here</a>!"
|
||||
words = "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]><font color='FF0000'>[io.name]</font></a><br>"
|
||||
for(var/datum/integrated_io/linked in io.linked)
|
||||
words += "<a href=?src=\ref[src];wire=1;user=\ref[user];pin=\ref[io]>\[[linked.name]\]</a> \
|
||||
@ <a href=?src=\ref[linked.holder];examine=1;user=\ref[user]>[linked.holder]</a><br>"
|
||||
HTML += "<tr>"
|
||||
HTML += "<td colspan='3' align='center'>[words]</td>"
|
||||
HTML += "</tr>"
|
||||
|
||||
HTML += "</table>"
|
||||
HTML += "</div>"
|
||||
|
||||
HTML += "<br><font color='0000FF'>Complexity: [complexity]</font>"
|
||||
HTML += "<br><font color='0000FF'>[extended_desc]</font>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
user << browse(HTML, "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
|
||||
//user << sanitize(HTML, "window=debug;size=400x400;border=1;can_resize=1;can_close=1;can_minimize=1")
|
||||
//world << sanitize(HTML)
|
||||
|
||||
user.set_machine(src)
|
||||
onclose(user, "circuit-\ref[src]")
|
||||
|
||||
/obj/item/integrated_circuit/Topic(href, href_list[])
|
||||
var/mob/living/user = locate(href_list["user"]) in mob_list
|
||||
var/pin = locate(href_list["pin"]) in inputs + outputs + activators
|
||||
|
||||
if(!user || !user.Adjacent(get_turf(src)) )
|
||||
return 1
|
||||
|
||||
if(!user.canmove || user.stat || user.restrained())
|
||||
return
|
||||
|
||||
if(href_list["wire"])
|
||||
if(ishuman(user) && Adjacent(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/held_item = H.get_active_hand()
|
||||
|
||||
if(istype(held_item, /obj/item/device/integrated_electronics/wirer))
|
||||
var/obj/item/device/integrated_electronics/wirer/wirer = held_item
|
||||
if(pin)
|
||||
wirer.wire(pin, user)
|
||||
|
||||
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, user)
|
||||
|
||||
// if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer))
|
||||
// wirer = H.r_hand
|
||||
// else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer))
|
||||
// wirer = H.l_hand
|
||||
|
||||
// if(wirer && pin)
|
||||
// wirer.wire(pin, user)
|
||||
else
|
||||
user << "<span class='warning'>You can't do a whole lot without tools.</span>"
|
||||
|
||||
if(href_list["examine"])
|
||||
examine(user)
|
||||
|
||||
if(href_list["rename"])
|
||||
rename_component(user)
|
||||
|
||||
interact(user) // To refresh the UI.
|
||||
|
||||
/datum/integrated_io
|
||||
var/name = "input/output"
|
||||
var/obj/item/integrated_circuit/holder = null
|
||||
var/data = null
|
||||
var/list/linked = list()
|
||||
var/io_type = DATA_CHANNEL
|
||||
|
||||
/datum/integrated_io/New(var/newloc)
|
||||
..()
|
||||
holder = newloc
|
||||
if(!holder)
|
||||
message_admins("ERROR: An integrated_io ([src.name]) spawned without a holder! This is a bug.")
|
||||
|
||||
/datum/integrated_io/Destroy()
|
||||
disconnect()
|
||||
holder = null
|
||||
..()
|
||||
|
||||
/datum/integrated_io/proc/display_data()
|
||||
if(isnull(data))
|
||||
return "(null)" // Empty data means nothing to show.
|
||||
if(istext(data))
|
||||
return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'.
|
||||
if(istype(data, /atom))
|
||||
var/atom/A = data
|
||||
return "([A.name] \[Ref\])" // For refs, we want just the name displayed.
|
||||
return "([data])" // Nothing special needed for numbers or other stuff.
|
||||
|
||||
/datum/integrated_io/activate/display_data()
|
||||
return "(\[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) || istype(new_data, /atom/) ) // Anything else is a type we don't want.
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/proc/push_data()
|
||||
if(linked.len)
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.write_data_to_pin(data)
|
||||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
if(linked.len)
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.holder.work()
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
if(linked.len)
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
write_data_to_pin(io.data)
|
||||
|
||||
/datum/integrated_io/proc/get_linked_to_desc()
|
||||
if(linked.len)
|
||||
var/result = english_list(linked)
|
||||
return "the [result]"
|
||||
return "nothing"
|
||||
|
||||
/datum/integrated_io/proc/disconnect()
|
||||
if(linked.len)
|
||||
//First we iterate over everything we are linked to.
|
||||
for(var/datum/integrated_io/their_io in linked)
|
||||
//While doing that, we iterate them as well, and disconnect ourselves from them.
|
||||
for(var/datum/integrated_io/their_linked_io in their_io.linked)
|
||||
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.
|
||||
src.linked.Remove(their_io)
|
||||
|
||||
/datum/integrated_io/input
|
||||
name = "input pin"
|
||||
|
||||
/datum/integrated_io/output
|
||||
name = "output pin"
|
||||
|
||||
/datum/integrated_io/activate
|
||||
name = "activation pin"
|
||||
io_type = PULSE_CHANNEL
|
||||
|
||||
/obj/item/integrated_circuit/proc/push_data()
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/pull_data()
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/work(var/datum/integrated_io/io)
|
||||
if(last_used + cooldown_per_use > world.time) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
return 0
|
||||
last_used = world.time
|
||||
return 1
|
||||
|
||||
/obj/item/integrated_circuit/proc/disconnect_all()
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.disconnect()
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.disconnect()
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
A.disconnect()
|
||||
183
code/modules/integrated_electronics/arithmetic.dm
Normal file
183
code/modules/integrated_electronics/arithmetic.dm
Normal file
@@ -0,0 +1,183 @@
|
||||
//These circuits do simple math.
|
||||
/obj/item/integrated_circuit/arithmetic
|
||||
complexity = 1
|
||||
number_of_inputs = 8
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D",
|
||||
"E",
|
||||
"F",
|
||||
"G",
|
||||
"H"
|
||||
)
|
||||
output_names = list(
|
||||
"result"
|
||||
)
|
||||
activator_names = list(
|
||||
"compute"
|
||||
)
|
||||
|
||||
// +Adding+ //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/addition
|
||||
name = "addition circuit"
|
||||
desc = "This circuit can add numbers together."
|
||||
icon_state = "addition"
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/addition/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result + I.data
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
|
||||
// -Subtracting- //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction
|
||||
name = "subtraction circuit"
|
||||
desc = "This circuit can subtract numbers."
|
||||
icon_state = "subtraction"
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result - I.data
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
|
||||
// *Multiply* //
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/multiplication
|
||||
name = "multiplication circuit"
|
||||
desc = "This circuit can multiply numbers."
|
||||
icon_state = "multiplication"
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/subtraction/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
result = result * I.data
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
|
||||
// /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!"
|
||||
icon_state = "division"
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/division/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(isnum(I.data) && I.data != 0) //No runtimes here.
|
||||
result = result / I.data
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
|
||||
// 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"
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 1
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/absolute/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(isnum(I.data) && I.data != 0)
|
||||
result = abs(result)
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
|
||||
// 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."
|
||||
icon_state = "average"
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/average/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
var/inputs_used = 0
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(isnum(I.data))
|
||||
inputs_used++
|
||||
result = result + I.data
|
||||
|
||||
if(inputs_used)
|
||||
result = result / inputs_used
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
|
||||
// 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"
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 1
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/pi/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/output/O = outputs[1]
|
||||
O.data = 3.14159
|
||||
O.push_data()
|
||||
|
||||
// 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."
|
||||
icon_state = "random"
|
||||
number_of_inputs = 2
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"L",
|
||||
"H"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/arithmetic/random/work()
|
||||
if(..())
|
||||
var/result = 0
|
||||
var/datum/integrated_io/L = inputs[1]
|
||||
var/datum/integrated_io/H = inputs[2]
|
||||
|
||||
if(isnum(L.data) && isnum(H.data))
|
||||
result = rand(L.data, H.data)
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = result
|
||||
O.push_data()
|
||||
168
code/modules/integrated_electronics/assemblies.dm
Normal file
168
code/modules/integrated_electronics/assemblies.dm
Normal file
@@ -0,0 +1,168 @@
|
||||
/obj/item/device/electronic_assembly
|
||||
name = "electronic assembly"
|
||||
desc = "It's a case, for building electronics with."
|
||||
w_class = 2
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "setup_small"
|
||||
var/max_components = 10
|
||||
var/max_complexity = 40
|
||||
var/opened = 0
|
||||
|
||||
/obj/item/device/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
icon_state = "setup_medium"
|
||||
w_class = 3
|
||||
max_components = 20
|
||||
max_complexity = 80
|
||||
|
||||
/obj/item/device/electronic_assembly/large
|
||||
name = "electronic machine"
|
||||
icon_state = "setup_large"
|
||||
w_class = 4
|
||||
max_components = 30
|
||||
max_complexity = 120
|
||||
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
icon_state = "setup_drone"
|
||||
w_class = 3
|
||||
max_components = 25
|
||||
max_complexity = 100
|
||||
|
||||
/obj/item/device/electronic_assembly/interact(mob/user)
|
||||
if(get_dist(get_turf(src), user) > 1)
|
||||
user.unset_machine(src)
|
||||
return
|
||||
var/total_parts = 0
|
||||
var/total_complexity = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
total_parts++
|
||||
total_complexity = total_complexity + part.complexity
|
||||
var/HTML = "<html><head><title>[src.name]</title></head><body>"
|
||||
|
||||
HTML += "<br><a href='?src=\ref[src];user=\ref[user]'>\[Refresh\]</a> | "
|
||||
HTML += "<a href='?src=\ref[src];user=\ref[user];rename=1'>\[Rename\]</a><br>"
|
||||
HTML += "[total_parts]/[max_components] ([round((total_parts / 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."
|
||||
HTML += "<br><br>"
|
||||
HTML += "Components;<br>"
|
||||
for(var/obj/item/integrated_circuit/circuit in contents)
|
||||
HTML += "<a href=?src=\ref[circuit];examine=1;user=\ref[user]>[circuit.name]</a> | "
|
||||
HTML += "<a href=?src=\ref[circuit];rename=1;user=\ref[user]>\[Rename\]</a>"
|
||||
HTML += "<br>"
|
||||
|
||||
HTML += "</body></html>"
|
||||
user << browse(HTML, "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[])
|
||||
var/mob/living/user = locate(href_list["user"]) in mob_list
|
||||
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(!user.canmove || user.stat || user.restrained())
|
||||
return
|
||||
|
||||
if(href_list["rename"])
|
||||
rename(user)
|
||||
|
||||
interact(user) // To refresh the UI.
|
||||
|
||||
/obj/item/device/electronic_assembly/verb/rename()
|
||||
set name = "Rename Circuit"
|
||||
set category = "Object"
|
||||
set desc = "Rename your circuit, useful to stay organized."
|
||||
|
||||
var/mob/M = usr
|
||||
|
||||
if(!M.canmove || M.stat || M.restrained())
|
||||
return
|
||||
|
||||
var/input = sanitizeSafe(input("What do you want to name this?", "Rename", src.name), MAX_NAME_LEN)
|
||||
|
||||
if(src && input)
|
||||
M << "<span class='notice'>The machine now has a label reading '[input]'.</span>"
|
||||
name = input
|
||||
|
||||
/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)
|
||||
..()
|
||||
if(user.Adjacent(src))
|
||||
if(!opened)
|
||||
for(var/obj/item/integrated_circuit/output/screen/S in contents)
|
||||
if(S.stuff_to_display)
|
||||
user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'."
|
||||
else
|
||||
interact(user)
|
||||
// var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents
|
||||
// if(IC)
|
||||
// IC.examine(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user)
|
||||
if(istype(I, /obj/item/integrated_circuit))
|
||||
if(!opened)
|
||||
user << "<span class='warning'>\The [src] isn't opened, so you can't put anything inside. Try using a crowbar.</span>"
|
||||
return 0
|
||||
var/obj/item/integrated_circuit/IC = I
|
||||
var/total_parts = 0
|
||||
var/total_complexity = 0
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
total_parts++
|
||||
total_complexity = total_complexity + part.complexity
|
||||
|
||||
if( (total_parts + 1) >= max_components)
|
||||
user << "<span class='warning'>You can't seem to add this [IC.name], since there's no more room.</span>"
|
||||
return 0
|
||||
if( (total_complexity + IC.complexity) >= max_complexity)
|
||||
user << "<span class='warning'>You can't seem to add this [IC.name], since this setup's too complicated for the case.</span>"
|
||||
return 0
|
||||
|
||||
user << "<span class='notice'>You slide \the [IC] inside \the [src].</span>"
|
||||
user.drop_item()
|
||||
IC.forceMove(src)
|
||||
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(!opened)
|
||||
user << "<span class='warning'>\The [src] isn't opened, so you can't remove anything inside. Try using a crowbar.</span>"
|
||||
return 0
|
||||
if(!contents.len)
|
||||
user << "<span class='warning'>There's nothing inside this to remove!</span>"
|
||||
return 0
|
||||
var/obj/item/integrated_circuit/option = input("What do you want to remove?", "Component Removal") as null|anything in contents
|
||||
if(option)
|
||||
option.disconnect_all()
|
||||
option.forceMove(get_turf(src))
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
user << "<span class='notice'>You pop \the [option] out of the case, and slide it out.</span>"
|
||||
if(istype(I, /obj/item/weapon/crowbar))
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
opened = !opened
|
||||
user << "<span class='notice'>You [opened ? "opened" : "closed"] \the [src].</span>"
|
||||
update_icon()
|
||||
if(istype(I, /obj/item/device/integrated_electronics/wirer))
|
||||
if(opened)
|
||||
var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents
|
||||
if(IC)
|
||||
IC.examine(user)
|
||||
else
|
||||
user << "<span class='warning'>\The [src] isn't opened, so you can't fiddle with the internal components. \
|
||||
Try using a crowbar.</span>"
|
||||
|
||||
/obj/item/device/electronic_assembly/attack_self(mob/user)
|
||||
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/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs
|
||||
if(choice)
|
||||
choice.ask_for_input(user)
|
||||
|
||||
/obj/item/device/electronic_assembly/emp_act(severity)
|
||||
..()
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.emp_act(severity)
|
||||
133
code/modules/integrated_electronics/converters.dm
Normal file
133
code/modules/integrated_electronics/converters.dm
Normal file
@@ -0,0 +1,133 @@
|
||||
//These circuits convert one variable to another.
|
||||
/obj/item/integrated_circuit/converter
|
||||
complexity = 2
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"input",
|
||||
)
|
||||
output_names = list(
|
||||
"result"
|
||||
)
|
||||
activator_names = list(
|
||||
"convert"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/converter/num2text
|
||||
name = "number to string"
|
||||
desc = "This circuit can convert a number variable into a string."
|
||||
icon_state = "num-string"
|
||||
|
||||
/obj/item/integrated_circuit/converter/num2text/work()
|
||||
if(..())
|
||||
var/result = null
|
||||
var/datum/integrated_io/incoming = inputs[1]
|
||||
var/datum/integrated_io/outgoing = outputs[1]
|
||||
if(incoming.data && isnum(incoming.data))
|
||||
result = num2text(incoming.data)
|
||||
|
||||
outgoing.data = result
|
||||
outgoing.push_data()
|
||||
|
||||
/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"
|
||||
|
||||
/obj/item/integrated_circuit/converter/text2num/work()
|
||||
if(..())
|
||||
var/result = null
|
||||
var/datum/integrated_io/incoming = inputs[1]
|
||||
var/datum/integrated_io/outgoing = outputs[1]
|
||||
if(incoming.data && istext(incoming.data))
|
||||
result = text2num(incoming.data)
|
||||
|
||||
outgoing.data = result
|
||||
outgoing.push_data()
|
||||
|
||||
/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"
|
||||
|
||||
/obj/item/integrated_circuit/converter/ref2text/work()
|
||||
if(..())
|
||||
var/result = null
|
||||
var/datum/integrated_io/incoming = inputs[1]
|
||||
var/datum/integrated_io/outgoing = outputs[1]
|
||||
if(incoming.data && istype(incoming.data, /atom/))
|
||||
var/atom/A = incoming.data
|
||||
result = A.name
|
||||
|
||||
outgoing.data = result
|
||||
outgoing.push_data()
|
||||
|
||||
/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"
|
||||
|
||||
/obj/item/integrated_circuit/converter/lowercase/work()
|
||||
if(..())
|
||||
var/result = null
|
||||
var/datum/integrated_io/incoming = inputs[1]
|
||||
var/datum/integrated_io/outgoing = outputs[1]
|
||||
if(incoming.data && istext(incoming.data))
|
||||
result = lowertext(incoming.data)
|
||||
|
||||
outgoing.data = result
|
||||
outgoing.push_data()
|
||||
|
||||
/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"
|
||||
|
||||
/obj/item/integrated_circuit/converter/uppercase/work()
|
||||
if(..())
|
||||
var/result = null
|
||||
var/datum/integrated_io/incoming = inputs[1]
|
||||
var/datum/integrated_io/outgoing = outputs[1]
|
||||
if(incoming.data && istext(incoming.data))
|
||||
result = uppertext(incoming.data)
|
||||
|
||||
outgoing.data = result
|
||||
outgoing.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenatior
|
||||
name = "concatenatior"
|
||||
desc = "This joins many strings together to get one big string."
|
||||
complexity = 4
|
||||
number_of_inputs = 8
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D",
|
||||
"E",
|
||||
"F",
|
||||
"G",
|
||||
"H"
|
||||
)
|
||||
output_names = list(
|
||||
"result"
|
||||
)
|
||||
activator_names = list(
|
||||
"concatenate"
|
||||
)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/converter/concatenatior/work()
|
||||
if(..())
|
||||
var/result = null
|
||||
for(var/datum/integrated_io/input/I in inputs)
|
||||
I.pull_data()
|
||||
if(istext(I.data))
|
||||
result = result + I.data
|
||||
|
||||
var/datum/integrated_io/outgoing = outputs[1]
|
||||
outgoing.data = result
|
||||
outgoing.push_data()
|
||||
75
code/modules/integrated_electronics/coordinate.dm
Normal file
75
code/modules/integrated_electronics/coordinate.dm
Normal file
@@ -0,0 +1,75 @@
|
||||
//This circuit gives information on where the machine is.
|
||||
/obj/item/integrated_circuit/gps
|
||||
name = "global positioning system"
|
||||
desc = "This allows you to easily know the position of a machine containing this device."
|
||||
icon_state = "gps"
|
||||
complexity = 4
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 2
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
)
|
||||
output_names = list(
|
||||
"X (abs)",
|
||||
"Y (abs)"
|
||||
)
|
||||
activator_names = list(
|
||||
"get coordinates"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/gps/work()
|
||||
if(..())
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/integrated_io/result_x = outputs[1]
|
||||
var/datum/integrated_io/result_y = outputs[2]
|
||||
|
||||
result_x.data = null
|
||||
result_y.data = null
|
||||
if(!T)
|
||||
return
|
||||
|
||||
result_x.data = T.x
|
||||
result_y.data = T.y
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/abs_to_rel_coords
|
||||
name = "abs to rel coordinate converter"
|
||||
desc = "Easily convert absolute coordinates to relative coordinates with this."
|
||||
complexity = 4
|
||||
number_of_inputs = 4
|
||||
number_of_outputs = 2
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"X1 (abs)",
|
||||
"Y1 (abs)",
|
||||
"X2 (abs)",
|
||||
"Y2 (abs)"
|
||||
)
|
||||
output_names = list(
|
||||
"X (rel)",
|
||||
"Y (rel)"
|
||||
)
|
||||
activator_names = list(
|
||||
"compute rel coordinates"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/abs_to_rel_coords/work()
|
||||
var/datum/integrated_io/x1 = inputs[1]
|
||||
var/datum/integrated_io/y1 = inputs[2]
|
||||
|
||||
var/datum/integrated_io/x2 = inputs[3]
|
||||
var/datum/integrated_io/y2 = inputs[4]
|
||||
|
||||
var/datum/integrated_io/result_x = outputs[1]
|
||||
var/datum/integrated_io/result_y = outputs[2]
|
||||
|
||||
if(x1.data && y1.data && x2.data && y2.data)
|
||||
result_x.data = x1.data - x2.data
|
||||
result_y.data = y1.data - y2.data
|
||||
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
..()
|
||||
79
code/modules/integrated_electronics/data_transfer.dm
Normal file
79
code/modules/integrated_electronics/data_transfer.dm
Normal file
@@ -0,0 +1,79 @@
|
||||
/obj/item/integrated_circuit/transfer/splitter
|
||||
name = "splitter"
|
||||
desc = "Splits incoming data into all of the output pins."
|
||||
icon_state = "splitter"
|
||||
complexity = 3
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 2
|
||||
input_names = list(
|
||||
"data to split"
|
||||
)
|
||||
output_names = list(
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D",
|
||||
"E",
|
||||
"F",
|
||||
"G",
|
||||
"H"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/medium
|
||||
name = "four splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 5
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 4
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/large
|
||||
name = "eight splitter"
|
||||
icon_state = "splitter8"
|
||||
complexity = 9
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 8
|
||||
|
||||
/obj/item/integrated_circuit/transfer/splitter/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.data = I.data
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter
|
||||
name = "activator splitter"
|
||||
desc = "Splits incoming activation pulses into all of the output pins."
|
||||
icon_state = "splitter"
|
||||
complexity = 3
|
||||
number_of_activators = 3
|
||||
activator_names = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse A",
|
||||
"outgoing pulse B",
|
||||
"outgoing pulse C",
|
||||
"outgoing pulse D",
|
||||
"outgoing pulse E",
|
||||
"outgoing pulse F",
|
||||
"outgoing pulse G",
|
||||
"outgoing pulse H"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/work()
|
||||
if(..())
|
||||
for(var/datum/integrated_io/activate/A in outputs)
|
||||
if(A == activators[1])
|
||||
continue
|
||||
if(A.linked.len)
|
||||
for(var/datum/integrated_io/activate/target in A.linked)
|
||||
target.holder.work()
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/medium
|
||||
name = "four activator splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 5
|
||||
number_of_activators = 5
|
||||
|
||||
/obj/item/integrated_circuit/transfer/activator_splitter/large
|
||||
name = "eight activator splitter"
|
||||
icon_state = "splitter4"
|
||||
complexity = 9
|
||||
number_of_activators = 9
|
||||
494
code/modules/integrated_electronics/input_output.dm
Normal file
494
code/modules/integrated_electronics/input_output.dm
Normal file
@@ -0,0 +1,494 @@
|
||||
/obj/item/integrated_circuit/input
|
||||
var/can_be_asked_input = 0
|
||||
|
||||
/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"
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
complexity = 1
|
||||
can_be_asked_input = 1
|
||||
activator_names = list(
|
||||
"on pressed"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use.
|
||||
var/datum/integrated_io/A = activators[1]
|
||||
if(A.linked.len)
|
||||
for(var/datum/integrated_io/activate/target in A.linked)
|
||||
target.holder.work()
|
||||
user << "<span class='notice'>You press the button labeled '[src.name]'.</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"
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
output_names = list(
|
||||
"number entered"
|
||||
)
|
||||
activator_names = list(
|
||||
"on entered"
|
||||
)
|
||||
|
||||
/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))
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = new_input
|
||||
O.push_data()
|
||||
var/datum/integrated_io/A = activators[1]
|
||||
A.push_data()
|
||||
|
||||
/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"
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
output_names = list(
|
||||
"string entered"
|
||||
)
|
||||
activator_names = list(
|
||||
"on entered"
|
||||
)
|
||||
|
||||
/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(new_input && istext(new_input))
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = new_input
|
||||
O.push_data()
|
||||
var/datum/integrated_io/A = activators[1]
|
||||
A.push_data()
|
||||
|
||||
/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"
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 2
|
||||
number_of_activators = 1
|
||||
complexity = 4
|
||||
input_names = list(
|
||||
"target ref"
|
||||
)
|
||||
output_names = list(
|
||||
"total health %",
|
||||
"total missing health"
|
||||
)
|
||||
activator_names = list(
|
||||
"scan"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/input/med_scanner/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
if(!I.data || !ishuman(I.data)) //Invalid input
|
||||
return
|
||||
var/mob/living/carbon/human/H = I.data
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
var/total_health = round(H.health/H.maxHealth, 0.1)*100
|
||||
var/missing_health = H.maxHealth - H.health
|
||||
|
||||
var/datum/integrated_io/total = outputs[1]
|
||||
var/datum/integrated_io/missing = outputs[2]
|
||||
|
||||
total.data = total_health
|
||||
missing.data = missing_health
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/adv_med_scanner
|
||||
name = "integrated advanced medical analyser"
|
||||
desc = "A very small version of the common 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"
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 7
|
||||
number_of_activators = 1
|
||||
complexity = 12
|
||||
input_names = list(
|
||||
"target ref"
|
||||
)
|
||||
output_names = list(
|
||||
"total health %",
|
||||
"total missing health",
|
||||
"brute damage",
|
||||
"burn damage",
|
||||
"tox damage",
|
||||
"oxy damage",
|
||||
"clone damage"
|
||||
)
|
||||
activator_names = list(
|
||||
"scan"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/input/adv_med_scanner/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
if(!I.data || !ishuman(I.data)) //Invalid input
|
||||
return
|
||||
var/mob/living/carbon/human/H = I.data
|
||||
if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
|
||||
var/total_health = round(H.health/H.maxHealth, 0.1)*100
|
||||
var/missing_health = H.maxHealth - H.health
|
||||
|
||||
var/datum/integrated_io/total = outputs[1]
|
||||
var/datum/integrated_io/missing = outputs[2]
|
||||
var/datum/integrated_io/brute = outputs[3]
|
||||
var/datum/integrated_io/burn = outputs[4]
|
||||
var/datum/integrated_io/tox = outputs[5]
|
||||
var/datum/integrated_io/oxy = outputs[6]
|
||||
var/datum/integrated_io/clone = outputs[7]
|
||||
|
||||
total.data = total_health
|
||||
missing.data = missing_health
|
||||
brute.data = H.getBruteLoss()
|
||||
burn.data = H.getFireLoss()
|
||||
tox.data = H.getToxLoss()
|
||||
oxy.data = H.getOxyLoss()
|
||||
clone.data = H.getCloneLoss()
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
|
||||
/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."
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
complexity = 4
|
||||
output_names = list(
|
||||
"located ref"
|
||||
)
|
||||
activator_names = list(
|
||||
"locate"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/input/local_locator/work()
|
||||
if(..())
|
||||
var/mob/living/L = null
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
O.data = null
|
||||
if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine.
|
||||
var/obj/item/device/electronic_assembly/assembly = src.loc
|
||||
if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us.
|
||||
L = assembly.loc
|
||||
|
||||
if(L)
|
||||
O.data = L
|
||||
|
||||
O.push_data()
|
||||
|
||||
/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"
|
||||
number_of_inputs = 2
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 2
|
||||
complexity = 4
|
||||
input_names = list(
|
||||
"frequency",
|
||||
"code"
|
||||
)
|
||||
activator_names = list(
|
||||
"send signal",
|
||||
"on signal received"
|
||||
)
|
||||
var/frequency = 1457
|
||||
var/code = 30
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/New()
|
||||
..()
|
||||
spawn(4 SECONDS)
|
||||
set_frequency(frequency)
|
||||
var/datum/integrated_io/new_freq = inputs[1]
|
||||
var/datum/integrated_io/new_code = inputs[2]
|
||||
// Set the pins so when someone sees them, they won't show as null
|
||||
new_freq.data = frequency
|
||||
new_code.data = code
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/Destroy()
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src,frequency)
|
||||
frequency = 0
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/on_data_written()
|
||||
var/datum/integrated_io/new_freq = inputs[1]
|
||||
var/datum/integrated_io/new_code = inputs[2]
|
||||
if(isnum(new_freq.data))
|
||||
set_frequency(new_freq.data)
|
||||
if(isnum(new_code.data))
|
||||
code = new_code.data
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/work() // Sends a signal.
|
||||
if(..())
|
||||
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)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency)
|
||||
if(!frequency)
|
||||
return
|
||||
if(!radio_controller)
|
||||
sleep(20)
|
||||
if(!radio_controller)
|
||||
return
|
||||
radio_controller.remove_object(src, frequency)
|
||||
frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
|
||||
|
||||
/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal)
|
||||
var/datum/integrated_io/new_code = inputs[2]
|
||||
var/code = 0
|
||||
|
||||
if(isnum(new_code.data))
|
||||
code = new_code.data
|
||||
if(!signal)
|
||||
return 0
|
||||
if(signal.encryption != code)
|
||||
return 0
|
||||
if(signal.source == src) // Don't trigger ourselves.
|
||||
return 0
|
||||
|
||||
var/datum/integrated_io/A = activators[2]
|
||||
A.push_data()
|
||||
|
||||
for(var/mob/O in hearers(1, src.loc))
|
||||
O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2
|
||||
name = "\improper 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 activaiton pin \
|
||||
will pulse whatever's connected to it. Pulsing the first activation pin will send a message."
|
||||
icon_state = "signal"
|
||||
number_of_inputs = 3
|
||||
number_of_outputs = 3
|
||||
number_of_activators = 2
|
||||
complexity = 4
|
||||
input_names = list(
|
||||
"target EPv2 address",
|
||||
"data to send",
|
||||
"secondary text"
|
||||
)
|
||||
output_names = list(
|
||||
"address received",
|
||||
"data received",
|
||||
"secondary text received"
|
||||
)
|
||||
activator_names = list(
|
||||
"send data",
|
||||
"on data received"
|
||||
)
|
||||
var/datum/exonet_protocol/exonet = null
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/New()
|
||||
..()
|
||||
exonet = new(src)
|
||||
exonet.make_address("EPv2_circuit-\ref[src]")
|
||||
desc += "This circuit's EPv2 address is: [exonet.address]."
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/Destroy()
|
||||
if(exonet)
|
||||
exonet.remove_address()
|
||||
qdel(exonet)
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/input/EPv2/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/target_address = inputs[1]
|
||||
var/datum/integrated_io/message = inputs[2]
|
||||
var/datum/integrated_io/text = inputs[3]
|
||||
if(istext(target_address.data))
|
||||
exonet.send_message(target_address.data, message.data, text.data)
|
||||
|
||||
/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text)
|
||||
var/datum/integrated_io/message_received = outputs[1]
|
||||
var/datum/integrated_io/data_received = outputs[2]
|
||||
var/datum/integrated_io/text_received = outputs[3]
|
||||
|
||||
var/datum/integrated_io/A = activators[2]
|
||||
A.push_data()
|
||||
|
||||
message_received.write_data_to_pin(origin_address)
|
||||
data_received.write_data_to_pin(message)
|
||||
text_received.write_data_to_pin(text)
|
||||
|
||||
/obj/item/integrated_circuit/output/screen
|
||||
name = "screen"
|
||||
desc = "This small screen can display a single piece of data, when the machine is examined closely."
|
||||
icon_state = "screen"
|
||||
complexity = 4
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"displayed data"
|
||||
)
|
||||
activator_names = list(
|
||||
"load data"
|
||||
)
|
||||
var/stuff_to_display = null
|
||||
|
||||
/obj/item/integrated_circuit/output/screen/work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
stuff_to_display = I.data
|
||||
|
||||
/obj/item/integrated_circuit/output/light
|
||||
name = "light"
|
||||
desc = "This light can turn on and off on command."
|
||||
icon_state = "light_adv"
|
||||
// icon_state = "light"
|
||||
complexity = 4
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
activator_names = list(
|
||||
"toggle light"
|
||||
)
|
||||
var/light_toggled = 0
|
||||
var/light_brightness = 3
|
||||
var/light_rgb = "#FFFFFF"
|
||||
|
||||
/obj/item/integrated_circuit/output/light/work()
|
||||
if(..())
|
||||
light_toggled = !light_toggled
|
||||
update_lighting()
|
||||
|
||||
/obj/item/integrated_circuit/output/light/proc/update_lighting()
|
||||
if(light_toggled)
|
||||
set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/obj/item/integrated_circuit/output/light/advanced/update_lighting()
|
||||
var/datum/integrated_io/R = inputs[1]
|
||||
var/datum/integrated_io/G = inputs[2]
|
||||
var/datum/integrated_io/B = inputs[3]
|
||||
var/datum/integrated_io/brightness = inputs[4]
|
||||
|
||||
if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data))
|
||||
R.data = Clamp(R.data, 0, 255)
|
||||
G.data = Clamp(G.data, 0, 255)
|
||||
B.data = Clamp(B.data, 0, 255)
|
||||
brightness.data = Clamp(brightness.data, 0, 6)
|
||||
light_rgb = rgb(R.data, G.data, B.data)
|
||||
light_brightness = brightness.data
|
||||
|
||||
..()
|
||||
|
||||
/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
|
||||
number_of_inputs = 4
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"R",
|
||||
"G",
|
||||
"B",
|
||||
"Brightness"
|
||||
)
|
||||
|
||||
/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
|
||||
number_of_inputs = 3
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"sound ID",
|
||||
"volume",
|
||||
"frequency"
|
||||
)
|
||||
activator_names = list(
|
||||
"play sound"
|
||||
)
|
||||
var/list/sounds = list()
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/ID = inputs[1]
|
||||
var/datum/integrated_io/vol = inputs[2]
|
||||
var/datum/integrated_io/frequency = inputs[3]
|
||||
if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data))
|
||||
var/selected_sound = sounds[ID.data]
|
||||
vol.data = Clamp(vol.data, 0, 1)
|
||||
frequency.data = Clamp(frequency.data, 0, 100)
|
||||
playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1)
|
||||
|
||||
/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."
|
||||
extended_desc = "The first input pin determines what sound is used. The choices are; beep, chime, buzz sigh, buzz twice, ping, \
|
||||
synth yes, synth no, warning buzz. The second pin determines the volume of sound that is played, and the third determines if \
|
||||
the frequency of the sound will vary with each activation."
|
||||
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'
|
||||
)
|
||||
|
||||
/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."
|
||||
extended_desc = "The first input pin determines what sound is used. The choices are; creep, criminal, freeze, god, \
|
||||
i am the law, insult, radio, secure day. The second pin determines the volume of sound that is played, and the \
|
||||
third determines if the frequency of the sound will vary with each activation."
|
||||
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',
|
||||
)
|
||||
|
||||
172
code/modules/integrated_electronics/logic.dm
Normal file
172
code/modules/integrated_electronics/logic.dm
Normal file
@@ -0,0 +1,172 @@
|
||||
/obj/item/integrated_circuit/logic
|
||||
name = "logic gate"
|
||||
desc = "This tiny chip will decide for you!"
|
||||
complexity = 3
|
||||
number_of_inputs = 2
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 2
|
||||
input_names = list(
|
||||
"A",
|
||||
"B"
|
||||
)
|
||||
output_names = list(
|
||||
"result"
|
||||
)
|
||||
activator_names = list(
|
||||
"compare",
|
||||
"on true result"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/logic/equals
|
||||
name = "equal gate"
|
||||
desc = "This gate compares two values, and outputs the number one if both are the same."
|
||||
icon_state = "equal"
|
||||
|
||||
/obj/item/integrated_circuit/logic/equals/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data == B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/not
|
||||
name = "not gate"
|
||||
desc = "This gate inverts what's fed into it."
|
||||
icon_state = "not"
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
output_names = list(
|
||||
"invert"
|
||||
)
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/logic/not/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/A = inputs[1]
|
||||
var/datum/integrated_io/O = outputs[1]
|
||||
if(A.data)
|
||||
O.data = !A.data
|
||||
O.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/and
|
||||
name = "and gate"
|
||||
desc = "This gate will output 'one' if both inputs evaluate to true."
|
||||
icon_state = "and"
|
||||
|
||||
/obj/item/integrated_circuit/logic/and/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data && B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
A.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/or
|
||||
name = "or gate"
|
||||
desc = "This gate will output 'one' if one of the inputs evaluate to true."
|
||||
icon_state = "or"
|
||||
|
||||
/obj/item/integrated_circuit/logic/or/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data || B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
A.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/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"
|
||||
|
||||
/obj/item/integrated_circuit/logic/less_than/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data < B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
A.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/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"
|
||||
|
||||
/obj/item/integrated_circuit/logic/less_than_or_equal/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data <= B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
A.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/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"
|
||||
|
||||
/obj/item/integrated_circuit/logic/greater_than/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data > B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
A.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
|
||||
/obj/item/integrated_circuit/logic/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"
|
||||
|
||||
/obj/item/integrated_circuit/logic/greater_than_or_equal/work()
|
||||
if(..())
|
||||
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/P = activators[2]
|
||||
if(A.data >= B.data)
|
||||
O.data = 1
|
||||
O.push_data()
|
||||
A.push_data()
|
||||
P.push_data()
|
||||
else
|
||||
O.data = 0
|
||||
158
code/modules/integrated_electronics/manipulation.dm
Normal file
158
code/modules/integrated_electronics/manipulation.dm
Normal file
@@ -0,0 +1,158 @@
|
||||
/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 most ranged weapons, ballistic and energy. \
|
||||
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. Note that the \
|
||||
normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism."
|
||||
complexity = 20
|
||||
number_of_inputs = 2
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"target X rel",
|
||||
"target Y rel"
|
||||
)
|
||||
activator_names = list(
|
||||
"fire"
|
||||
)
|
||||
var/obj/item/weapon/gun/installed_gun = null
|
||||
|
||||
/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/weapon/gun))
|
||||
var/obj/item/weapon/gun/gun = O
|
||||
if(installed_gun)
|
||||
user << "<span class='warning'>There's already a weapon installed.</span>"
|
||||
return
|
||||
user.drop_from_inventory(gun)
|
||||
installed_gun = gun
|
||||
gun.forceMove(src)
|
||||
user << "<span class='notice'>You slide \the [gun] into the firing mechanism.</span>"
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user)
|
||||
if(installed_gun)
|
||||
installed_gun.forceMove(get_turf(src))
|
||||
user << "<span class='notice'>You slide \the [installed_gun] out of the firing mechanism.</span>"
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
|
||||
installed_gun = null
|
||||
else
|
||||
user << "<span class='notice'>There's no weapon to remove from the mechanism.</span>"
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/weapon_firing/work()
|
||||
if(..())
|
||||
if(!installed_gun)
|
||||
return
|
||||
|
||||
var/datum/integrated_io/target_x = inputs[1]
|
||||
var/datum/integrated_io/target_y = inputs[2]
|
||||
|
||||
if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data))
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves.
|
||||
return
|
||||
|
||||
// We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates.
|
||||
var/i
|
||||
if(target_x.data > 0)
|
||||
i = abs(target_x.data)
|
||||
while(i)
|
||||
T = get_step(T, EAST)
|
||||
i--
|
||||
else if(target_x.data < 0)
|
||||
i = abs(target_x.data)
|
||||
while(i)
|
||||
T = get_step(T, WEST)
|
||||
i--
|
||||
|
||||
if(target_y.data > 0)
|
||||
i = abs(target_y.data)
|
||||
while(i)
|
||||
T = get_step(T, NORTH)
|
||||
i--
|
||||
else if(target_y.data < 0)
|
||||
i = abs(target_y.data)
|
||||
while(i)
|
||||
T = get_step(T, SOUTH)
|
||||
i--
|
||||
|
||||
if(!T)
|
||||
return
|
||||
installed_gun.Fire_userless(T)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/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."
|
||||
flags = OPENCONTAINER
|
||||
complexity = 20
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
cooldown_per_use = 30 SECONDS
|
||||
input_names = list()
|
||||
activator_names = list(
|
||||
"create smoke"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/smoke/New()
|
||||
..()
|
||||
create_reagents(100)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/smoke/work()
|
||||
if(..())
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new()
|
||||
smoke_system.set_up(reagents, 10, 0, get_turf(src))
|
||||
spawn(0)
|
||||
for(var/i = 1 to 8)
|
||||
smoke_system.start()
|
||||
reagents.clear_reagents()
|
||||
|
||||
/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 number as a direction to move towards.<br> \
|
||||
North/Fore = 1,<br>\
|
||||
South/Aft = 2,<br>\
|
||||
East/Starboard = 4,<br>\
|
||||
West/Port = 8,<br>\
|
||||
Northeast = 5,<br>\
|
||||
Northwest = 9,<br>\
|
||||
Southeast = 6,<br>\
|
||||
Southwest = 10<br>\
|
||||
<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."
|
||||
complexity = 20
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 0
|
||||
number_of_activators = 1
|
||||
input_names = list(
|
||||
"dir num"
|
||||
)
|
||||
activator_names = list(
|
||||
"step towards dir"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/locomotion/work()
|
||||
if(..())
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(loc, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/machine = loc
|
||||
if(machine.anchored || machine.w_class >= 4)
|
||||
return
|
||||
if(machine.loc && machine.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))
|
||||
step(machine, wanted_dir.data)
|
||||
101
code/modules/integrated_electronics/memory.dm
Normal file
101
code/modules/integrated_electronics/memory.dm
Normal file
@@ -0,0 +1,101 @@
|
||||
/obj/item/integrated_circuit/memory
|
||||
name = "memory chip"
|
||||
desc = "This tiny chip can store one piece of data."
|
||||
icon_state = "memory"
|
||||
complexity = 1
|
||||
number_of_inputs = 1
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
activator_names = list(
|
||||
"set"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/memory/examine(mob/user)
|
||||
..()
|
||||
var/i
|
||||
for(i = 1, i <= outputs.len, i++)
|
||||
var/datum/integrated_io/O = outputs[i]
|
||||
user << "\The [src] has [O.data ? "'O.data'" : "nothing"] saved to address [i]."
|
||||
|
||||
/obj/item/integrated_circuit/memory/work()
|
||||
if(..())
|
||||
var/i
|
||||
for(i = 1, i <= inputs.len, i++)
|
||||
var/datum/integrated_io/I = inputs[i]
|
||||
var/datum/integrated_io/O = outputs[i]
|
||||
O.data = I.data
|
||||
|
||||
/obj/item/integrated_circuit/memory/medium
|
||||
name = "memory circuit"
|
||||
desc = "This circuit can store four pieces of data."
|
||||
icon_state = "memory4"
|
||||
complexity = 4
|
||||
number_of_inputs = 4
|
||||
number_of_outputs = 4
|
||||
|
||||
/obj/item/integrated_circuit/memory/large
|
||||
name = "large memory circuit"
|
||||
desc = "This big circuit can hold eight pieces of data."
|
||||
icon_state = "memory8"
|
||||
complexity = 8
|
||||
number_of_inputs = 8
|
||||
number_of_outputs = 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"
|
||||
complexity = 16
|
||||
number_of_inputs = 16
|
||||
number_of_outputs = 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"
|
||||
complexity = 1
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 1
|
||||
number_of_activators = 1
|
||||
activator_names = list(
|
||||
"push data"
|
||||
)
|
||||
var/accepting_refs = 0
|
||||
|
||||
/obj/item/integrated_circuit/memory/constant/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]
|
||||
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 = 0
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data))
|
||||
O.data = new_data
|
||||
user << "<span class='notice'>You set \the [src]'s memory to [O.display_data()].</span>"
|
||||
if("number")
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data))
|
||||
O.data = new_data
|
||||
user << "<span class='notice'>You set \the [src]'s memory to [O.display_data()].</span>"
|
||||
if("ref")
|
||||
accepting_refs = 1
|
||||
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
|
||||
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 = target
|
||||
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
|
||||
user << "<span class='notice'>You set \the [src]'s memory to a reference to [O.display_data()]. The ref scanner is \
|
||||
now off.</span>"
|
||||
accepting_refs = 0
|
||||
144
code/modules/integrated_electronics/time.dm
Normal file
144
code/modules/integrated_electronics/time.dm
Normal file
@@ -0,0 +1,144 @@
|
||||
/obj/item/integrated_circuit/time
|
||||
name = "time circuit"
|
||||
desc = "Now you can build your own clock!"
|
||||
complexity = 2
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 0
|
||||
|
||||
/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"
|
||||
number_of_activators = 2
|
||||
var/delay = 20
|
||||
activator_names = list(
|
||||
"incoming pulse",
|
||||
"outgoing pulse"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/out_pulse = activators[2]
|
||||
sleep(delay)
|
||||
out_pulse.push_data()
|
||||
|
||||
/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
|
||||
|
||||
/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
|
||||
|
||||
/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
|
||||
|
||||
/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
|
||||
|
||||
/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"
|
||||
number_of_inputs = 1
|
||||
input_names = list(
|
||||
"delay time",
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/time/delay/custom/work()
|
||||
var/datum/integrated_io/delay_input = inputs[1]
|
||||
if(delay_input.data && isnum(delay_input.data) )
|
||||
var/new_delay = min(delay_input.data, 1)
|
||||
new_delay = max(new_delay, 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
|
||||
number_of_inputs = 1
|
||||
number_of_activators = 1
|
||||
var/ticks_to_pulse = 2
|
||||
var/ticks_completed = 0
|
||||
input_names = list(
|
||||
"toggle ticking"
|
||||
)
|
||||
activator_names = list(
|
||||
"outgoing pulse"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/New()
|
||||
..()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/Destroy()
|
||||
processing_objects -= src
|
||||
|
||||
/obj/item/integrated_circuit/time/ticker/process()
|
||||
ticks_completed++
|
||||
if( (ticks_completed % ticks_to_pulse) == 0)
|
||||
var/datum/integrated_io/pulser = activators[1]
|
||||
pulser.push_data()
|
||||
|
||||
/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
|
||||
ticks_to_pulse = 1
|
||||
|
||||
/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
|
||||
ticks_to_pulse = 3
|
||||
|
||||
|
||||
/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"
|
||||
number_of_inputs = 0
|
||||
number_of_outputs = 4
|
||||
number_of_activators = 1
|
||||
output_names = list(
|
||||
"time (string)",
|
||||
"hours (number)",
|
||||
"minutes (number)",
|
||||
"seconds (number)"
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/time/clock/work()
|
||||
if(..())
|
||||
var/datum/integrated_io/time = outputs[1]
|
||||
var/datum/integrated_io/hour = outputs[2]
|
||||
var/datum/integrated_io/min = outputs[3]
|
||||
var/datum/integrated_io/sec = outputs[4]
|
||||
|
||||
time.data = time2text(station_time_in_ticks, "hh:mm:ss")
|
||||
hour.data = text2num(time2text(station_time_in_ticks, "hh"))
|
||||
min.data = text2num(time2text(station_time_in_ticks, "mm"))
|
||||
sec.data = text2num(time2text(station_time_in_ticks, "ss"))
|
||||
|
||||
for(var/datum/integrated_io/output/O in outputs)
|
||||
O.push_data()
|
||||
227
code/modules/integrated_electronics/tools.dm
Normal file
227
code/modules/integrated_electronics/tools.dm
Normal file
@@ -0,0 +1,227 @@
|
||||
#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 = CONDUCT
|
||||
w_class = 2
|
||||
var/datum/integrated_io/selected_io = null
|
||||
var/mode = WIRE
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/New()
|
||||
..()
|
||||
|
||||
/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(mode == WIRE)
|
||||
selected_io = io
|
||||
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)
|
||||
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)
|
||||
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
|
||||
selected_io.linked |= io
|
||||
io.linked |= selected_io
|
||||
|
||||
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()
|
||||
//io.updateDialog()
|
||||
//selected_io.updateDialog()
|
||||
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)
|
||||
user << "<span class='warning'>There is nothing connected to \the [selected_io] data channel.</span>"
|
||||
selected_io = null
|
||||
return
|
||||
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)
|
||||
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)
|
||||
user << "<span class='notice'>You disconnect \the [selected_io.holder]'s [selected_io.name] from \
|
||||
\the [io.holder]'s [io.name].</span>"
|
||||
//io.updateDialog()
|
||||
//selected_io.updateDialog()
|
||||
selected_io.holder.interact(user) // This is to update the UI.
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
update_icon()
|
||||
else
|
||||
user << "<span class='warning'>\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \
|
||||
[io.name] are not connected.</span>"
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/device/integrated_electronics/wirer/attack_self(mob/user)
|
||||
switch(mode)
|
||||
if(WIRE)
|
||||
mode = UNWIRE
|
||||
if(WIRING)
|
||||
if(selected_io)
|
||||
user << "<span class='notice'>You decide not to wire the data channel.</span>"
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
if(UNWIRE)
|
||||
mode = WIRE
|
||||
if(UNWIRING)
|
||||
if(selected_io)
|
||||
user << "<span class='notice'>You decide not to disconnect the data channel.</span>"
|
||||
selected_io = null
|
||||
mode = UNWIRE
|
||||
update_icon()
|
||||
user << "<span class='notice'>You set \the [src] to [mode].</span>"
|
||||
|
||||
#undef WIRE
|
||||
#undef WIRING
|
||||
#undef UNWIRE
|
||||
#undef UNWIRING
|
||||
|
||||
/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 = CONDUCT
|
||||
w_class = 2
|
||||
var/data_to_write = null
|
||||
var/accepting_refs = 0
|
||||
|
||||
/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")
|
||||
var/new_data = null
|
||||
switch(type_to_use)
|
||||
if("string")
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a string.","[src] string writing") as null|text
|
||||
if(istext(new_data))
|
||||
data_to_write = new_data
|
||||
user << "<span class='notice'>You set \the [src]'s memory to \"[new_data]\".</span>"
|
||||
if("number")
|
||||
accepting_refs = 0
|
||||
new_data = input("Now type in a number.","[src] number writing") as null|num
|
||||
if(isnum(new_data))
|
||||
data_to_write = new_data
|
||||
user << "<span class='notice'>You set \the [src]'s memory to [new_data].</span>"
|
||||
if("ref")
|
||||
accepting_refs = 1
|
||||
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
|
||||
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 = target
|
||||
visible_message("<span class='notice'>[user] slides \a [src]'s over \the [target].</span>")
|
||||
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 = 0
|
||||
|
||||
/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)
|
||||
user << "<span class='notice'>You write [data_to_write] to \the [io.holder]'s [io].</span>"
|
||||
else if(io.io_type == PULSE_CHANNEL)
|
||||
io.holder.work()
|
||||
user << "<span class='notice'>You pulse \the [io.holder]'s [io].</span>"
|
||||
|
||||
io.holder.interact(user) // This is to update the UI.
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits
|
||||
name = "circuit kit"
|
||||
desc = "This kit's essential for any circuitry projects."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon_state = "circuit_kit"
|
||||
w_class = 3
|
||||
storage_slots = 200
|
||||
max_storage_space = 400
|
||||
max_w_class = 3
|
||||
display_contents_with_number = 1
|
||||
can_hold = list(/obj/item/integrated_circuit, /obj/item/device/integrated_electronics, /obj/item/device/electronic_assembly,
|
||||
/obj/item/weapon/screwdriver, /obj/item/weapon/crowbar)
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/basic/New()
|
||||
..()
|
||||
var/list/types_to_spawn = typesof(/obj/item/integrated_circuit/arithmetic,
|
||||
/obj/item/integrated_circuit/logic,
|
||||
/obj/item/integrated_circuit/memory,
|
||||
) - list(/obj/item/integrated_circuit/arithmetic,
|
||||
/obj/item/integrated_circuit/memory,
|
||||
/obj/item/integrated_circuit/logic,
|
||||
)
|
||||
|
||||
types_to_spawn.Add(/obj/item/integrated_circuit/input/numberpad,
|
||||
/obj/item/integrated_circuit/input/textpad,
|
||||
/obj/item/integrated_circuit/input/button,
|
||||
/obj/item/integrated_circuit/input/signaler,
|
||||
/obj/item/integrated_circuit/input/local_locator,
|
||||
/obj/item/integrated_circuit/output/screen,
|
||||
/obj/item/integrated_circuit/converter/num2text,
|
||||
/obj/item/integrated_circuit/converter/text2num,
|
||||
/obj/item/integrated_circuit/converter/uppercase,
|
||||
/obj/item/integrated_circuit/converter/lowercase,
|
||||
/obj/item/integrated_circuit/time/delay/five_sec,
|
||||
/obj/item/integrated_circuit/time/delay/one_sec,
|
||||
/obj/item/integrated_circuit/time/delay/half_sec,
|
||||
/obj/item/integrated_circuit/time/delay/tenth_sec,
|
||||
/obj/item/integrated_circuit/time/ticker/slow,
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
)
|
||||
|
||||
for(var/thing in types_to_spawn)
|
||||
var/i = 3
|
||||
while(i)
|
||||
new thing(src)
|
||||
i--
|
||||
|
||||
new /obj/item/device/electronic_assembly(src)
|
||||
new /obj/item/device/integrated_electronics/wirer(src)
|
||||
new /obj/item/device/integrated_electronics/debugger(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits/all/New()
|
||||
..()
|
||||
var/list/types_to_spawn = typesof(/obj/item/integrated_circuit)
|
||||
|
||||
for(var/thing in types_to_spawn)
|
||||
var/i = 10
|
||||
while(i)
|
||||
new thing(src)
|
||||
i--
|
||||
|
||||
new /obj/item/device/electronic_assembly(src)
|
||||
new /obj/item/device/integrated_electronics/wirer(src)
|
||||
new /obj/item/device/integrated_electronics/debugger(src)
|
||||
new /obj/item/weapon/crowbar(src)
|
||||
new /obj/item/weapon/screwdriver(src)
|
||||
Reference in New Issue
Block a user