mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-30 03:52:52 +00:00
Circuits Update One (#6852)
Ports a buuuuunch of circuits from Polaris. Allows metabolic siphons and internal energy siphons to consume power to feed their host. Ports /tg/ circuits too while I'm at it. Increases base size and complexity for circuits. You're all adults. Hopefully. Don't abuse it. Ports the integrated circuit detailer.
This commit is contained in:
@@ -43,7 +43,7 @@
|
||||
/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 = 'icons/obj/assemblies/electronic_components.dmi'
|
||||
icon_state = "template"
|
||||
w_class = ITEMSIZE_TINY
|
||||
var/obj/item/device/electronic_assembly/assembly // Reference to the assembly holding this circuit, if any.
|
||||
|
||||
@@ -1,40 +1,19 @@
|
||||
#define IC_COMPONENTS_BASE 20
|
||||
#define IC_COMPLEXITY_BASE 60
|
||||
#define IC_COMPONENTS_BASE 25
|
||||
#define IC_COMPLEXITY_BASE 75
|
||||
|
||||
/obj/item/device/electronic_assembly
|
||||
name = "electronic assembly"
|
||||
desc = "It's a case, for building small electronics with."
|
||||
w_class = ITEMSIZE_SMALL
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon = 'icons/obj/assemblies/electronic_setups.dmi'
|
||||
icon_state = "setup_small"
|
||||
var/max_components = IC_COMPONENTS_BASE
|
||||
var/max_complexity = IC_COMPLEXITY_BASE
|
||||
var/opened = 0
|
||||
var/can_anchor = FALSE // If true, wrenching it will anchor it.
|
||||
var/obj/item/weapon/cell/device/battery // Internal cell which most circuits need to work.
|
||||
|
||||
/obj/item/device/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
icon_state = "setup_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with."
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
|
||||
/obj/item/device/electronic_assembly/large
|
||||
name = "electronic machine"
|
||||
icon_state = "setup_large"
|
||||
desc = "It's a case, for building large electronics with."
|
||||
w_class = ITEMSIZE_LARGE
|
||||
max_components = IC_COMPONENTS_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
icon_state = "setup_drone"
|
||||
desc = "It's a case, for building mobile electronics with."
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 1.5
|
||||
max_complexity = IC_COMPLEXITY_BASE * 1.5
|
||||
var/detail_color = COLOR_ASSEMBLY_BLACK
|
||||
var/obj/item/weapon/card/id/access_card
|
||||
|
||||
/obj/item/device/electronic_assembly/implant
|
||||
name = "electronic implant"
|
||||
@@ -50,12 +29,22 @@
|
||||
if (!printed)
|
||||
battery = new(src)
|
||||
START_PROCESSING(SSelectronics, src)
|
||||
access_card = new /obj/item/weapon/card/id(src)
|
||||
|
||||
/obj/item/device/electronic_assembly/Destroy()
|
||||
QDEL_NULL(battery)
|
||||
STOP_PROCESSING(SSelectronics, src)
|
||||
QDEL_NULL(access_card)
|
||||
return ..()
|
||||
|
||||
/obj/item/device/electronic_assembly/Collide(atom/AM)
|
||||
var/collw = AM
|
||||
.=..()
|
||||
if((istype(collw, /obj/machinery/door/airlock) || istype(collw, /obj/machinery/door/window)) && (!isnull(access_card)))
|
||||
var/obj/machinery/door/D = collw
|
||||
if(D.check_access(access_card))
|
||||
D.open()
|
||||
|
||||
/obj/item/device/electronic_assembly/process()
|
||||
handle_idle_power()
|
||||
|
||||
@@ -175,14 +164,17 @@
|
||||
/obj/item/device/electronic_assembly/proc/can_move()
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/can_move()
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/update_icon()
|
||||
if(opened)
|
||||
icon_state = "[initial(icon_state)]-open"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
cut_overlays()
|
||||
if(detail_color == COLOR_ASSEMBLY_BLACK) //Black colored overlay looks almost but not exactly like the base sprite, so just cut the overlay and avoid it looking kinda off.
|
||||
return
|
||||
var/image/detail_overlay = image('icons/obj/assemblies/electronic_setups.dmi', "[icon_state]-color")
|
||||
detail_overlay.color = detail_color
|
||||
add_overlay(detail_overlay)
|
||||
|
||||
/obj/item/device/electronic_assembly/GetAccess()
|
||||
. = list()
|
||||
@@ -234,14 +226,18 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
// Non-interactive version of above that always succeeds, intended for build-in circuits that get added on assembly initialization.
|
||||
/obj/item/device/electronic_assembly/proc/force_add_circuit(var/obj/item/integrated_circuit/IC)
|
||||
IC.forceMove(src)
|
||||
IC.assembly = src
|
||||
|
||||
/obj/item/device/electronic_assembly/afterattack(atom/target, mob/user, proximity)
|
||||
if(proximity)
|
||||
var/scanned = FALSE
|
||||
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
|
||||
if(S.scan(target))
|
||||
scanned = TRUE
|
||||
if(scanned)
|
||||
visible_message("<span class='notice'>\The [user] waves \the [src] around [target].</span>")
|
||||
var/scanned = FALSE
|
||||
for(var/obj/item/integrated_circuit/input/sensor/S in contents)
|
||||
if(S.sense(target))
|
||||
scanned = TRUE
|
||||
if(scanned)
|
||||
visible_message("<span class='notice'>\The [user] waves \the [src] around [target].</span>")
|
||||
|
||||
/obj/item/device/electronic_assembly/attackby(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/integrated_circuit))
|
||||
@@ -254,7 +250,17 @@
|
||||
interact(user)
|
||||
return TRUE
|
||||
|
||||
else if(istype(I, /obj/item/weapon/crowbar))
|
||||
else if(I.iswrench() && can_anchor)
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
anchored = !anchored
|
||||
if(anchored)
|
||||
on_anchored()
|
||||
else
|
||||
on_unanchored()
|
||||
user.visible_message("[user] has wrenched [src]'s anchoring bolts [anchored ? "into" : "out of"] place.", "You wrench [src]'s anchoring bolts [anchored ? "into" : "out of"] place.", "You hear the sound of a ratcheting wrench turning.")
|
||||
return TRUE
|
||||
|
||||
else if(I.iscrowbar())
|
||||
playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
|
||||
opened = !opened
|
||||
to_chat(user, "<span class='notice'>You [opened ? "open" : "close"] \the [src].</span>")
|
||||
@@ -271,10 +277,14 @@
|
||||
else if(istype(I, /obj/item/weapon/cell/device))
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='warning'>\The [src] isn't open, so you can't put anything inside. Try using a crowbar.</span>")
|
||||
for(var/obj/item/integrated_circuit/input/S in contents)
|
||||
S.attackby_react(I,user,user.a_intent)
|
||||
return FALSE
|
||||
|
||||
if(battery)
|
||||
to_chat(user, "<span class='warning'>\The [src] already has \a [battery] inside. Remove it first if you want to replace it.</span>")
|
||||
for(var/obj/item/integrated_circuit/input/S in contents)
|
||||
S.attackby_react(I,user,user.a_intent)
|
||||
return FALSE
|
||||
|
||||
var/obj/item/weapon/cell/device/cell = I
|
||||
@@ -284,12 +294,18 @@
|
||||
to_chat(user, "<span class='notice'>You slot \the [cell] inside \the [src]'s power supply.</span>")
|
||||
interact(user)
|
||||
return TRUE
|
||||
else if(istype(I, /obj/item/device/integrated_electronics/detailer))
|
||||
var/obj/item/device/integrated_electronics/detailer/D = I
|
||||
detail_color = D.detail_color
|
||||
update_icon()
|
||||
|
||||
else //Attempt to insert the item into any contained insert_slots
|
||||
for(var/obj/item/integrated_circuit/insert_slot/S in contents)
|
||||
else
|
||||
for(var/obj/item/integrated_circuit/insert_slot/S in contents) //Attempt to insert the item into any contained insert_slots
|
||||
if(S.insert(I, user))
|
||||
return TRUE
|
||||
|
||||
for(var/obj/item/integrated_circuit/input/S in contents) // Attempt to swipe on scanners
|
||||
if(S.attackby_react(I,user,user.a_intent))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/device/electronic_assembly/attack_self(mob/user)
|
||||
@@ -338,3 +354,11 @@
|
||||
if(battery && battery.give(amount * CELLRATE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/on_anchored()
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.on_anchored()
|
||||
|
||||
/obj/item/device/electronic_assembly/proc/on_unanchored()
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
IC.on_unanchored()
|
||||
192
code/modules/integrated_electronics/core/assemblies/clothing.dm
Normal file
192
code/modules/integrated_electronics/core/assemblies/clothing.dm
Normal file
@@ -0,0 +1,192 @@
|
||||
|
||||
// The base subtype for assemblies that can be worn. Certain pieces will have more or less capabilities
|
||||
// E.g. Glasses have less room than something worn over the chest.
|
||||
// Note that the electronic assembly is INSIDE the object that actually gets worn, in a similar way to implants.
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing
|
||||
name = "electronic clothing"
|
||||
icon_state = "circuitry" // Needs to match the clothing's base icon_state.
|
||||
desc = "It's a case, for building machines attached to clothing."
|
||||
w_class = ITEMSIZE_SMALL
|
||||
max_components = IC_COMPONENTS_BASE
|
||||
max_complexity = IC_COMPLEXITY_BASE
|
||||
var/obj/item/clothing/clothing = null
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing/ui_host()
|
||||
return clothing
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing/resolve_ui_host()
|
||||
return clothing
|
||||
|
||||
/obj/item/device/electronic_assembly/clothing/update_icon()
|
||||
..()
|
||||
clothing.icon_state = icon_state
|
||||
// We don't need to update the mob sprite since it won't (and shouldn't) actually get changed.
|
||||
|
||||
// This is 'small' relative to the size of regular clothing assemblies.
|
||||
/obj/item/device/electronic_assembly/clothing/small
|
||||
max_components = IC_COMPONENTS_BASE / 2
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
// Ditto.
|
||||
/obj/item/device/electronic_assembly/clothing/large
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
|
||||
|
||||
// This is defined higher up, in /clothing to avoid lots of copypasta.
|
||||
/obj/item/clothing
|
||||
var/obj/item/device/electronic_assembly/clothing/IC = null
|
||||
var/obj/item/integrated_circuit/built_in/action_button/action_circuit = null // This gets pulsed when someone clicks the button on the hud, OR when certain interactions are performed (such as clicking on something with gloves worn)
|
||||
|
||||
/obj/item/clothing/emp_act(severity)
|
||||
if(IC)
|
||||
IC.emp_act(severity)
|
||||
..()
|
||||
|
||||
/obj/item/clothing/examine(mob/user)
|
||||
if(IC)
|
||||
IC.examine(user)
|
||||
..()
|
||||
|
||||
/obj/item/clothing/attackby(obj/item/I, mob/user)
|
||||
if(IC)
|
||||
// This needs to be done in a better way...
|
||||
if(I.iscrowbar() || I.isscrewdriver() || istype(I, /obj/item/integrated_circuit) || istype(I, /obj/item/weapon/cell) || istype(I, /obj/item/device/integrated_electronics))
|
||||
IC.attackby(I, user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/clothing/attack_self(mob/user)
|
||||
if(IC)
|
||||
if(IC.opened)
|
||||
IC.attack_self(user)
|
||||
else
|
||||
action_circuit.do_work()
|
||||
else
|
||||
..()
|
||||
|
||||
// Does most of the repeatative setup.
|
||||
/obj/item/clothing/proc/setup_integrated_circuit(new_type)
|
||||
// Set up the internal circuit holder.
|
||||
IC = new new_type(src)
|
||||
IC.clothing = src
|
||||
IC.name = name
|
||||
|
||||
// Clothing assemblies can be triggered by clicking on the HUD. This allows that to occur.
|
||||
action_circuit = new(src.IC)
|
||||
IC.force_add_circuit(action_circuit)
|
||||
action_button_name = "Activate [name]"
|
||||
|
||||
/obj/item/clothing/Destroy()
|
||||
if(IC)
|
||||
IC.clothing = null
|
||||
action_circuit = null // Will get deleted by qdel-ing the IC assembly.
|
||||
qdel(IC)
|
||||
return ..()
|
||||
|
||||
// Specific subtypes.
|
||||
|
||||
// Jumpsuit.
|
||||
/obj/item/clothing/under/circuitry
|
||||
name = "electronic jumpsuit"
|
||||
desc = "It's a wearable case for electronics. This on is a black jumpsuit with wiring weaved into the fabric."
|
||||
icon_state = "circuitry"
|
||||
worn_state = "circuitry"
|
||||
|
||||
/obj/item/clothing/under/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing)
|
||||
return ..()
|
||||
|
||||
|
||||
// Gloves.
|
||||
/obj/item/clothing/gloves/circuitry
|
||||
name = "electronic gloves"
|
||||
desc = "It's a wearable case for electronics. This one is a pair of black gloves, with wires woven into them. A small \
|
||||
device with a screen is attached to the left glove."
|
||||
icon_state = "circuitry"
|
||||
item_state = "circuitry"
|
||||
|
||||
/obj/item/clothing/gloves/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/gloves/circuitry/Touch(var/atom/A, var/mob/user, var/proximity)
|
||||
if(!A || !proximity)
|
||||
return 0
|
||||
|
||||
if(istype(action_circuit) && action_circuit.check_then_do_work())
|
||||
action_circuit.set_pin_data(IC_OUTPUT, 1, A)
|
||||
action_circuit.push_data() // we have to not return 1 so we can still do normal stuff like picking things up, etc.
|
||||
return 0
|
||||
|
||||
// Glasses.
|
||||
/obj/item/clothing/glasses/circuitry
|
||||
name = "electronic goggles"
|
||||
desc = "It's a wearable case for electronics. This one is a pair of goggles, with wiring sticking out. \
|
||||
Could this augment your vision?" // Sadly it won't, or at least not yet.
|
||||
icon_state = "circuitry"
|
||||
item_state = "night" // The on-mob sprite would be identical anyways.
|
||||
|
||||
/obj/item/clothing/glasses/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/glasses/circuitry/Look(var/atom/A, mob/user, var/proximity)
|
||||
if(!A)
|
||||
return 0
|
||||
|
||||
if(istype(action_circuit) && action_circuit.check_then_do_work())
|
||||
action_circuit.set_pin_data(IC_OUTPUT, 1, A)
|
||||
action_circuit.push_data() // we have to not return 1 so we can still do normal stuff like picking things up, etc.
|
||||
return 0
|
||||
|
||||
// Shoes
|
||||
/obj/item/clothing/shoes/circuitry
|
||||
name = "electronic boots"
|
||||
desc = "It's a wearable case for electronics. This one is a pair of boots, with wires attached to a small \
|
||||
cover."
|
||||
icon_state = "circuitry"
|
||||
item_state = "circuitry"
|
||||
|
||||
/obj/item/clothing/shoes/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small)
|
||||
return ..()
|
||||
|
||||
// Head
|
||||
/obj/item/clothing/head/circuitry
|
||||
name = "electronic headwear"
|
||||
desc = "It's a wearable case for electronics. This one appears to be a very technical-looking piece that \
|
||||
goes around the collar, with a heads-up-display attached on the right."
|
||||
icon_state = "circuitry"
|
||||
item_state = "circuitry"
|
||||
|
||||
/obj/item/clothing/head/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small)
|
||||
return ..()
|
||||
|
||||
// Ear
|
||||
/obj/item/clothing/ears/circuitry
|
||||
name = "electronic earwear"
|
||||
desc = "It's a wearable case for electronics. This one appears to be a technical-looking headset."
|
||||
icon = 'icons/obj/clothing/ears.dmi'
|
||||
icon_state = "circuitry"
|
||||
item_state = "circuitry"
|
||||
|
||||
/obj/item/clothing/ears/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/small)
|
||||
return ..()
|
||||
|
||||
// Exo-slot
|
||||
/obj/item/clothing/suit/circuitry
|
||||
name = "electronic chestpiece"
|
||||
desc = "It's a wearable case for electronics. This one appears to be a very technical-looking vest, that \
|
||||
almost looks professionally made, however the wiring popping out betrays that idea."
|
||||
icon_state = "circuitry"
|
||||
item_state = "circuitry"
|
||||
|
||||
/obj/item/clothing/suit/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/device/electronic_assembly/clothing/large)
|
||||
return ..()
|
||||
255
code/modules/integrated_electronics/core/assemblies/generic.dm
Normal file
255
code/modules/integrated_electronics/core/assemblies/generic.dm
Normal file
@@ -0,0 +1,255 @@
|
||||
// Generic subtypes without a lot of special code.
|
||||
|
||||
// Small assemblies.
|
||||
|
||||
/obj/item/device/electronic_assembly/default
|
||||
name = "type-a electronic assembly"
|
||||
|
||||
/obj/item/device/electronic_assembly/calc
|
||||
name = "type-b electronic assembly"
|
||||
icon_state = "setup_small_calc"
|
||||
desc = "It's a case, for building small electronics with. This one resembles a pocket calculator."
|
||||
|
||||
/obj/item/device/electronic_assembly/clam
|
||||
name = "type-c electronic assembly"
|
||||
icon_state = "setup_small_clam"
|
||||
desc = "It's a case, for building small electronics with. This one has a clamshell design."
|
||||
|
||||
/obj/item/device/electronic_assembly/simple
|
||||
name = "type-d electronic assembly"
|
||||
icon_state = "setup_small_simple"
|
||||
desc = "It's a case, for building small electronics with. This one has a simple design."
|
||||
|
||||
/obj/item/device/electronic_assembly/hook
|
||||
name = "type-e electronic assembly"
|
||||
icon_state = "setup_small_hook"
|
||||
desc = "It's a case, for building small electronics with. This one looks like it has a belt clip, but it's purely decorative."
|
||||
|
||||
/obj/item/device/electronic_assembly/pda
|
||||
name = "type-f electronic assembly"
|
||||
icon_state = "setup_small_pda"
|
||||
desc = "It's a case, for building small electronics with. This one resembles a PDA."
|
||||
|
||||
// Tiny assemblies.
|
||||
|
||||
/obj/item/device/electronic_assembly/tiny
|
||||
name = "electronic device"
|
||||
icon_state = "setup_device"
|
||||
desc = "It's a case, for building tiny-sized electronics with."
|
||||
w_class = ITEMSIZE_TINY
|
||||
max_components = IC_COMPONENTS_BASE / 2
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
|
||||
/obj/item/device/electronic_assembly/tiny/default
|
||||
name = "type-a electronic device"
|
||||
|
||||
/obj/item/device/electronic_assembly/tiny/cylinder
|
||||
name = "type-b electronic device"
|
||||
icon_state = "setup_device_cylinder"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one has a cylindrical design."
|
||||
|
||||
/obj/item/device/electronic_assembly/tiny/scanner
|
||||
name = "type-c electronic device"
|
||||
icon_state = "setup_device_scanner"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one has a scanner-like design."
|
||||
|
||||
/obj/item/device/electronic_assembly/tiny/hook
|
||||
name = "type-d electronic device"
|
||||
icon_state = "setup_device_hook"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one looks like it has a belt clip, but it's purely decorative."
|
||||
|
||||
/obj/item/device/electronic_assembly/tiny/box
|
||||
name = "type-e electronic device"
|
||||
icon_state = "setup_device_box"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one has a boxy design."
|
||||
|
||||
// Medium assemblies.
|
||||
|
||||
/obj/item/device/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
icon_state = "setup_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with."
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
|
||||
/obj/item/device/electronic_assembly/medium/default
|
||||
name = "type-a electronic mechanism"
|
||||
|
||||
/obj/item/device/electronic_assembly/medium/box
|
||||
name = "type-b electronic mechanism"
|
||||
icon_state = "setup_medium_box"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one has a boxy design."
|
||||
|
||||
/obj/item/device/electronic_assembly/medium/clam
|
||||
name = "type-c electronic mechanism"
|
||||
icon_state = "setup_medium_clam"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one has a clamshell design."
|
||||
|
||||
/obj/item/device/electronic_assembly/medium/medical
|
||||
name = "type-d electronic mechanism"
|
||||
icon_state = "setup_medium_med"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one resembles some type of medical apparatus."
|
||||
|
||||
/obj/item/device/electronic_assembly/medium/gun
|
||||
name = "type-e electronic mechanism"
|
||||
icon_state = "setup_medium_gun"
|
||||
item_state = "circuitgun"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one resembles a gun, or some type of tool, \
|
||||
if you're feeling optimistic."
|
||||
item_icons = list(
|
||||
slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',
|
||||
slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi',
|
||||
)
|
||||
|
||||
/obj/item/device/electronic_assembly/medium/radio
|
||||
name = "type-f electronic mechanism"
|
||||
icon_state = "setup_medium_radio"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one resembles an old radio."
|
||||
|
||||
// Large assemblies.
|
||||
|
||||
/obj/item/device/electronic_assembly/large
|
||||
name = "electronic machine"
|
||||
icon_state = "setup_large"
|
||||
desc = "It's a case, for building large electronics with."
|
||||
w_class = ITEMSIZE_LARGE
|
||||
max_components = IC_COMPONENTS_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
can_anchor = TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/large/default
|
||||
name = "type-a electronic machine"
|
||||
|
||||
/obj/item/device/electronic_assembly/large/scope
|
||||
name = "type-b electronic machine"
|
||||
icon_state = "setup_large_scope"
|
||||
desc = "It's a case, for building large electronics with. This one resembles an oscilloscope."
|
||||
|
||||
/obj/item/device/electronic_assembly/large/terminal
|
||||
name = "type-c electronic machine"
|
||||
icon_state = "setup_large_terminal"
|
||||
desc = "It's a case, for building large electronics with. This one resembles a computer terminal."
|
||||
|
||||
/obj/item/device/electronic_assembly/large/arm
|
||||
name = "type-d electronic machine"
|
||||
icon_state = "setup_large_arm"
|
||||
desc = "It's a case, for building large electronics with. This one resembles a robotic arm."
|
||||
|
||||
/obj/item/device/electronic_assembly/large/tall
|
||||
name = "type-e electronic machine"
|
||||
icon_state = "setup_large_tall"
|
||||
desc = "It's a case, for building large electronics with. This one has a tall design."
|
||||
|
||||
/obj/item/device/electronic_assembly/large/industrial
|
||||
name = "type-f electronic machine"
|
||||
icon_state = "setup_large_industrial"
|
||||
desc = "It's a case, for building large electronics with. This one resembles some kind of industrial machinery."
|
||||
|
||||
// Drone assemblies, which can move with the locomotion circuit.
|
||||
|
||||
/obj/item/device/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
icon_state = "setup_drone"
|
||||
desc = "It's a case, for building mobile electronics with."
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 1.5
|
||||
max_complexity = IC_COMPLEXITY_BASE * 1.5
|
||||
can_anchor = FALSE
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/can_move()
|
||||
return TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/default
|
||||
name = "type-a electronic drone"
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/arms
|
||||
name = "type-b electronic drone"
|
||||
icon_state = "setup_drone_arms"
|
||||
desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/secbot
|
||||
name = "type-c electronic drone"
|
||||
icon_state = "setup_drone_secbot"
|
||||
desc = "It's a case, for building mobile electronics with. This one resembles a Securitron."
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/medbot
|
||||
name = "type-d electronic drone"
|
||||
icon_state = "setup_drone_medbot"
|
||||
desc = "It's a case, for building mobile electronics with. This one resembles a Medibot."
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/genbot
|
||||
name = "type-e electronic drone"
|
||||
icon_state = "setup_drone_genbot"
|
||||
desc = "It's a case, for building mobile electronics with. This one has a generic bot design."
|
||||
|
||||
/obj/item/device/electronic_assembly/drone/android
|
||||
name = "type-f electronic drone"
|
||||
icon_state = "setup_drone_android"
|
||||
desc = "It's a case, for building mobile electronics with. This one has a hominoid design."
|
||||
|
||||
// Wall mounted assemblies.
|
||||
|
||||
/obj/item/device/electronic_assembly/wallmount
|
||||
name = "wall-mounted electronic assembly"
|
||||
icon_state = "setup_wallmount_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with. It has a magnetized \
|
||||
backing to allow it to stick to walls."
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
can_anchor = TRUE
|
||||
|
||||
/obj/item/device/electronic_assembly/wallmount/proc/mount_assembly(turf/on_wall, mob/user)
|
||||
if(get_dist(on_wall,user) > 1)
|
||||
return
|
||||
var/ndir = get_dir(on_wall, user)
|
||||
if(!(ndir in cardinal))
|
||||
return
|
||||
var/turf/T = get_turf(user)
|
||||
if(!istype(T, /turf/simulated/floor))
|
||||
to_chat(user, "<span class='warning'>You cannot place \the [src] on this spot!</span>")
|
||||
return
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 75, 1)
|
||||
user.visible_message("\The [user] attaches \the [src] to the wall.",
|
||||
"<span class='notice'>You attach \the [src] to the wall.</span>",
|
||||
"<span class='italics'>You hear clicking.</span>")
|
||||
if(isrobot(user)) //Robots cannot unequip/drop items, for Safety Reasons.
|
||||
forceMove(T)
|
||||
user.drop_item(T)
|
||||
anchored = TRUE
|
||||
on_anchored()
|
||||
pixel_x = DIR2PIXEL_X(ndir)
|
||||
pixel_y = DIR2PIXEL_Y(ndir)
|
||||
|
||||
/obj/item/device/electronic_assembly/wallmount/on_unanchored()
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
..()
|
||||
|
||||
/obj/item/device/electronic_assembly/wallmount/heavy
|
||||
name = "heavy wall-mounted electronic assembly"
|
||||
icon_state = "setup_wallmount_large"
|
||||
desc = "It's a case, for building large electronics with. It has a magnetized backing \
|
||||
to allow it to stick to walls."
|
||||
w_class = ITEMSIZE_LARGE
|
||||
max_components = IC_COMPONENTS_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
|
||||
/obj/item/device/electronic_assembly/wallmount/light
|
||||
name = "light wall-mounted electronic assembly"
|
||||
icon_state = "setup_wallmount_small"
|
||||
desc = "It's a case, for building small electronics with. It has a magnetized backing \
|
||||
to allow it to stick to walls."
|
||||
w_class = ITEMSIZE_SMALL
|
||||
max_components = IC_COMPONENTS_BASE
|
||||
max_complexity = IC_COMPLEXITY_BASE
|
||||
|
||||
/obj/item/device/electronic_assembly/wallmount/tiny
|
||||
name = "tiny wall-mounted electronic assembly"
|
||||
icon_state = "setup_wallmount_tiny"
|
||||
desc = "It's a case, for building tiny electronics with. It has a magnetized backing \
|
||||
to allow it to stick to walls."
|
||||
w_class = ITEMSIZE_TINY
|
||||
max_components = IC_COMPONENTS_BASE / 2
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
/obj/item/integrated_circuit/proc/activate_pin(pin_number)
|
||||
var/datum/integrated_io/activate/A = activators[pin_number]
|
||||
A.push_data()
|
||||
A.push_data(pin_number)
|
||||
|
||||
/datum/integrated_io/proc/get_data()
|
||||
if(isweakref(data))
|
||||
@@ -73,3 +73,11 @@
|
||||
debugger.write_data(pin, usr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/XorEncrypt(string, key)
|
||||
if(!string || !key ||!istext(string)||!istext(key))
|
||||
return
|
||||
var/r
|
||||
for(var/i = 1 to length(string))
|
||||
r += ascii2text(text2ascii(string,i) ^ text2ascii(key,(i-1)%length(string)+1))
|
||||
return r
|
||||
@@ -333,17 +333,18 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
return TRUE // Battery has enough.
|
||||
return FALSE // Not enough power.
|
||||
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work(ignore_power = FALSE)
|
||||
/obj/item/integrated_circuit/proc/check_then_do_work(ignore_power = FALSE, activator_id)
|
||||
if(world.time < next_use) // All intergrated circuits have an internal cooldown, to protect from spam.
|
||||
return
|
||||
return 0
|
||||
if(power_draw_per_use && !ignore_power)
|
||||
if(!check_power())
|
||||
power_fail()
|
||||
return
|
||||
return 0
|
||||
next_use = world.time + cooldown_per_use
|
||||
do_work()
|
||||
do_work(activator_id)
|
||||
return 1
|
||||
|
||||
/obj/item/integrated_circuit/proc/do_work()
|
||||
/obj/item/integrated_circuit/proc/do_work(activator_id)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/disconnect_all()
|
||||
@@ -353,3 +354,12 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
O.disconnect()
|
||||
for(var/datum/integrated_io/activate/A in activators)
|
||||
A.disconnect()
|
||||
|
||||
/obj/item/integrated_circuit/proc/attackby_react(var/atom/movable/A,mob/user)
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/on_anchored()
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/on_unanchored()
|
||||
return
|
||||
@@ -121,7 +121,7 @@ list[](
|
||||
|
||||
/datum/integrated_io/activate/push_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
io.holder.check_then_do_work()
|
||||
io.holder.check_then_do_work(FALSE)
|
||||
|
||||
/datum/integrated_io/proc/pull_data()
|
||||
for(var/datum/integrated_io/io in linked)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/device/integrated_circuit_printer
|
||||
name = "integrated circuit printer"
|
||||
desc = "A portable(ish) machine made to print tiny modular circuitry out of metal."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "circuit_printer"
|
||||
w_class = ITEMSIZE_LARGE
|
||||
var/metal = 0
|
||||
@@ -154,7 +154,7 @@
|
||||
/obj/item/weapon/disk/integrated_circuit/upgrade
|
||||
name = "integrated circuit printer upgrade disk"
|
||||
desc = "Install this into your integrated circuit printer to enhance it."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
icon = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "upgrade_disk"
|
||||
item_state = "card-id"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
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 = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "wirer-wire"
|
||||
item_state = "wirer"
|
||||
flags = CONDUCT
|
||||
@@ -60,7 +60,7 @@
|
||||
to_chat(user, "<span class='notice'>You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel.</span>")
|
||||
mode = UNWIRING
|
||||
update_icon()
|
||||
|
||||
|
||||
if (UNWIRING)
|
||||
if(io == selected_io)
|
||||
to_chat(user, "<span class='warning'>You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \
|
||||
@@ -107,7 +107,7 @@
|
||||
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 = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "debugger"
|
||||
flags = CONDUCT
|
||||
w_class = 2
|
||||
@@ -234,10 +234,56 @@
|
||||
io1.holder.interact(user) // This is to update the UI.
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer
|
||||
name = "assembly detailer"
|
||||
desc = "A combination autopainter and flash anodizer designed to give electronic assemblies a colorful, wear-resistant finish."
|
||||
icon = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "detailer"
|
||||
item_flags = NOBLUDGEON
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/detail_color = COLOR_ASSEMBLY_WHITE
|
||||
var/list/color_list = list(
|
||||
"black" = COLOR_ASSEMBLY_BLACK,
|
||||
"machine gray" = COLOR_ASSEMBLY_BGRAY,
|
||||
"white" = COLOR_ASSEMBLY_WHITE,
|
||||
"red" = COLOR_ASSEMBLY_RED,
|
||||
"orange" = COLOR_ASSEMBLY_ORANGE,
|
||||
"beige" = COLOR_ASSEMBLY_BEIGE,
|
||||
"brown" = COLOR_ASSEMBLY_BROWN,
|
||||
"gold" = COLOR_ASSEMBLY_GOLD,
|
||||
"yellow" = COLOR_ASSEMBLY_YELLOW,
|
||||
"gurkha" = COLOR_ASSEMBLY_GURKHA,
|
||||
"light green" = COLOR_ASSEMBLY_LGREEN,
|
||||
"green" = COLOR_ASSEMBLY_GREEN,
|
||||
"light blue" = COLOR_ASSEMBLY_LBLUE,
|
||||
"blue" = COLOR_ASSEMBLY_BLUE,
|
||||
"purple" = COLOR_ASSEMBLY_PURPLE,
|
||||
"hot pink" = COLOR_ASSEMBLY_HOT_PINK
|
||||
)
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/Initialize()
|
||||
update_icon()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/update_icon()
|
||||
cut_overlays()
|
||||
var/image/detail_overlay = image('icons/obj/assemblies/electronic_tools.dmi', "detailer-color")
|
||||
detail_overlay.color = detail_color
|
||||
add_overlay(detail_overlay)
|
||||
|
||||
/obj/item/device/integrated_electronics/detailer/attack_self(mob/user)
|
||||
var/color_choice = input(user, "Select color.", "Assembly Detailer", detail_color) as null|anything in color_list
|
||||
if(!color_list[color_choice])
|
||||
return
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
detail_color = color_list[color_choice]
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/storage/bag/circuits
|
||||
name = "circuit kit"
|
||||
desc = "This kit's essential for any circuitry projects."
|
||||
icon = 'icons/obj/electronic_assemblies.dmi'
|
||||
desc = "This kit is essential for any circuitry projects."
|
||||
icon = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "circuit_kit"
|
||||
w_class = 3
|
||||
display_contents_with_number = 0
|
||||
|
||||
@@ -66,13 +66,18 @@
|
||||
// For implants.
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon
|
||||
name = "metabolic siphon"
|
||||
desc = "A complicated piece of technology which converts bodily nutriments of a host into electricity."
|
||||
desc = "A complicated piece of technology which converts bodily nutriments of a host into electricity, or vice versa."
|
||||
extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a biological entity. The entity will feel an increased \
|
||||
appetite and will need to eat more often due to this. This device will fail if used inside synthetic entities."
|
||||
appetite and will need to eat more often due to this. This device will fail if used inside synthetic entities.\
|
||||
If the polarity is reversed, it will instead generate chemical energy with electricity, continuously consuming power from the assembly.\
|
||||
It is slightly less efficient than generating power."
|
||||
icon_state = "setup_implant"
|
||||
complexity = 10
|
||||
origin_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_BIO = 5)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
inputs = list("reverse" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("nutrition" = IC_PINTYPE_NUMBER)
|
||||
var/inefficiency = 1.2
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/proc/test_validity(var/mob/living/carbon/human/host)
|
||||
if(!host || host.isSynthetic() || host.stat == DEAD || host.nutrition <= 10)
|
||||
@@ -85,22 +90,139 @@
|
||||
var/obj/item/device/electronic_assembly/implant/implant_assembly = assembly
|
||||
if(implant_assembly.implant.imp_in)
|
||||
host = implant_assembly.implant.imp_in
|
||||
|
||||
if(test_validity(host))
|
||||
assembly.give_power(10)
|
||||
host.adjustNutritionLoss(HUNGER_FACTOR)
|
||||
if(!get_pin_data(IC_INPUT, 1))
|
||||
if(test_validity(host))
|
||||
assembly.give_power(10)
|
||||
host.adjustNutritionLoss(HUNGER_FACTOR)
|
||||
else
|
||||
if(assembly.draw_power(10*inefficiency)) // slightly less efficient the other way around
|
||||
host.adjustNutritionLoss(-HUNGER_FACTOR)
|
||||
set_pin_data(IC_OUTPUT, 1, host.nutrition)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/synthetic
|
||||
name = "internal energy siphon"
|
||||
desc = "A small circuit designed to be connected to an internal power wire inside a synthetic entity."
|
||||
extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a synthetic entity. The entity need to recharge \
|
||||
more often due to this. This device will fail if used inside organic entities."
|
||||
extended_desc = "The siphon generates 10W of energy, so long as the siphon exists inside a synthetic entity. The entity needs to recharge \
|
||||
more often due to this. If the polarity is reversed, it will instead transfer electricity back to the entity, continuously consuming power from \
|
||||
the assembly. This device will fail if used inside organic entities."
|
||||
icon_state = "setup_implant"
|
||||
complexity = 10
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 4, TECH_DATA = 3)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
inefficiency = 1 // it's not converting anything, just transferring power
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/metabolic_siphon/synthetic/test_validity(var/mob/living/carbon/human/host)
|
||||
if(!host || !host.isSynthetic() || host.stat == DEAD || host.nutrition <= 10)
|
||||
return FALSE // This time we don't want a metabolism.
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell
|
||||
name = "fuel cell"
|
||||
desc = "Produces electricity from chemicals."
|
||||
icon_state = "chemical_cell"
|
||||
extended_desc = "This is effectively an internal beaker. It will consume and produce power from phoron, slime jelly, welding fuel, carbon,\
|
||||
ethanol, nutriments and blood, in order of decreasing efficiency. It will consume fuel only if the battery can take more energy."
|
||||
flags = OPENCONTAINER
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/volume = 60
|
||||
var/list/fuel = list("phoron" = 50000, "slimejelly" = 25000, "fuel" = 15000, "carbon" = 10000, "ethanol"= 10000, "nutriment" =8000, "blood" = 5000)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/New()
|
||||
..()
|
||||
create_reagents(volume)
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, src)
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/chemical_cell/make_energy()
|
||||
if(assembly)
|
||||
for(var/I in fuel)
|
||||
if((assembly.battery.maxcharge - assembly.battery.charge) / CELLRATE > fuel[I])
|
||||
if(reagents.remove_reagent(I, 1))
|
||||
assembly.give_power(fuel[I])
|
||||
|
||||
// Interacts with the powernet.
|
||||
// Now you can make your own power generation (or poor man's powersink).
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/powernet
|
||||
name = "power network interface"
|
||||
desc = "Gives or takes power from a wire underneath the machine."
|
||||
icon_state = "powernet"
|
||||
extended_desc = "The assembly must be anchored, with a wrench, and a wire node must be avaiable directly underneath.<br>\
|
||||
The first pin determines if power is moved at all. The second pin, if true, will draw from the powernet to charge the assembly's \
|
||||
cell, otherwise it will give power from the cell to the powernet."
|
||||
complexity = 20
|
||||
inputs = list(
|
||||
"active" = IC_PINTYPE_BOOLEAN,
|
||||
"draw power" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
outputs = list(
|
||||
"power in grid" = IC_PINTYPE_NUMBER,
|
||||
"surplus power" = IC_PINTYPE_NUMBER,
|
||||
"load" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_POWER = 2)
|
||||
var/obj/machinery/power/circuit_io/IO = null // Dummy power machine to move energy in/out without a bunch of code duplication.
|
||||
var/throughput = 10000 // Give/take up to 10kW.
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/powernet/Initialize()
|
||||
IO = new(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/powernet/Destroy()
|
||||
qdel(IO)
|
||||
return ..()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/powernet/on_anchored()
|
||||
IO.connect_to_network()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/powernet/on_unanchored()
|
||||
IO.disconnect_from_network()
|
||||
|
||||
/obj/item/integrated_circuit/passive/power/powernet/make_energy()
|
||||
if(assembly && assembly.anchored && assembly.battery)
|
||||
var/should_act = get_pin_data(IC_INPUT, 1) // Even if this is false, we still need to update the output pins with powernet information.
|
||||
var/drawing = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(should_act) // We're gonna give or take from the net.
|
||||
if(drawing)
|
||||
var/to_transfer = min(throughput, (assembly.battery.maxcharge - assembly.battery.charge) / CELLRATE) // So we don't need to draw 10kW if the cell needs much less.
|
||||
var/amount = IO.draw_power(to_transfer)
|
||||
assembly.give_power(amount)
|
||||
else
|
||||
var/amount = assembly.draw_power(throughput)
|
||||
IO.add_avail(amount)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, IO.avail())
|
||||
set_pin_data(IC_OUTPUT, 2, IO.surplus())
|
||||
set_pin_data(IC_OUTPUT, 3, -IO.surplus()-IO.avail()) // we don't have a viewload() proc on machines and i'm lazy
|
||||
|
||||
// Internal power machine for interacting with the powernet.
|
||||
// It needs a bit of special code since base /machinery/power assumes loc will be a tile.
|
||||
/obj/machinery/power/circuit_io
|
||||
name = "embedded electrical I/O"
|
||||
|
||||
/obj/machinery/power/circuit_io/connect_to_network()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return FALSE
|
||||
|
||||
var/obj/structure/cable/C = T.get_cable_node()
|
||||
if(!C?.powernet)
|
||||
return FALSE
|
||||
|
||||
C.powernet.add_machine(src)
|
||||
return TRUE
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/integrated_circuit/built_in
|
||||
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 = 'icons/obj/assemblies/electronic_components.dmi'
|
||||
icon_state = "template"
|
||||
size = -1
|
||||
w_class = ITEMSIZE_TINY
|
||||
@@ -26,3 +26,15 @@
|
||||
if(istype(assembly, /obj/item/device/electronic_assembly/device))
|
||||
var/obj/item/device/electronic_assembly/device/device = assembly
|
||||
device.holder.pulse()
|
||||
|
||||
// Triggered when clothing assembly's hud button is clicked, used in-hand, or when another clothing-specific interaction occurs (like touching something with gloves on).
|
||||
/obj/item/integrated_circuit/built_in/action_button
|
||||
name = "external trigger circuit"
|
||||
desc = "A built in chip that outputs a pulse when an external control event occurs. It also provides additional data depending on the nature of the event and device."
|
||||
extended_desc = "This outputs a pulse if the assembly's HUD button is clicked while the assembly is closed."
|
||||
complexity = 0
|
||||
activators = list("on activation" = IC_PINTYPE_PULSE_OUT)
|
||||
outputs = list("output" = IC_PINTYPE_ANY)
|
||||
|
||||
/obj/item/integrated_circuit/built_in/action_button/do_work()
|
||||
activate_pin(1)
|
||||
@@ -168,6 +168,52 @@
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring
|
||||
name = "find text"
|
||||
desc = "This gives position of sample in the string. Or returns 0."
|
||||
extended_desc = "The first pin is the string to be examined. The second pin is the sample to be found. \
|
||||
For example, 'eat this burger',' ' will give you position 4. This circuit isn't case sensitive."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string" = IC_PINTYPE_STRING,
|
||||
"sample" = IC_PINTYPE_STRING,
|
||||
)
|
||||
outputs = list(
|
||||
"position" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("search" = IC_PINTYPE_PULSE_IN, "after search" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/findstring/do_work()
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, findtext(get_pin_data(IC_INPUT, 1),get_pin_data(IC_INPUT, 2)) )
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/exploders
|
||||
name = "string exploder"
|
||||
desc = "This splits a single string into a list of strings."
|
||||
extended_desc = "This circuit splits a given string into a list of strings based on the string and given delimiter. \
|
||||
For example, 'eat this burger',' ' will be converted to list('eat','this','burger')."
|
||||
complexity = 4
|
||||
inputs = list(
|
||||
"string to split" = IC_PINTYPE_STRING,
|
||||
"delimiter" = IC_PINTYPE_STRING,
|
||||
)
|
||||
outputs = list(
|
||||
"list" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list("separate" = IC_PINTYPE_PULSE_IN, "on separated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/exploders/do_work()
|
||||
var/strin = get_pin_data(IC_INPUT, 1)
|
||||
var/sample = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, splittext( strin ,sample ))
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/radians2degrees
|
||||
name = "radians to degrees converter"
|
||||
@@ -236,3 +282,75 @@
|
||||
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/stringlength
|
||||
name = "len circuit"
|
||||
desc = "This circuit will return the number of characters in a string."
|
||||
complexity = 1
|
||||
inputs = list(
|
||||
"string" = IC_PINTYPE_STRING
|
||||
)
|
||||
outputs = list(
|
||||
"length" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("get length" = IC_PINTYPE_PULSE_IN, "on acquisition" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/stringlength/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, length(get_pin_data(IC_INPUT, 1)))
|
||||
push_data()
|
||||
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/hsv2hex
|
||||
name = "hsv to hexadecimal converter"
|
||||
desc = "This circuit can convert a HSV (Hue, Saturation, and Value) color to a Hexadecimal RGB color."
|
||||
extended_desc = "The first pin controls tint (0-359), the second pin controls how intense the tint is (0-255), \
|
||||
and the third controls how bright the tint is (0 for black, 127 for normal, 255 for white)."
|
||||
icon_state = "hsv-hex"
|
||||
inputs = list(
|
||||
"hue" = IC_PINTYPE_NUMBER,
|
||||
"saturation" = IC_PINTYPE_NUMBER,
|
||||
"value" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/hsv2hex/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/hue = get_pin_data(IC_INPUT, 1)
|
||||
var/saturation = get_pin_data(IC_INPUT, 2)
|
||||
var/value = get_pin_data(IC_INPUT, 3)
|
||||
if(isnum(hue) && isnum(saturation) && isnum(value))
|
||||
result = HSVtoRGB(hsv(AngleToHue(hue),saturation,value))
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/converter/rgb2hex
|
||||
name = "rgb to hexadecimal converter"
|
||||
desc = "This circuit can convert a RGB (Red, Green, Blue) color to a Hexadecimal RGB color."
|
||||
extended_desc = "The first pin controls red amount, the second pin controls green amount, and the third controls blue amount. They all go from 0-255."
|
||||
icon_state = "rgb-hex"
|
||||
inputs = list(
|
||||
"red" = IC_PINTYPE_NUMBER,
|
||||
"green" = IC_PINTYPE_NUMBER,
|
||||
"blue" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("hexadecimal rgb" = IC_PINTYPE_COLOR)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/converter/rgb2hex/do_work()
|
||||
var/result = null
|
||||
pull_data()
|
||||
var/red = get_pin_data(IC_INPUT, 1)
|
||||
var/green = get_pin_data(IC_INPUT, 2)
|
||||
var/blue = get_pin_data(IC_INPUT, 3)
|
||||
if(isnum(red) && isnum(green) && isnum(blue))
|
||||
result = rgb(red, green, blue)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, result)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
@@ -76,6 +76,25 @@
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/colorpad
|
||||
name = "color pad"
|
||||
desc = "This small color pad allows someone to input a hexadecimal color into the system."
|
||||
icon_state = "colorpad"
|
||||
complexity = 2
|
||||
can_be_asked_input = 1
|
||||
inputs = list()
|
||||
outputs = list("color entered" = IC_PINTYPE_COLOR)
|
||||
activators = list("on entered" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 4
|
||||
|
||||
/obj/item/integrated_circuit/input/colorpad/ask_for_input(mob/user)
|
||||
var/new_color = input(user, "Enter a color, please.", "Color pad", get_pin_data(IC_OUTPUT, 1)) as color|null
|
||||
if(new_color && CanInteract(user, physical_state))
|
||||
set_pin_data(IC_OUTPUT, 1, new_color)
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
|
||||
/obj/item/integrated_circuit/input/med_scanner
|
||||
name = "integrated medical analyser"
|
||||
desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is."
|
||||
@@ -145,6 +164,59 @@
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/examiner
|
||||
name = "examiner"
|
||||
desc = "It's a little machine vision system. It can return the name, description, distance,\
|
||||
relative coordinates, total amount of reagents, and maximum amount of reagents of the referenced object."
|
||||
icon_state = "video_camera"
|
||||
complexity = 6
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"name" = IC_PINTYPE_STRING,
|
||||
"description" = IC_PINTYPE_STRING,
|
||||
"X" = IC_PINTYPE_NUMBER,
|
||||
"Y" = IC_PINTYPE_NUMBER,
|
||||
"distance" = IC_PINTYPE_NUMBER,
|
||||
"max reagents" = IC_PINTYPE_NUMBER,
|
||||
"amount of reagents" = IC_PINTYPE_NUMBER,
|
||||
"density" = IC_PINTYPE_BOOLEAN,
|
||||
"opacity" = IC_PINTYPE_BOOLEAN,
|
||||
"occupied turf" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT, "not scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4)
|
||||
power_draw_per_use = 80
|
||||
|
||||
/obj/item/integrated_circuit/input/examiner/do_work()
|
||||
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(H)) //Invalid input
|
||||
return
|
||||
|
||||
if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see.
|
||||
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, H.name)
|
||||
set_pin_data(IC_OUTPUT, 2, H.desc)
|
||||
set_pin_data(IC_OUTPUT, 3, H.x-T.x)
|
||||
set_pin_data(IC_OUTPUT, 4, H.y-T.y)
|
||||
set_pin_data(IC_OUTPUT, 5, sqrt((H.x-T.x)*(H.x-T.x)+ (H.y-T.y)*(H.y-T.y)))
|
||||
var/mr = 0
|
||||
var/tr = 0
|
||||
if(H.reagents)
|
||||
mr = H.reagents.maximum_volume
|
||||
tr = H.reagents.total_volume
|
||||
set_pin_data(IC_OUTPUT, 6, mr)
|
||||
set_pin_data(IC_OUTPUT, 7, tr)
|
||||
set_pin_data(IC_OUTPUT, 8, H.density)
|
||||
set_pin_data(IC_OUTPUT, 9, H.opacity)
|
||||
set_pin_data(IC_OUTPUT, 10, get_turf(H))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/local_locator
|
||||
name = "local locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \
|
||||
@@ -201,6 +273,50 @@
|
||||
set_pin_data(IC_OUTPUT, 1, pick(valid_things))
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator
|
||||
complexity = 6
|
||||
name = "advanced locator"
|
||||
desc = "This is needed for certain devices that demand a reference for a target to act upon. This type locates something that is standing in given radius of up to 7 meters."
|
||||
extended_desc = "The first pin requires a ref to a kind of object that you want the locator to acquire. This means that it will give refs to nearby objects that are similar to given sample. If this pin is a string, the locator will search for item by matching desired text in name + description. If more than one valid object is found nearby, it will choose one of them at random. The second pin is a radius."
|
||||
inputs = list("desired type" = IC_PINTYPE_ANY, "radius" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("located ref" = IC_PINTYPE_REF )
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
var/radius = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 7)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/nearby_things = view(radius, T)
|
||||
var/list/valid_things = list()
|
||||
var/I = get_pin_data(IC_INPUT, 1)
|
||||
if(isweakref(I))
|
||||
var/datum/weakref/WR = I
|
||||
var/atom/A = WR.resolve()
|
||||
var/desired_type = A?.type
|
||||
if(desired_type)
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(thing.type == desired_type)
|
||||
valid_things.Add(thing)
|
||||
else if(istext(I))
|
||||
var/DT = I
|
||||
for(var/atom/thing in nearby_things)
|
||||
if(findtext(addtext(thing.name, " ", thing.desc), DT, 1, 0))
|
||||
valid_things.Add(thing)
|
||||
if(valid_things.len)
|
||||
set_pin_data(IC_OUTPUT, 1, pick(valid_things))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
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."
|
||||
@@ -381,7 +497,9 @@
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/proc/scan(var/atom/A)
|
||||
/obj/item/integrated_circuit/input/sensor/proc/sense(var/atom/A)
|
||||
if(!src.Adjacent(A))
|
||||
return FALSE
|
||||
var/ignore_bags = get_pin_data(IC_INPUT, 1)
|
||||
if(ignore_bags)
|
||||
if(istype(A, /obj/item/weapon/storage))
|
||||
@@ -413,6 +531,85 @@
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3)
|
||||
power_draw_per_use = 60
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm
|
||||
name = "internal battery monitor"
|
||||
desc = "This monitors the charge level of an internal battery."
|
||||
icon_state = "internalbm"
|
||||
extended_desc = "This circuit will give you values of charge, max charge and percentage of the internal battery on demand."
|
||||
w_class = ITEMSIZE_TINY
|
||||
complexity = 1
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"cell charge" = IC_PINTYPE_NUMBER,
|
||||
"max charge" = IC_PINTYPE_NUMBER,
|
||||
"percentage" = IC_PINTYPE_NUMBER,
|
||||
"refference to assembly" = IC_PINTYPE_REF
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/internalbm/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
set_pin_data(IC_OUTPUT, 4, assembly)
|
||||
if(assembly)
|
||||
if(assembly.battery)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, assembly.battery.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, assembly.battery.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, 100*assembly.battery.charge/assembly.battery.maxcharge)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/externalbm
|
||||
name = "external battery monitor"
|
||||
desc = "This can help watch the battery level of any device in range."
|
||||
icon_state = "externalbm"
|
||||
extended_desc = "This circuit will give you values of charge, max charge and percentage of any device or battery in view"
|
||||
w_class = ITEMSIZE_TINY
|
||||
complexity = 2
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
outputs = list(
|
||||
"cell charge" = IC_PINTYPE_NUMBER,
|
||||
"max charge" = IC_PINTYPE_NUMBER,
|
||||
"percentage" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3)
|
||||
power_draw_per_use = 1
|
||||
|
||||
/obj/item/integrated_circuit/input/externalbm/do_work()
|
||||
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
set_pin_data(IC_OUTPUT, 3, null)
|
||||
if(AM)
|
||||
|
||||
|
||||
var/obj/item/weapon/cell/cell = null
|
||||
if(istype(AM, /obj/item/weapon/cell)) // Is this already a cell?
|
||||
cell = AM
|
||||
else // If not, maybe there's a cell inside it?
|
||||
for(var/obj/item/weapon/cell/C in AM.contents)
|
||||
if(C) // Find one cell to charge.
|
||||
cell = C
|
||||
break
|
||||
if(cell)
|
||||
|
||||
var/turf/A = get_turf(src)
|
||||
if(AM in view(A))
|
||||
push_data()
|
||||
set_pin_data(IC_OUTPUT, 1, cell.charge)
|
||||
set_pin_data(IC_OUTPUT, 2, cell.maxcharge)
|
||||
set_pin_data(IC_OUTPUT, 3, cell.percent())
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/atmo_scanner/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T)) //Invalid input
|
||||
@@ -553,4 +750,246 @@
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/phoron
|
||||
gas_name = "phoron"
|
||||
gas_display_name = "phoron"
|
||||
gas_display_name = "phoron"
|
||||
|
||||
/obj/item/integrated_circuit/input/turfpoint
|
||||
name = "tile pointer"
|
||||
desc = "This circuit will get a tile ref with the provided absolute coordinates."
|
||||
extended_desc = "If the machine cannot see the target, it will not be able to calculate the correct direction.\
|
||||
This circuit only works while inside an assembly."
|
||||
icon_state = "numberpad"
|
||||
complexity = 5
|
||||
inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("tile" = IC_PINTYPE_REF)
|
||||
activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/input/turfpoint/do_work()
|
||||
if(!assembly)
|
||||
activate_pin(3)
|
||||
return
|
||||
var/turf/T = get_turf(assembly)
|
||||
var/target_x = Clamp(get_pin_data(IC_INPUT, 1), 0, world.maxx)
|
||||
var/target_y = Clamp(get_pin_data(IC_INPUT, 2), 0, world.maxy)
|
||||
var/turf/A = locate(target_x, target_y, T.z)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
if(!A || !(A in view(T)))
|
||||
activate_pin(3)
|
||||
return
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, A)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/input/turfscan
|
||||
name = "tile analyzer"
|
||||
desc = "This circuit can analyze the contents of the scanned turf, and can read letters on the turf."
|
||||
icon_state = "video_camera"
|
||||
complexity = 5
|
||||
inputs = list(
|
||||
"target" = IC_PINTYPE_REF
|
||||
)
|
||||
outputs = list(
|
||||
"located ref" = IC_PINTYPE_LIST,
|
||||
"Written letters" = IC_PINTYPE_STRING,
|
||||
"area" = IC_PINTYPE_STRING
|
||||
)
|
||||
activators = list(
|
||||
"scan" = IC_PINTYPE_PULSE_IN,
|
||||
"on scanned" = IC_PINTYPE_PULSE_OUT,
|
||||
"not scanned" = IC_PINTYPE_PULSE_OUT
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 40
|
||||
cooldown_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/input/turfscan/do_work()
|
||||
var/turf/scanned_turf = get_pin_data_as_type(IC_INPUT, 1, /turf)
|
||||
var/turf/circuit_turf = get_turf(src)
|
||||
var/area_name = get_area_name(scanned_turf)
|
||||
if(!istype(scanned_turf)) //Invalid input
|
||||
activate_pin(3)
|
||||
return
|
||||
|
||||
if(scanned_turf in view(circuit_turf)) // This is a camera. It can't examine things that it can't see.
|
||||
var/list/turf_contents = new()
|
||||
for(var/obj/U in scanned_turf)
|
||||
turf_contents += WEAKREF(U)
|
||||
for(var/mob/U in scanned_turf)
|
||||
turf_contents += WEAKREF(U)
|
||||
set_pin_data(IC_OUTPUT, 1, turf_contents)
|
||||
set_pin_data(IC_OUTPUT, 3, area_name)
|
||||
var/list/St = new()
|
||||
for(var/obj/effect/decal/cleanable/crayon/I in scanned_turf)
|
||||
St.Add(I.icon_state)
|
||||
if(St.len)
|
||||
set_pin_data(IC_OUTPUT, 2, jointext(St, ",", 1, 0))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list
|
||||
complexity = 6
|
||||
name = "list advanced locator"
|
||||
desc = "This is needed for certain devices that demand list of names for a target to act upon. This type locates something \
|
||||
that is standing in given radius of up to 8 meters. Output is non-associative. Input will only consider keys if associative."
|
||||
extended_desc = "The first pin requires a list of the kinds of objects that you want the locator to acquire. It will locate nearby objects by name and description, \
|
||||
and will then provide a list of all found objects which are similar. \
|
||||
The second pin is a radius."
|
||||
inputs = list("desired type ref list" = IC_PINTYPE_LIST, "radius" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("located ref" = IC_PINTYPE_LIST)
|
||||
activators = list("locate" = IC_PINTYPE_PULSE_IN,"found" = IC_PINTYPE_PULSE_OUT,"not found" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 30
|
||||
var/radius = 1
|
||||
cooldown_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/on_data_written()
|
||||
var/rad = get_pin_data(IC_INPUT, 2)
|
||||
|
||||
if(isnum(rad))
|
||||
rad = Clamp(rad, 0, 8)
|
||||
radius = rad
|
||||
|
||||
/obj/item/integrated_circuit/input/advanced_locator_list/do_work()
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
var/list/input_list = list()
|
||||
input_list = get_pin_data(IC_INPUT, 1)
|
||||
if(length(input_list)) //if there is no input don't do anything.
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/nearby_things = view(radius,T)
|
||||
var/list/valid_things = list()
|
||||
for(var/item in input_list)
|
||||
if(!isnull(item) && !isnum(item))
|
||||
if(istext(item))
|
||||
for(var/i in nearby_things)
|
||||
var/atom/thing = i
|
||||
if(ismob(thing) && !isliving(thing))
|
||||
continue
|
||||
if(findtext(addtext(thing.name," ",thing.desc), item, 1, 0) )
|
||||
valid_things.Add(WEAKREF(thing))
|
||||
else
|
||||
var/atom/A = item
|
||||
var/desired_type = A.type
|
||||
for(var/i in nearby_things)
|
||||
var/atom/thing = i
|
||||
if(thing.type != desired_type)
|
||||
continue
|
||||
if(ismob(thing) && !isliving(thing))
|
||||
continue
|
||||
valid_things.Add(WEAKREF(thing))
|
||||
if(valid_things.len)
|
||||
set_pin_data(IC_OUTPUT, 1, valid_things)
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/ranged
|
||||
name = "ranged sensor"
|
||||
desc = "Scans and obtains a reference for any objects or persons in range. All you need to do is point the machine towards the target."
|
||||
extended_desc = "If the 'ignore storage' pin is set to true, the sensor will disregard scanning various storage containers such as backpacks."
|
||||
icon_state = "recorder"
|
||||
complexity = 36
|
||||
inputs = list("ignore storage" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 120
|
||||
|
||||
/obj/item/integrated_circuit/input/sensor/ranged/sense(atom/A, mob/user)
|
||||
if(!user || (!istype(A) && !isliving(A)))
|
||||
return FALSE
|
||||
if(user.client)
|
||||
if(!(A in view(user.client)))
|
||||
return FALSE
|
||||
else
|
||||
if(!(A in view(user)))
|
||||
return FALSE
|
||||
if(!check_then_do_work())
|
||||
return FALSE
|
||||
var/ignore_bags = get_pin_data(IC_INPUT, 1)
|
||||
if(ignore_bags)
|
||||
if(istype(A, /obj/item/weapon/storage))
|
||||
return FALSE
|
||||
set_pin_data(IC_OUTPUT, 1, A)
|
||||
push_data()
|
||||
to_chat(user, "<span class='notice'>You scan [A] with [assembly].</span>")
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/obj_scanner
|
||||
name = "scanner"
|
||||
desc = "Scans and obtains a reference for any objects you use on the assembly."
|
||||
extended_desc = "If the 'put down' pin is set to true, the assembly will take the scanned object from your hands to its location. \
|
||||
Useful for interaction with the grabber. The scanner only works using the help intent."
|
||||
icon_state = "recorder"
|
||||
complexity = 4
|
||||
inputs = list("put down" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("scanned" = IC_PINTYPE_REF)
|
||||
activators = list("on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/input/obj_scanner/attackby_react(var/atom/A,var/mob/user,intent)
|
||||
if(intent!=I_HELP)
|
||||
return FALSE
|
||||
if(!check_then_do_work())
|
||||
return FALSE
|
||||
var/pu = get_pin_data(IC_INPUT, 1)
|
||||
if(pu)
|
||||
user.drop_from_inventory(A)
|
||||
set_pin_data(IC_OUTPUT, 1, A)
|
||||
push_data()
|
||||
to_chat(user, "<span class='notice'>You let [assembly] scan [A].</span>")
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/integrated_circuit/input/card_reader
|
||||
name = "ID card reader" //To differentiate it from the data card reader
|
||||
desc = "A circuit that can read the registred name, assignment, and PassKey string from an ID card."
|
||||
icon_state = "card_reader"
|
||||
|
||||
complexity = 4
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
inputs = list(
|
||||
"enable credential cache" = IC_PINTYPE_BOOLEAN
|
||||
)
|
||||
outputs = list(
|
||||
"registered name" = IC_PINTYPE_STRING,
|
||||
"assignment" = IC_PINTYPE_STRING,
|
||||
"passkey" = IC_PINTYPE_LIST
|
||||
)
|
||||
activators = list(
|
||||
"on read" = IC_PINTYPE_PULSE_OUT
|
||||
)
|
||||
|
||||
/obj/item/integrated_circuit/input/card_reader/attackby_react(obj/item/I, mob/living/user, intent)
|
||||
var/obj/item/weapon/card/id/card = I.GetID()
|
||||
var/list/access = I.GetAccess()
|
||||
if(!access)
|
||||
return
|
||||
|
||||
if(get_pin_data(IC_INPUT, 1))
|
||||
assembly?.access_card.access |= access
|
||||
|
||||
if(card) // An ID card.
|
||||
set_pin_data(IC_OUTPUT, 1, card.registered_name)
|
||||
set_pin_data(IC_OUTPUT, 2, card.assignment)
|
||||
|
||||
else if(length(access)) // A non-card object that has access levels.
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
set_pin_data(IC_OUTPUT, 2, null)
|
||||
|
||||
else
|
||||
return FALSE
|
||||
|
||||
set_pin_data(IC_OUTPUT, 3, access)
|
||||
|
||||
push_data()
|
||||
activate_pin(1)
|
||||
return TRUE
|
||||
|
||||
@@ -50,6 +50,116 @@
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/list/search
|
||||
name = "search circuit"
|
||||
desc = "This circuit will give index of desired element in the list."
|
||||
extended_desc = "Search will start at 1 position and will return first matching position."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"item" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/list/search/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/item = get_pin_data(IC_INPUT, 2)
|
||||
set_pin_data(IC_OUTPUT, 1, input_list.Find(item))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/list/at
|
||||
name = "at circuit"
|
||||
desc = "This circuit will pick an element from a list by index."
|
||||
extended_desc = "If there is no element with such index, result will be null."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list("item" = IC_PINTYPE_ANY)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/list/at/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/item = input_list[index]
|
||||
set_pin_data(IC_OUTPUT, 1, item)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/list/delete
|
||||
name = "delete circuit"
|
||||
desc = "This circuit will delete the element from a list by index."
|
||||
extended_desc = "If there is no element with such index, result list will be unchanged."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
outputs = list(
|
||||
"item" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/list/delete/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/list/red_list = list()
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/j = 0
|
||||
for(var/I in input_list)
|
||||
j = j + 1
|
||||
if(j != index)
|
||||
red_list.Add(I)
|
||||
set_pin_data(IC_OUTPUT, 1, red_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/list/write
|
||||
name = "write circuit"
|
||||
desc = "This circuit will write element in list with given index."
|
||||
extended_desc = "If there is no element with such index, it will give the same list, as before."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
"index" = IC_PINTYPE_NUMBER,
|
||||
"item" = IC_PINTYPE_ANY
|
||||
)
|
||||
outputs = list(
|
||||
"redacted list" = IC_PINTYPE_LIST
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/list/write/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
var/index = get_pin_data(IC_INPUT, 2)
|
||||
var/item = get_pin_data(IC_INPUT, 3)
|
||||
input_list[index] = item
|
||||
set_pin_data(IC_OUTPUT, 1, input_list)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
obj/item/integrated_circuit/list/len
|
||||
name = "len circuit"
|
||||
desc = "This circuit will give length of the list."
|
||||
inputs = list(
|
||||
"list" = IC_PINTYPE_LIST,
|
||||
)
|
||||
outputs = list(
|
||||
"item" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
icon_state = "addition"
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/integrated_circuit/list/len/do_work()
|
||||
var/list/input_list = get_pin_data(IC_INPUT, 1)
|
||||
set_pin_data(IC_OUTPUT, 1, input_list.len)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/list/jointext
|
||||
name = "join text circuit"
|
||||
desc = "This circuit will add all elements of a list into one string, seperated by a character."
|
||||
|
||||
@@ -77,6 +77,84 @@
|
||||
/obj/item/integrated_circuit/logic/binary/equals/do_compare(A, B)
|
||||
return A == B
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/jklatch
|
||||
name = "JK latch"
|
||||
desc = "This gate is a synchronized JK latch."
|
||||
icon_state = "jklatch"
|
||||
inputs = list("J" = IC_PINTYPE_ANY,"K" = IC_PINTYPE_ANY)
|
||||
outputs = list("Q" = IC_PINTYPE_BOOLEAN,"!Q" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/jklatch/do_work()
|
||||
if(get_pin_data(IC_INPUT, 1))
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
lstate=!lstate
|
||||
else
|
||||
lstate = TRUE
|
||||
else
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
lstate=FALSE
|
||||
set_pin_data(IC_OUTPUT, 1, lstate ? TRUE : FALSE)
|
||||
set_pin_data(IC_OUTPUT, 2, !lstate ? TRUE : FALSE)
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/rslatch
|
||||
name = "RS latch"
|
||||
desc = "This gate is a synchronized RS latch. If both R and S are true, its state will not change."
|
||||
icon_state = "sr_nor"
|
||||
inputs = list("S" = IC_PINTYPE_ANY,"R" = IC_PINTYPE_ANY)
|
||||
outputs = list("Q" = IC_PINTYPE_BOOLEAN,"!Q" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/rslatch/do_work()
|
||||
if(get_pin_data(IC_INPUT, 1))
|
||||
if(!get_pin_data(IC_INPUT, 2))
|
||||
lstate=TRUE
|
||||
else
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
lstate=FALSE
|
||||
set_pin_data(IC_OUTPUT, 1, lstate ? TRUE : FALSE)
|
||||
set_pin_data(IC_OUTPUT, 2, !lstate ? TRUE : FALSE)
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/gdlatch
|
||||
name = "gated D latch"
|
||||
desc = "This gate is a synchronized gated D latch."
|
||||
icon_state = "gated_d"
|
||||
inputs = list("D" = IC_PINTYPE_ANY,"E" = IC_PINTYPE_ANY)
|
||||
outputs = list("Q" = IC_PINTYPE_BOOLEAN,"!Q" = IC_PINTYPE_BOOLEAN)
|
||||
activators = list("pulse in C" = IC_PINTYPE_PULSE_IN, "pulse out Q" = IC_PINTYPE_PULSE_OUT, "pulse out !Q" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
var/lstate=FALSE
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/gdlatch/do_work()
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
if(get_pin_data(IC_INPUT, 1))
|
||||
lstate=TRUE
|
||||
else
|
||||
lstate=FALSE
|
||||
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, lstate ? TRUE : FALSE)
|
||||
set_pin_data(IC_OUTPUT, 2, !lstate ? TRUE : FALSE)
|
||||
if(get_pin_data(IC_OUTPUT, 1))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/logic/binary/not_equals
|
||||
name = "not equal gate"
|
||||
desc = "This gate compares two values, and outputs the number one if both are different."
|
||||
|
||||
@@ -111,10 +111,10 @@
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grenade
|
||||
name = "grenade primer"
|
||||
desc = "This circuit comes with the ability to attach most types of grenades at prime them at will."
|
||||
desc = "This circuit comes with the ability to attach most types of grenades and prime them at will."
|
||||
extended_desc = "Time between priming and detonation is limited to between 1 to 12 seconds but is optional. \
|
||||
If unset, not a number, or a number less than 1 then the grenade's built-in timing will be used. \
|
||||
Beware: Once primed there is no aborting the process!"
|
||||
Beware: Once primed, there is no aborting the process!"
|
||||
icon_state = "grenade"
|
||||
complexity = 30
|
||||
size = 2
|
||||
@@ -185,3 +185,154 @@
|
||||
pre_attached_grenade_type = /obj/item/weapon/grenade/frag
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 10)
|
||||
spawn_flags = null // Used for world initializing, see the #defines above.
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker
|
||||
name = "shocker circuit"
|
||||
desc = "Used to shock adjacent creatures with electricity."
|
||||
icon_state = "shocker"
|
||||
extended_desc = "The circuit accepts a reference to creature to shock. It can shock a target on adjacent tiles. \
|
||||
Severity determines hardness of shock and its power consumption. It accepts values between 0 and 60."
|
||||
w_class = ITEMSIZE_TINY
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"severity" = IC_PINTYPE_NUMBER)
|
||||
outputs = list()
|
||||
activators = list("shock" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 0
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/on_data_written()
|
||||
var/s = get_pin_data(IC_INPUT, 2)
|
||||
power_draw_per_use = Clamp(s,0,60)*4
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/shocker/do_work()
|
||||
..()
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/living/M = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
|
||||
if(!istype(M)) //Invalid input
|
||||
return
|
||||
if(!M.Adjacent(T))
|
||||
return //Can't reach
|
||||
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
|
||||
spark(get_turf(M), 3, 1)
|
||||
M.stun_effect_act(0, Clamp(get_pin_data(IC_INPUT, 2),0,60), null)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber
|
||||
name = "grabber"
|
||||
desc = "A circuit with its own inventory for small/medium items, used to grab and store things."
|
||||
icon_state = "grabber"
|
||||
extended_desc = "The circuit accepts a reference to thing to be grabbed. It can store up to 10 things. Modes: 1 for grab. 0 for eject the first thing. -1 for eject all."
|
||||
w_class = ITEMSIZE_TINY
|
||||
size = 3
|
||||
|
||||
complexity = 10
|
||||
inputs = list("target" = IC_PINTYPE_REF,"mode" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("first" = IC_PINTYPE_REF, "last" = IC_PINTYPE_REF, "amount" = IC_PINTYPE_NUMBER)
|
||||
activators = list("pulse in" = IC_PINTYPE_PULSE_IN,"pulse out" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 50
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/do_work()
|
||||
var/turf/T = get_turf(src)
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
|
||||
var/mode = get_pin_data(IC_INPUT, 2)
|
||||
if(mode == 1)
|
||||
if(AM.Adjacent(T))
|
||||
if(contents.len < 10)
|
||||
if(istype(AM,/obj/item))
|
||||
var/obj/item/A = AM
|
||||
if(A.w_class < ITEMSIZE_NORMAL)
|
||||
AM.forceMove(src)
|
||||
if(mode == 0)
|
||||
if(contents.len)
|
||||
var/obj/item/U = contents[1]
|
||||
U.forceMove(T)
|
||||
if(mode == -1)
|
||||
if(contents.len)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
set_pin_data(IC_OUTPUT, 1, contents[1])
|
||||
set_pin_data(IC_OUTPUT, 2, contents[contents.len])
|
||||
set_pin_data(IC_OUTPUT, 3, src.contents.len)
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower
|
||||
name = "thrower"
|
||||
desc = "A compact launcher to throw things from inside or nearby tiles"
|
||||
extended_desc = "The first and second inputs need to be numbers. They are coordinates to throw thing at, relative to the machine itself. \
|
||||
The 'fire' activator will cause the mechanism to attempt to throw thing at the coordinates, if possible. Note that the \
|
||||
projectile need to be inside the machine, or to be on an adjacent tile, and to be up to medium size."
|
||||
complexity = 15
|
||||
w_class = ITEMSIZE_TINY
|
||||
size = 2
|
||||
inputs = list(
|
||||
"target X rel" = IC_PINTYPE_NUMBER,
|
||||
"target Y rel" = IC_PINTYPE_NUMBER,
|
||||
"projectile" = IC_PINTYPE_REF
|
||||
)
|
||||
outputs = list()
|
||||
activators = list(
|
||||
"fire" = IC_PINTYPE_PULSE_IN
|
||||
)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4)
|
||||
power_draw_per_use = 50
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/thrower/do_work()
|
||||
|
||||
var/datum/integrated_io/target_x = inputs[1]
|
||||
var/datum/integrated_io/target_y = inputs[2]
|
||||
var/datum/integrated_io/projectile = inputs[3]
|
||||
if(!isweakref(projectile.data))
|
||||
return
|
||||
var/obj/item/A = projectile.data.resolve()
|
||||
if(A.anchored)
|
||||
return
|
||||
if(A.w_class>ITEMSIZE_NORMAL)
|
||||
return
|
||||
var/turf/T = get_turf(src.assembly)
|
||||
var/turf/TP = get_turf(A)
|
||||
if(!(TP.Adjacent(T)))
|
||||
return
|
||||
if(src.assembly)
|
||||
if(isnum(target_x.data))
|
||||
target_x.data = round(target_x.data)
|
||||
if(isnum(target_y.data))
|
||||
target_y.data = round(target_y.data)
|
||||
|
||||
if(target_x.data == 0 && target_y.data == 0)
|
||||
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 > 0)
|
||||
T = get_step(T, EAST)
|
||||
i--
|
||||
else
|
||||
i = abs(target_x.data)
|
||||
while(i > 0)
|
||||
T = get_step(T, WEST)
|
||||
i--
|
||||
|
||||
i = 0
|
||||
if(target_y.data > 0)
|
||||
i = abs(target_y.data)
|
||||
while(i > 0)
|
||||
T = get_step(T, NORTH)
|
||||
i--
|
||||
else if(target_y.data < 0)
|
||||
i = abs(target_y.data)
|
||||
while(i > 0)
|
||||
T = get_step(T, SOUTH)
|
||||
i--
|
||||
|
||||
if(!T)
|
||||
return
|
||||
|
||||
A.forceMove(get_turf(src))
|
||||
A.throw_at(T, round(Clamp(sqrt(target_x.data*target_x.data+target_y.data*target_y.data),0,8),1), 3, assembly)
|
||||
|
||||
@@ -18,13 +18,22 @@
|
||||
complexity = 20
|
||||
cooldown_per_use = 30 SECONDS
|
||||
inputs = list()
|
||||
outputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list("create smoke" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3)
|
||||
volume = 100
|
||||
power_draw_per_use = 20
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, src)
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/smoke/do_work()
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new()
|
||||
@@ -45,40 +54,125 @@
|
||||
cooldown_per_use = 6 SECONDS
|
||||
inputs = list("target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER)
|
||||
inputs_default = list("2" = 5)
|
||||
outputs = list()
|
||||
activators = list("inject" = IC_PINTYPE_PULSE_IN)
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF)
|
||||
activators = list("inject" = IC_PINTYPE_PULSE_IN, "on injected" = IC_PINTYPE_PULSE_OUT, "on fail" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
volume = 30
|
||||
power_draw_per_use = 15
|
||||
var/direc = 1
|
||||
var/transfer_amount = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/proc/inject_amount()
|
||||
var/amount = get_pin_data(IC_INPUT, 2)
|
||||
if(isnum(amount))
|
||||
return Clamp(amount, 0, 30)
|
||||
/obj/item/integrated_circuit/reagent/injector/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, src)
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_reagent_change()
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 2)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direc = 0
|
||||
else
|
||||
direc = 1
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, volume)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/injector/do_work()
|
||||
set waitfor = 0 // Don't sleep in a proc that is called by a processor without this set, otherwise it'll delay the entire thing
|
||||
|
||||
var/atom/movable/AM = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
if(!istype(AM)) //Invalid input
|
||||
activate_pin(3)
|
||||
return
|
||||
if(!reagents.total_volume) // Empty
|
||||
return
|
||||
if(AM.can_be_injected_by(src))
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
var/turf/T = get_turf(AM)
|
||||
T.visible_message("<span class='warning'>[src] is trying to inject [L]!</span>")
|
||||
sleep(3 SECONDS)
|
||||
if(!L.can_be_injected_by(src))
|
||||
|
||||
if(direc == 1)
|
||||
|
||||
if(!istype(AM)) //Invalid input
|
||||
activate_pin(3)
|
||||
return
|
||||
if(!reagents.total_volume) // Empty
|
||||
activate_pin(3)
|
||||
return
|
||||
if(AM.can_be_injected_by(src))
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
var/turf/T = get_turf(AM)
|
||||
T.visible_message("<span class='warning'>[src] is trying to inject [L]!</span>")
|
||||
sleep(3 SECONDS)
|
||||
if(!L.can_be_injected_by(src))
|
||||
activate_pin(3)
|
||||
return
|
||||
var/contained = reagents.get_reagents()
|
||||
var/trans = reagents.trans_to_mob(L, transfer_amount, CHEM_BLOOD)
|
||||
message_admins("[src] injected \the [L] with [trans]u of [contained].")
|
||||
to_chat(AM, "<span class='notice'>You feel a tiny prick!</span>")
|
||||
visible_message("<span class='warning'>[src] injects [L]!</span>")
|
||||
else
|
||||
reagents.trans_to(AM, transfer_amount)
|
||||
else
|
||||
|
||||
if(reagents.total_volume >= volume) // Full
|
||||
activate_pin(3)
|
||||
return
|
||||
var/obj/target = AM
|
||||
if(!target.reagents)
|
||||
activate_pin(3)
|
||||
return
|
||||
var/turf/TS = get_turf(src)
|
||||
var/turf/TT = get_turf(AM)
|
||||
if(!TS.Adjacent(TT))
|
||||
activate_pin(3)
|
||||
return
|
||||
var/tramount = Clamp(min(transfer_amount, reagents.maximum_volume - reagents.total_volume), 0, reagents.maximum_volume)
|
||||
if(ismob(target))//Blood!
|
||||
if(istype(target, /mob/living/carbon))
|
||||
var/mob/living/carbon/T = target
|
||||
if(!T.dna)
|
||||
if(T.reagents.trans_to_obj(src, tramount))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
return
|
||||
if(NOCLONE in T.mutations) //target done been et, no more blood in him
|
||||
if(T.reagents.trans_to_obj(src, tramount))
|
||||
activate_pin(2)
|
||||
else
|
||||
activate_pin(3)
|
||||
return
|
||||
return
|
||||
var/datum/reagent/B
|
||||
if(istype(T, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = T
|
||||
if(H.species && !H.has_organ("heart"))
|
||||
H.reagents.trans_to_obj(src, tramount)
|
||||
else
|
||||
B = T.take_blood(src, tramount)
|
||||
else
|
||||
B = T.take_blood(src,tramount)
|
||||
if (B)
|
||||
reagents.reagent_list |= B
|
||||
reagents.update_total()
|
||||
on_reagent_change()
|
||||
reagents.handle_reactions()
|
||||
B = null
|
||||
visible_message( "<span class='notice'>Machine takes a blood sample from [target].</span>")
|
||||
else
|
||||
activate_pin(3)
|
||||
return
|
||||
var/contained = reagents.get_reagents()
|
||||
var/trans = reagents.trans_to_mob(L, inject_amount(), CHEM_BLOOD)
|
||||
message_admins("[src] injected \the [L] with [trans]u of [contained].")
|
||||
to_chat(AM, "<span class='notice'>You feel a tiny prick!</span>")
|
||||
visible_message("<span class='warning'>[src] injects [L]!</span>")
|
||||
else
|
||||
reagents.trans_to(AM, inject_amount())
|
||||
|
||||
else //if not mob
|
||||
if(!target.reagents.total_volume)
|
||||
visible_message( "<span class='notice'>[target] is empty.</span>")
|
||||
activate_pin(3)
|
||||
return
|
||||
target.reagents.trans_to_obj(src, tramount)
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump
|
||||
name = "reagent pump"
|
||||
@@ -103,11 +197,17 @@
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
var/direc = 1
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/pump/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 3)
|
||||
if(!isnull(new_amount))
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direc = 0
|
||||
else
|
||||
direc = 1
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
@@ -130,9 +230,14 @@
|
||||
return
|
||||
if(!source.is_open_container() || !target.is_open_container())
|
||||
return
|
||||
if(!target.reagents.get_free_space())
|
||||
return
|
||||
source.reagents.trans_to(target, transfer_amount)
|
||||
if(direc)
|
||||
if(!target.reagents.get_free_space())
|
||||
return
|
||||
source.reagents.trans_to(target, transfer_amount)
|
||||
else
|
||||
if(!source.reagents.get_free_space())
|
||||
return
|
||||
target.reagents.trans_to(source, transfer_amount)
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage
|
||||
@@ -143,7 +248,7 @@
|
||||
flags = OPENCONTAINER
|
||||
complexity = 4
|
||||
inputs = list()
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER)
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF)
|
||||
activators = list()
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
@@ -153,6 +258,11 @@
|
||||
set_pin_data(IC_OUTPUT, 1, reagents.total_volume)
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/interact(mob/user)
|
||||
set_pin_data(IC_OUTPUT, 2, src)
|
||||
push_data()
|
||||
..()
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/cryo
|
||||
name = "cryo reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. This will also suppress reactions."
|
||||
@@ -162,3 +272,92 @@
|
||||
complexity = 8
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/big
|
||||
name = "big reagent storage"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 180u."
|
||||
icon_state = "reagent_storage_big"
|
||||
extended_desc = "This is effectively an internal beaker."
|
||||
flags = OPENCONTAINER
|
||||
complexity = 16
|
||||
volume = 180
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan
|
||||
name = "reagent scanner"
|
||||
desc = "Stores liquid inside, and away from electrical components. Can store up to 60u. On pulse this beaker will send list of contained reagents, as well as analyse their taste."
|
||||
icon_state = "reagent_scan"
|
||||
extended_desc = "Mostly useful for reagent filters."
|
||||
flags = OPENCONTAINER
|
||||
complexity = 8
|
||||
outputs = list("volume used" = IC_PINTYPE_NUMBER,"self reference" = IC_PINTYPE_REF,"list of reagents" = IC_PINTYPE_LIST,"taste" = IC_PINTYPE_STRING)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
|
||||
/obj/item/integrated_circuit/reagent/storage/scan/do_work()
|
||||
var/list/cont = list()
|
||||
for(var/datum/reagent/RE in reagents.reagent_list)
|
||||
cont += RE.id
|
||||
set_pin_data(IC_OUTPUT, 3, cont)
|
||||
set_pin_data(IC_OUTPUT, 4, reagents.generate_taste_message(src))
|
||||
push_data()
|
||||
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter
|
||||
name = "reagent filter"
|
||||
desc = "Filtering liquids by list of desired or unwanted reagents."
|
||||
icon_state = "reagent_filter"
|
||||
extended_desc = "This is a filter which will move liquids from the source ref to the target ref. \
|
||||
It will move all reagents, except list, given in fourth pin if amount value is positive.\
|
||||
Or it will move only desired reagents if amount is negative, The third pin determines \
|
||||
how much reagent is moved per pulse, between 0 and 50. Amount is given for each separate reagent."
|
||||
flags = OPENCONTAINER
|
||||
complexity = 8
|
||||
inputs = list("source" = IC_PINTYPE_REF, "target" = IC_PINTYPE_REF, "injection amount" = IC_PINTYPE_NUMBER, "list of reagents" = IC_PINTYPE_LIST)
|
||||
inputs_default = list("3" = 5)
|
||||
outputs = list()
|
||||
activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2)
|
||||
var/transfer_amount = 10
|
||||
var/direc = 1
|
||||
power_draw_per_use = 10
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/on_data_written()
|
||||
var/new_amount = get_pin_data(IC_INPUT, 3)
|
||||
if(new_amount < 0)
|
||||
new_amount = -new_amount
|
||||
direc = 0
|
||||
else
|
||||
direc = 1
|
||||
if(isnum(new_amount))
|
||||
new_amount = Clamp(new_amount, 0, 50)
|
||||
transfer_amount = new_amount
|
||||
|
||||
/obj/item/integrated_circuit/reagent/filter/do_work()
|
||||
var/atom/movable/source = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
|
||||
var/atom/movable/target = get_pin_data_as_type(IC_INPUT, 2, /atom/movable)
|
||||
var/list/demand = get_pin_data(IC_INPUT, 4)
|
||||
if(!istype(source) || !istype(target)) //Invalid input
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
if(source.Adjacent(T) && target.Adjacent(T))
|
||||
if(!source.reagents || !target.reagents)
|
||||
return
|
||||
if(ismob(source) || ismob(target))
|
||||
return
|
||||
if(!source.is_open_container() || !target.is_open_container())
|
||||
return
|
||||
if(!target.reagents.get_free_space())
|
||||
return
|
||||
for(var/datum/reagent/G in source.reagents.reagent_list)
|
||||
if (!direc)
|
||||
if(G.id in demand)
|
||||
source.reagents.trans_id_to(target, G.id, transfer_amount)
|
||||
else
|
||||
if(!(G.id in demand))
|
||||
source.reagents.trans_id_to(target, G.id, transfer_amount)
|
||||
activate_pin(2)
|
||||
push_data()
|
||||
|
||||
@@ -4,33 +4,70 @@
|
||||
/obj/item/integrated_circuit/smart/basic_pathfinder
|
||||
name = "basic pathfinder"
|
||||
desc = "This complex circuit is able to determine what direction a given target is."
|
||||
extended_desc = "This circuit uses a miniturized, integrated camera to determine where the target is. If the machine \
|
||||
extended_desc = "This circuit uses a miniturized integrated camera to determine where the target is. If the machine \
|
||||
cannot see the target, it will not be able to calculate the correct direction."
|
||||
icon_state = "numberpad"
|
||||
complexity = 25
|
||||
inputs = list("target" = IC_PINTYPE_REF)
|
||||
complexity = 5
|
||||
inputs = list("target" = IC_PINTYPE_REF,"ignore obstacles" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list("dir" = IC_PINTYPE_DIR)
|
||||
activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT)
|
||||
activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5)
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/smart/basic_pathfinder/do_work()
|
||||
var/datum/integrated_io/I = inputs[1]
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
|
||||
if(!isweakref(I.data))
|
||||
push_data()
|
||||
return
|
||||
activate_pin(3)
|
||||
var/atom/A = I.data.resolve()
|
||||
if(!A)
|
||||
push_data()
|
||||
activate_pin(3)
|
||||
return
|
||||
if(!(A in view(get_turf(src))))
|
||||
push_data()
|
||||
activate_pin(3)
|
||||
return // Can't see the target.
|
||||
var/desired_dir = get_dir(get_turf(src), A)
|
||||
|
||||
set_pin_data(IC_OUTPUT, 1, desired_dir)
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A)))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/smart/coord_basic_pathfinder
|
||||
name = "coordinate pathfinder"
|
||||
desc = "This complex circuit is able to determine what direction a given target is."
|
||||
extended_desc = "This circuit uses absolute coordinates to determine where the target is. If the machine \
|
||||
cannot see the target, it will not be able to calculate the correct direction. \
|
||||
This circuit will only work while inside an assembly."
|
||||
icon_state = "numberpad"
|
||||
complexity = 5
|
||||
inputs = list("X" = IC_PINTYPE_NUMBER,"Y" = IC_PINTYPE_NUMBER,"ignore obstacles" = IC_PINTYPE_BOOLEAN)
|
||||
outputs = list( "dir" = IC_PINTYPE_DIR,
|
||||
"distance" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT,"not calculated" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
power_draw_per_use = 40
|
||||
|
||||
/obj/item/integrated_circuit/smart/coord_basic_pathfinder/do_work()
|
||||
if(!assembly)
|
||||
activate_pin(3)
|
||||
return
|
||||
var/turf/T = get_turf(assembly)
|
||||
var/target_x = Clamp(get_pin_data(IC_INPUT, 1), 0, world.maxx)
|
||||
var/target_y = Clamp(get_pin_data(IC_INPUT, 2), 0, world.maxy)
|
||||
var/turf/A = locate(target_x, target_y, T.z)
|
||||
set_pin_data(IC_OUTPUT, 1, null)
|
||||
if(!A||A==T)
|
||||
activate_pin(3)
|
||||
return
|
||||
if(get_pin_data(IC_INPUT, 2))
|
||||
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_turf(A)))
|
||||
else
|
||||
set_pin_data(IC_OUTPUT, 1, get_dir(get_turf(src), get_step_towards2(get_turf(src),A)))
|
||||
set_pin_data(IC_OUTPUT, 2, sqrt((A.x-T.x)*(A.x-T.x)+ (A.y-T.y)*(A.y-T.y)))
|
||||
push_data()
|
||||
activate_pin(2)
|
||||
Reference in New Issue
Block a user