mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 00:21:11 +01:00
Integrated Circuit Overhaul 2.0 (#22647)
Complete overhaul of Integrated Circuits Final Edition! - Adds phoron cost to circuits (not assemblies). - Printer searching capability. - Changed names of assemblies to better match their description. - Adds cloning and auto appending JSON for large builds. - Adds database, debug, advanced math circuits. - Reworks the list circuits to finally accept anything other than NUM. - Adds plenty of list circuits to allow functional building and clearing of lists. - Reworks Complexity/Space to allow a bit better flexibility in creation of devices. - Adds a "Headroom" concept where space/complexity can go beyond the maximum to a very slight degree. Concretely, unused space gives `2` extra complexity per unused component slot, capped at `15%` of `max_complexity`. Unused complexity gives `1` extra component slot per `6` unused complexity, capped at `15%` of `max_components`. - Groups math and logic circuits and adds subgroups. - Doesn't mess with the circuit tool kit. - Adds a xenoarch drill assembly with a nice sprite. Thank you @EnchantedCrocolisk for the sprite! - Changes activation limit time to 1 second from 2 seconds, adds a 1 second timer that is unique to the INTEGRATED CIRCUIT PRINTER with the advanced design disk. - Ports several Baystation integrated-circuit manipulation components, primarily from Baystation12/Baystation12https://github.com/Baystation12/Baystation12/pull/22458, with anchoring bolts and hatch lock sourced from Baystation12/Baystation12https://github.com/Baystation12/Baystation12/pull/25052. - Changes the electronic ear piece into a workable radio headset with working encryption keys capability and unique ways the Microphone and TTS interacts with it. - Removed the ability for all the electronic wearables to spawn with a basic cell. - Combines https://github.com/Aurorastation/Aurora.3/pull/22466, https://github.com/Aurorastation/Aurora.3/pull/22456, https://github.com/Aurorastation/Aurora.3/pull/22455, https://github.com/Aurorastation/Aurora.3/pull/22446 that are now closed.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
/*
|
||||
* core/assemblies.dm
|
||||
* Base electronic assembly behavior: circuit storage, open/closed handling, interaction, icon updates, cloning hooks, and wiring rules.
|
||||
*/
|
||||
|
||||
/obj/item/electronic_assembly
|
||||
name = "electronic assembly"
|
||||
desc = "It's a case, for building small electronics with."
|
||||
name = "small circuit case"
|
||||
desc = "A case for building small electronic assemblies."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
icon = 'icons/obj/assemblies/electronic_setups.dmi'
|
||||
icon_state = "setup_small"
|
||||
@@ -9,25 +14,32 @@
|
||||
|
||||
var/max_components = IC_COMPONENTS_BASE
|
||||
var/max_complexity = IC_COMPLEXITY_BASE
|
||||
var/max_components_device = 16
|
||||
var/max_complexity_device = 42
|
||||
var/max_components_implant = 16
|
||||
var/max_complexity_implant = 42
|
||||
// Whether the assembly panel is open for direct circuit access.
|
||||
var/opened = 0
|
||||
var/can_anchor = FALSE // If true, wrenching it will anchor it.
|
||||
var/obj/item/cell/device/battery // Internal cell which most circuits need to work.
|
||||
// Power cell or battery object feeding the assembly.
|
||||
var/obj/item/cell/battery // Internal cell which most circuits need to work.
|
||||
// User-selected detail color used for assembly and wearable overlays.
|
||||
var/detail_color = COLOR_ASSEMBLY_BLACK
|
||||
var/obj/item/card/id/access_card
|
||||
|
||||
/obj/item/electronic_assembly/implant
|
||||
name = "electronic implant"
|
||||
icon_state = "setup_implant"
|
||||
desc = "It's a case, for building very tiny electronics with."
|
||||
desc = "A case for building very small electronic assemblies."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_components = IC_COMPONENTS_BASE * 3/4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 3/4
|
||||
max_components = /obj/item/electronic_assembly::max_components_implant
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_implant
|
||||
var/obj/item/implant/integrated_circuit/implant = null
|
||||
|
||||
/obj/item/electronic_assembly/Initialize(mapload, printed = FALSE)
|
||||
. = ..()
|
||||
if (!printed)
|
||||
battery = new(src)
|
||||
battery = new /obj/item/cell/device(src)
|
||||
START_PROCESSING(SSelectronics, src)
|
||||
access_card = new /obj/item/card/id(src)
|
||||
|
||||
@@ -86,11 +98,13 @@
|
||||
total_parts += part.size
|
||||
total_complexity = total_complexity + part.complexity
|
||||
var/list/HTML = list()
|
||||
var/effective_component_limit = get_effective_component_limit(total_complexity)
|
||||
var/effective_complexity_limit = get_effective_complexity_limit(total_parts)
|
||||
|
||||
HTML += "<br><a href='byond://?src=[REF(src)]'>Refresh</a> | "
|
||||
HTML += "<a href='byond://?src=[REF(src)];rename=1'>Rename</a><br>"
|
||||
HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.<br>"
|
||||
HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity.<br>"
|
||||
HTML += "[total_parts]/[max_components] space taken up in the assembly[effective_component_limit > max_components ? " ([effective_component_limit] with headroom)" : ""].<br>"
|
||||
HTML += "[total_complexity]/[max_complexity] maximum complexity[effective_complexity_limit > max_complexity ? " ([effective_complexity_limit] with headroom)" : ""].<br>"
|
||||
if(battery)
|
||||
HTML += "[round(battery.charge, 0.1)]/[battery.maxcharge] ([round(battery.percent(), 0.1)]%) cell charge. <a href='byond://?src=[REF(src)];remove_cell=1'>Remove</a>"
|
||||
else
|
||||
@@ -150,7 +164,7 @@
|
||||
/obj/item/electronic_assembly/verb/rename()
|
||||
set name = "Rename Circuit"
|
||||
set category = "Object"
|
||||
set desc = "Rename your circuit, useful to stay organized."
|
||||
set desc = "Renames the circuit to make assemblies easier to organize."
|
||||
set src in usr
|
||||
|
||||
var/mob/M = usr
|
||||
@@ -186,7 +200,7 @@
|
||||
|
||||
/obj/item/electronic_assembly/feedback_hints(mob/user, distance, is_adjacent)
|
||||
. = ..()
|
||||
if(opened && is_adjacent)
|
||||
if(is_adjacent && opened)
|
||||
for(var/obj/item/integrated_circuit/IC in contents)
|
||||
. += SPAN_NOTICE("It contains \a [IC].")
|
||||
|
||||
@@ -200,6 +214,16 @@
|
||||
for(var/obj/item/integrated_circuit/part in contents)
|
||||
. += part.size
|
||||
|
||||
/obj/item/electronic_assembly/proc/get_effective_complexity_limit(total_part_size)
|
||||
var/remaining_size = max(0, max_components - total_part_size)
|
||||
var/overflow_limit = round(max_complexity * IC_OVERFLOW_LIMIT)
|
||||
return max_complexity + min(remaining_size * IC_OVERFLOW_COMPONENT_TO_COMPLEXITY, overflow_limit)
|
||||
|
||||
/obj/item/electronic_assembly/proc/get_effective_component_limit(total_complexity)
|
||||
var/remaining_complexity = max(0, max_complexity - total_complexity)
|
||||
var/overflow_limit = round(max_components * IC_OVERFLOW_LIMIT)
|
||||
return max_components + min(round(remaining_complexity / IC_OVERFLOW_COMPLEXITY_TO_COMPONENT), overflow_limit)
|
||||
|
||||
// Returns true if the circuit made it inside.
|
||||
/obj/item/electronic_assembly/proc/add_circuit(obj/item/integrated_circuit/IC, mob/user)
|
||||
if(!opened)
|
||||
@@ -212,11 +236,13 @@
|
||||
|
||||
var/total_part_size = get_part_size()
|
||||
var/total_complexity = get_part_complexity()
|
||||
var/new_part_size = total_part_size + IC.size
|
||||
var/new_complexity = total_complexity + IC.complexity
|
||||
|
||||
if((total_part_size + IC.size) > max_components)
|
||||
if(new_part_size > get_effective_component_limit(new_complexity))
|
||||
to_chat(user, SPAN_WARNING("You can't seem to add the '[IC.name]', as there's insufficient space."))
|
||||
return FALSE
|
||||
if((total_complexity + IC.complexity) > max_complexity)
|
||||
if(new_complexity > get_effective_complexity_limit(new_part_size))
|
||||
to_chat(user, SPAN_WARNING("You can't seem to add the '[IC.name]', since this setup's too complicated for the case."))
|
||||
return FALSE
|
||||
|
||||
@@ -273,7 +299,7 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
else if(istype(attacking_item, /obj/item/cell/device))
|
||||
else if(istype(attacking_item, /obj/item/cell))
|
||||
if(!opened)
|
||||
to_chat(user, SPAN_WARNING("\The [src] isn't open, so you can't put anything inside. Try using a crowbar."))
|
||||
for(var/obj/item/integrated_circuit/input/S in contents)
|
||||
@@ -286,7 +312,7 @@
|
||||
S.attackby_react(attacking_item,user,user.a_intent)
|
||||
return FALSE
|
||||
|
||||
var/obj/item/cell/device/cell = attacking_item
|
||||
var/obj/item/cell/cell = attacking_item
|
||||
user.drop_from_inventory(cell,src)
|
||||
battery = cell
|
||||
playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
@@ -313,6 +339,7 @@
|
||||
return
|
||||
if(opened)
|
||||
interact(user)
|
||||
return
|
||||
|
||||
var/list/input_selection = list()
|
||||
var/list/available_inputs = list()
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
/*
|
||||
* core/assemblies/clothing.dm
|
||||
* Wearable electronic assemblies that can be embedded into clothing-style items and driven through item actions.
|
||||
*/
|
||||
|
||||
|
||||
// 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/electronic_assembly
|
||||
var/max_components_clothing = 26
|
||||
var/max_complexity_clothing = 68
|
||||
|
||||
/obj/item/electronic_assembly/clothing
|
||||
name = "electronic clothing"
|
||||
var/clothing_icon_state = "circuitry" // Needs to match the clothing's base icon_state.
|
||||
desc = "It's a case, for building machines attached to clothing."
|
||||
desc = "A clothing-mounted case for integrated electronics."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
max_components = IC_COMPONENTS_BASE
|
||||
max_complexity = IC_COMPLEXITY_BASE
|
||||
var/max_components_clothing_small = 14
|
||||
var/max_complexity_clothing_small = 36
|
||||
var/max_components_clothing_large = 42
|
||||
var/max_complexity_clothing_large = 105
|
||||
max_components = /obj/item/electronic_assembly::max_components_clothing
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_clothing
|
||||
var/obj/item/clothing/clothing = null
|
||||
|
||||
/obj/item/electronic_assembly/clothing/ui_host()
|
||||
@@ -22,23 +35,29 @@
|
||||
return clothing
|
||||
|
||||
/obj/item/electronic_assembly/clothing/update_icon()
|
||||
clothing.icon_state = "[initial(clothing.icon_state)][opened ? "-open" : ""]"
|
||||
if(!clothing)
|
||||
return
|
||||
|
||||
clothing.icon_state = opened ? "[initial(clothing.icon_state)]-open" : initial(clothing.icon_state)
|
||||
clothing.ClearOverlays()
|
||||
var/image/detail_overlay = image('icons/obj/assemblies/wearable_electronic_setups.dmi', "[initial(clothing.icon_state)][opened ? "-open" : ""]-color")
|
||||
|
||||
var/image/detail_overlay = image('icons/obj/assemblies/wearable_electronic_setups.dmi', "[clothing.icon_state]-color")
|
||||
detail_overlay.color = detail_color
|
||||
clothing.AddOverlays(detail_overlay)
|
||||
clothing.update_clothing_icon()
|
||||
|
||||
if(hascall(clothing, "update_clothing_icon"))
|
||||
call(clothing, "update_clothing_icon")()
|
||||
|
||||
// This is 'small' relative to the size of regular clothing assemblies.
|
||||
/obj/item/electronic_assembly/clothing/small
|
||||
max_components = IC_COMPONENTS_BASE / 2
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
max_components = /obj/item/electronic_assembly/clothing::max_components_clothing_small
|
||||
max_complexity = /obj/item/electronic_assembly/clothing::max_complexity_clothing_small
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
// Ditto.
|
||||
/obj/item/electronic_assembly/clothing/large
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
max_components = /obj/item/electronic_assembly/clothing::max_components_clothing_large
|
||||
max_complexity = /obj/item/electronic_assembly/clothing::max_complexity_clothing_large
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
/obj/item/electronic_assembly/clothing/rename()
|
||||
@@ -63,9 +82,9 @@
|
||||
..()
|
||||
|
||||
// Does most of the repeatative setup.
|
||||
/obj/item/clothing/proc/setup_integrated_circuit(new_type)
|
||||
/obj/item/clothing/proc/setup_integrated_circuit(new_type, printed = FALSE)
|
||||
// Set up the internal circuit holder.
|
||||
IC = new new_type(src)
|
||||
IC = new new_type(src, printed)
|
||||
IC.clothing = src
|
||||
IC.name = name
|
||||
|
||||
@@ -83,22 +102,22 @@
|
||||
// Jumpsuit.
|
||||
/obj/item/clothing/under/circuitry
|
||||
name = "electronic jumpsuit"
|
||||
desc = "It's a wearable case for electronics. This one is a black jumpsuit with wiring weaved into the fabric."
|
||||
desc = "A wearable case for integrated electronics. This one is a black jumpsuit with wiring weaved into the fabric."
|
||||
icon = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "jumpsuit"
|
||||
item_state = "jumpsuit"
|
||||
worn_state = "jumpsuit"
|
||||
|
||||
/obj/item/clothing/under/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing)
|
||||
/obj/item/clothing/under/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/under/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_w_uniform_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
@@ -106,22 +125,22 @@
|
||||
// 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 \
|
||||
desc = "A wearable case for integrated 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 = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "gloves"
|
||||
item_state = "gloves"
|
||||
|
||||
/obj/item/clothing/gloves/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
|
||||
/obj/item/clothing/gloves/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/gloves/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_gloves_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
@@ -139,22 +158,22 @@
|
||||
// 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. \
|
||||
desc = "A wearable case for integrated 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 = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "goggles"
|
||||
item_state = "goggles"
|
||||
|
||||
/obj/item/clothing/glasses/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
|
||||
/obj/item/clothing/glasses/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/glasses/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_glasses_str, slot_l_hand_str, slot_r_hand_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
@@ -177,22 +196,22 @@
|
||||
// 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 \
|
||||
desc = "A wearable case for integrated electronics. This one is a pair of boots, with wires attached to a small \
|
||||
cover."
|
||||
icon = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "shoes"
|
||||
item_state = "shoes"
|
||||
|
||||
/obj/item/clothing/shoes/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
|
||||
/obj/item/clothing/shoes/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/shoes/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_shoes_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
@@ -200,44 +219,44 @@
|
||||
// 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 \
|
||||
desc = "A wearable case for integrated 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 = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "head"
|
||||
item_state = "head"
|
||||
|
||||
/obj/item/clothing/head/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
|
||||
/obj/item/clothing/head/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_head_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
|
||||
// Ear
|
||||
// Ears
|
||||
/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."
|
||||
desc = "A wearable case for integrated electronics. This one appears to be a technical-looking headset."
|
||||
icon = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
|
||||
/obj/item/clothing/ears/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
|
||||
/obj/item/clothing/ears/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/ears/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_l_ear_str, slot_r_ear_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
@@ -245,22 +264,22 @@
|
||||
// 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 \
|
||||
desc = "A wearable case for integrated 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 = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "chest"
|
||||
item_state = "chest"
|
||||
|
||||
/obj/item/clothing/suit/circuitry/Initialize()
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/large)
|
||||
/obj/item/clothing/suit/circuitry/Initialize(mapload, printed = FALSE)
|
||||
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/large, printed)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/suit/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_wear_suit_str)
|
||||
if(IC.detail_color && (slot in valid_slots))
|
||||
if(IC?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", IC.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
return ..()
|
||||
|
||||
@@ -0,0 +1,261 @@
|
||||
/obj/item/radio/headset/circuitry
|
||||
name = "electronic radio headset"
|
||||
desc = "A radio headset modified to accept integrated circuitry. Takes encryption keys."
|
||||
icon = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
slot_flags = SLOT_EARS
|
||||
|
||||
ks1type = null
|
||||
ks2type = null
|
||||
|
||||
// Internal assembly that stores the actual circuits installed inside the host item.
|
||||
var/obj/item/electronic_assembly/clothing/small/circuit_assembly = null
|
||||
// Built-in action circuit used to expose an activation button to the wearer/user.
|
||||
var/obj/item/integrated_circuit/built_in/action_button/circuit_action = null
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/Initialize(mapload, printed = FALSE)
|
||||
. = ..()
|
||||
setup_headset_integrated_circuit()
|
||||
refresh_headset_sprite()
|
||||
refresh_radio_state()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/Destroy()
|
||||
QDEL_NULL(circuit_assembly)
|
||||
circuit_action = null
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/setup_headset_integrated_circuit()
|
||||
if(circuit_assembly)
|
||||
circuit_assembly.forceMove(src)
|
||||
circuit_assembly.clothing = src
|
||||
circuit_assembly.name = name
|
||||
else
|
||||
circuit_assembly = new /obj/item/electronic_assembly/clothing/small(src, TRUE)
|
||||
circuit_assembly.clothing = src
|
||||
circuit_assembly.name = name
|
||||
|
||||
QDEL_NULL(circuit_assembly.battery)
|
||||
|
||||
for(var/obj/item/integrated_circuit/C in circuit_assembly.contents)
|
||||
C.assembly = circuit_assembly
|
||||
|
||||
circuit_action = locate(/obj/item/integrated_circuit/built_in/action_button) in circuit_assembly.contents
|
||||
|
||||
if(!circuit_action)
|
||||
circuit_action = new(circuit_assembly)
|
||||
circuit_assembly.force_add_circuit(circuit_action)
|
||||
|
||||
default_action_type = /datum/action/item_action/integrated_circuit
|
||||
action_button_name = "Activate [capitalize_first_letters(name)]"
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/get_cloneable_assembly()
|
||||
return circuit_assembly
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/get_clone_host_type()
|
||||
return type
|
||||
|
||||
/obj/item/radio/headset/circuitry/feedback_hints(mob/user, distance, is_adjacent)
|
||||
. = ..()
|
||||
|
||||
if(distance <= 1 && !circuit_assembly?.opened)
|
||||
return
|
||||
|
||||
var/obj/item/electronic_assembly/E = get_cloneable_assembly()
|
||||
if(E)
|
||||
for(var/obj/item/integrated_circuit/IC in E.contents)
|
||||
. += SPAN_NOTICE("It contains \a [IC].")
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/clone_with_integrated_assembly(atom/location, obj/item/integrated_circuit_printer/printer, obj/item/electronic_assembly/source_assembly)
|
||||
if(!location || !printer || !source_assembly)
|
||||
return null
|
||||
|
||||
var/obj/item/radio/headset/circuitry/new_headset = new type(location)
|
||||
|
||||
if(!new_headset || !new_headset.circuit_assembly)
|
||||
if(new_headset)
|
||||
qdel(new_headset)
|
||||
return null
|
||||
|
||||
var/obj/item/electronic_assembly/clothing/small/internal_assembly = new_headset.circuit_assembly
|
||||
|
||||
if(!printer.copy_assembly_into_existing(source_assembly, internal_assembly))
|
||||
qdel(new_headset)
|
||||
return null
|
||||
|
||||
internal_assembly.forceMove(new_headset)
|
||||
internal_assembly.clothing = new_headset
|
||||
internal_assembly.name = source_assembly.name
|
||||
internal_assembly.detail_color = source_assembly.detail_color
|
||||
internal_assembly.opened = FALSE
|
||||
internal_assembly.battery = null
|
||||
|
||||
for(var/obj/item/integrated_circuit/C in internal_assembly.contents)
|
||||
C.assembly = internal_assembly
|
||||
|
||||
new_headset.name = source_assembly.name
|
||||
new_headset.circuit_assembly = internal_assembly
|
||||
new_headset.circuit_action = locate(/obj/item/integrated_circuit/built_in/action_button) in internal_assembly.contents
|
||||
|
||||
if(!new_headset.circuit_action)
|
||||
new_headset.circuit_action = new(internal_assembly)
|
||||
internal_assembly.force_add_circuit(new_headset.circuit_action)
|
||||
|
||||
new_headset.default_action_type = /datum/action/item_action/integrated_circuit
|
||||
new_headset.action_button_name = "Activate [capitalize_first_letters(new_headset.name)]"
|
||||
|
||||
new_headset.refresh_headset_sprite()
|
||||
new_headset.refresh_radio_state()
|
||||
|
||||
return new_headset
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/refresh_radio_state()
|
||||
on = TRUE
|
||||
set_frequency(PUB_FREQ)
|
||||
set_listening(TRUE)
|
||||
recalculateChannels(TRUE)
|
||||
|
||||
if(ismob(loc))
|
||||
possibly_deactivate_in_loc()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/refresh_headset_sprite()
|
||||
icon = 'icons/obj/assemblies/wearable_electronic_setups.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = circuit_assembly?.opened ? "headset-open" : "headset"
|
||||
item_state = "headset"
|
||||
|
||||
ClearOverlays()
|
||||
|
||||
if(circuit_assembly?.detail_color)
|
||||
var/image/detail_overlay = image('icons/obj/assemblies/wearable_electronic_setups.dmi', "[icon_state]-color")
|
||||
detail_overlay.color = circuit_assembly.detail_color
|
||||
AddOverlays(detail_overlay)
|
||||
|
||||
if(hascall(src, "update_clothing_icon"))
|
||||
call(src, "update_clothing_icon")()
|
||||
|
||||
/obj/item/radio/headset/circuitry/attack_self(mob/user)
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/attackby(obj/item/attacking_item, mob/user)
|
||||
if(istype(attacking_item, /obj/item/integrated_circuit_printer))
|
||||
var/obj/item/integrated_circuit_printer/P = attacking_item
|
||||
if(P.scan_cloneable_item(src, user))
|
||||
return TRUE
|
||||
|
||||
if(attacking_item.tool_behaviour == TOOL_CROWBAR && circuit_assembly)
|
||||
circuit_assembly.attackby(attacking_item, user)
|
||||
refresh_headset_sprite()
|
||||
refresh_radio_state()
|
||||
return TRUE
|
||||
|
||||
if(istype(attacking_item, /obj/item/encryptionkey))
|
||||
. = ..()
|
||||
refresh_radio_state()
|
||||
return
|
||||
|
||||
if(circuit_assembly?.opened)
|
||||
circuit_assembly.attackby(attacking_item, user)
|
||||
refresh_headset_sprite()
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/AltClick(mob/user)
|
||||
if(!circuit_assembly)
|
||||
return ..()
|
||||
|
||||
if(!circuit_assembly.opened)
|
||||
to_chat(user, SPAN_WARNING("The circuit panel is closed."))
|
||||
return
|
||||
|
||||
return circuit_assembly.attack_self(user)
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/verb/access_integrated_circuit()
|
||||
set category = "Object.Equipped"
|
||||
set name = "Access Integrated Circuit"
|
||||
set src in usr
|
||||
|
||||
if(!circuit_assembly)
|
||||
return
|
||||
|
||||
if(!circuit_assembly.opened)
|
||||
to_chat(usr, SPAN_WARNING("The circuit panel is closed."))
|
||||
return
|
||||
|
||||
circuit_assembly.attack_self(usr)
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
|
||||
if(slot == slot_l_ear || slot == slot_r_ear || slot == slot_l_ear_str || slot == slot_r_ear_str)
|
||||
refresh_radio_state()
|
||||
refresh_headset_sprite()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/dropped(mob/user)
|
||||
. = ..()
|
||||
set_listening(FALSE, actual_setting = FALSE)
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/Moved(atom/old_loc, forced)
|
||||
. = ..()
|
||||
possibly_deactivate_in_loc()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/build_additional_parts(mob/living/carbon/human/H, mob_icon, slot)
|
||||
var/static/list/valid_slots
|
||||
|
||||
if(!valid_slots)
|
||||
valid_slots = list(slot_l_ear_str, slot_r_ear_str)
|
||||
|
||||
if(circuit_assembly?.detail_color && (slot in valid_slots))
|
||||
var/image/electronic_overlay = overlay_image(icon, "[item_state][slot_str_to_contained_flag(slot)]-color", circuit_assembly.detail_color, RESET_COLOR)
|
||||
return electronic_overlay
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/get_wearer()
|
||||
if(!ishuman(loc))
|
||||
return null
|
||||
|
||||
var/mob/living/carbon/human/H = loc
|
||||
|
||||
if(H.l_ear == src)
|
||||
return H
|
||||
|
||||
if(H.r_ear == src)
|
||||
return H
|
||||
|
||||
return null
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/private_output(message)
|
||||
var/mob/living/carbon/human/H = get_wearer()
|
||||
|
||||
if(!H)
|
||||
return
|
||||
|
||||
to_chat(H, SPAN_NOTICE("[message]"))
|
||||
|
||||
|
||||
/obj/item/radio/headset/circuitry/proc/private_tts_output(message)
|
||||
var/mob/living/carbon/human/H = get_wearer()
|
||||
|
||||
if(!H)
|
||||
return
|
||||
|
||||
to_chat(H, SPAN_NOTICE("\The [src] states, \"[message]\""))
|
||||
@@ -1,213 +1,311 @@
|
||||
/*
|
||||
* core/assemblies/generic.dm
|
||||
* Generic handheld, large, wall-mounted, and specialty electronic assembly variants.
|
||||
*/
|
||||
|
||||
// Generic subtypes without a lot of special code.
|
||||
|
||||
// Anchored pickup protection.
|
||||
// This prevents anchored electronic assemblies from being picked up like normal items.
|
||||
// Anchored assemblies still pass ordinary hand interaction through attack_self(), so closed
|
||||
// assemblies expose their external inputs and opened assemblies expose the circuit UI.
|
||||
|
||||
/obj/item/electronic_assembly
|
||||
var/supports_builtin_powernet = FALSE
|
||||
var/supports_builtin_locomotion = FALSE
|
||||
var/max_components_tiny_assembly = 12
|
||||
var/max_complexity_tiny_assembly = 30
|
||||
var/max_components_medium_assembly = 55
|
||||
var/max_complexity_medium_assembly = 140
|
||||
var/max_components_large_assembly = 110
|
||||
var/max_complexity_large_assembly = 240
|
||||
var/max_components_drone = 38
|
||||
var/max_complexity_drone = 95
|
||||
var/max_components_wallmount = 55
|
||||
var/max_complexity_wallmount = 140
|
||||
|
||||
/obj/item/electronic_assembly/attack_hand(mob/user)
|
||||
if(anchored)
|
||||
if(!check_interactivity(user))
|
||||
return TRUE
|
||||
|
||||
attack_self(user)
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/electronic_assembly/mob_can_equip(mob/user, slot, disable_warning = FALSE, bypass_blocked_check = FALSE, is_overlay_check = FALSE)
|
||||
if(anchored)
|
||||
if(!disable_warning)
|
||||
to_chat(user, SPAN_WARNING("\The [src] is anchored in place."))
|
||||
return FALSE
|
||||
|
||||
return ..(user, slot, disable_warning, bypass_blocked_check, is_overlay_check)
|
||||
|
||||
// Small assemblies.
|
||||
|
||||
/obj/item/electronic_assembly/default
|
||||
name = "type-a electronic assembly"
|
||||
name = "basic small circuit case"
|
||||
|
||||
/obj/item/electronic_assembly/calc
|
||||
name = "type-b electronic assembly"
|
||||
name = "calculator small circuit case"
|
||||
icon_state = "setup_small_calc"
|
||||
desc = "It's a case, for building small electronics with. This one resembles a pocket calculator."
|
||||
desc = "A case for building small electronic assemblies. This one resembles a pocket calculator."
|
||||
|
||||
/obj/item/electronic_assembly/clam
|
||||
name = "type-c electronic assembly"
|
||||
name = "clamshell small circuit case"
|
||||
icon_state = "setup_small_clam"
|
||||
desc = "It's a case, for building small electronics with. This one has a clamshell design."
|
||||
desc = "A case for building small electronic assemblies. This one has a clamshell design."
|
||||
|
||||
/obj/item/electronic_assembly/simple
|
||||
name = "type-d electronic assembly"
|
||||
name = "compact small circuit case"
|
||||
icon_state = "setup_small_simple"
|
||||
desc = "It's a case, for building small electronics with. This one has a simple design."
|
||||
desc = "A case for building small electronic assemblies. This one has a simple design."
|
||||
|
||||
/obj/item/electronic_assembly/hook
|
||||
name = "type-e electronic assembly"
|
||||
name = "belt-clip small circuit case"
|
||||
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."
|
||||
desc = "A case for building small electronic assemblies. This one looks like it has a belt clip, but it's purely decorative."
|
||||
|
||||
/obj/item/electronic_assembly/pda
|
||||
name = "type-f electronic assembly"
|
||||
name = "PDA-style small circuit case"
|
||||
icon_state = "setup_small_pda"
|
||||
desc = "It's a case, for building small electronics with. This one resembles a PDA."
|
||||
desc = "A case for building small electronic assemblies. This one resembles a PDA."
|
||||
|
||||
|
||||
// Tiny assemblies.
|
||||
|
||||
/obj/item/electronic_assembly/tiny
|
||||
name = "electronic device"
|
||||
name = "tiny circuit case"
|
||||
icon_state = "setup_device"
|
||||
desc = "It's a case, for building tiny-sized electronics with."
|
||||
desc = "A case for building tiny electronic assemblies."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_components = IC_COMPONENTS_BASE / 2
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
max_components = /obj/item/electronic_assembly::max_components_tiny_assembly
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_tiny_assembly
|
||||
|
||||
/obj/item/electronic_assembly/tiny/default
|
||||
name = "type-a electronic device"
|
||||
name = "basic tiny circuit case"
|
||||
|
||||
/obj/item/electronic_assembly/tiny/cylinder
|
||||
name = "type-b electronic device"
|
||||
name = "cylindrical tiny circuit case"
|
||||
icon_state = "setup_device_cylinder"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one has a cylindrical design."
|
||||
desc = "A case for building tiny electronic assemblies. This one has a cylindrical design."
|
||||
|
||||
/obj/item/electronic_assembly/tiny/scanner
|
||||
name = "type-c electronic device"
|
||||
name = "scanner tiny circuit case"
|
||||
icon_state = "setup_device_scanner"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one has a scanner-like design."
|
||||
desc = "A case for building tiny electronic assemblies. This one has a scanner-like design."
|
||||
|
||||
/obj/item/electronic_assembly/tiny/hook
|
||||
name = "type-d electronic device"
|
||||
name = "belt-clip tiny circuit case"
|
||||
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."
|
||||
desc = "A case for building tiny electronic assemblies. This one looks like it has a belt clip, but it's purely decorative."
|
||||
|
||||
/obj/item/electronic_assembly/tiny/box
|
||||
name = "type-e electronic device"
|
||||
name = "boxy tiny circuit case"
|
||||
icon_state = "setup_device_box"
|
||||
desc = "It's a case, for building tiny-sized electronics with. This one has a boxy design."
|
||||
desc = "A case for building tiny electronic assemblies. This one has a boxy design."
|
||||
|
||||
|
||||
// Medium assemblies.
|
||||
|
||||
/obj/item/electronic_assembly/medium
|
||||
name = "electronic mechanism"
|
||||
name = "medium circuit case"
|
||||
icon_state = "setup_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with."
|
||||
desc = "A case for building medium electronic assemblies."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
var/max_components_anomaly_drill = 30
|
||||
var/max_complexity_anomaly_drill = 80
|
||||
max_components = /obj/item/electronic_assembly::max_components_medium_assembly
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_medium_assembly
|
||||
|
||||
/obj/item/electronic_assembly/medium/default
|
||||
name = "type-a electronic mechanism"
|
||||
name = "basic medium circuit case"
|
||||
|
||||
/obj/item/electronic_assembly/medium/box
|
||||
name = "type-b electronic mechanism"
|
||||
name = "boxy medium circuit case"
|
||||
icon_state = "setup_medium_box"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one has a boxy design."
|
||||
desc = "A case for building medium electronic assemblies. This one has a boxy design."
|
||||
|
||||
/obj/item/electronic_assembly/medium/clam
|
||||
name = "type-c electronic mechanism"
|
||||
name = "clamshell medium circuit case"
|
||||
icon_state = "setup_medium_clam"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one has a clamshell design."
|
||||
desc = "A case for building medium electronic assemblies. This one has a clamshell design."
|
||||
|
||||
/obj/item/electronic_assembly/medium/medical
|
||||
name = "type-d electronic mechanism"
|
||||
name = "medical medium circuit case"
|
||||
icon_state = "setup_medium_med"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one resembles some type of medical apparatus."
|
||||
desc = "A case for building medium electronic assemblies. This one resembles some type of medical apparatus."
|
||||
|
||||
/obj/item/electronic_assembly/medium/gun
|
||||
name = "type-e electronic mechanism"
|
||||
name = "tool-shaped medium circuit case"
|
||||
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, \
|
||||
desc = "A case for building medium electronic assemblies. This one resembles a gun, or some type of tool, \
|
||||
if you're feeling optimistic."
|
||||
|
||||
/obj/item/electronic_assembly/medium/radio
|
||||
name = "type-f electronic mechanism"
|
||||
name = "radio medium circuit case"
|
||||
icon_state = "setup_medium_radio"
|
||||
desc = "It's a case, for building medium-sized electronics with. This one resembles an old radio."
|
||||
desc = "A case for building medium electronic assemblies. This one resembles an old radio."
|
||||
|
||||
/obj/item/electronic_assembly/medium/anomaly_drill
|
||||
name = "anomaly drill assembly"
|
||||
desc = "A prebuilt electronic assembly designed to drill toward anomaly sensor coordinates."
|
||||
icon_state = "setup_medium_drill"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_components = /obj/item/electronic_assembly/medium::max_components_anomaly_drill
|
||||
max_complexity = /obj/item/electronic_assembly/medium::max_complexity_anomaly_drill
|
||||
can_anchor = FALSE
|
||||
|
||||
/obj/item/electronic_assembly/medium/anomaly_drill/Initialize(mapload, printed = FALSE)
|
||||
. = ..()
|
||||
|
||||
var/obj/item/integrated_circuit/manipulation/xenoarch_precision_excavator/drill_controller = new(src)
|
||||
drill_controller.removable = FALSE
|
||||
drill_controller.assembly = src
|
||||
force_add_circuit(drill_controller)
|
||||
|
||||
|
||||
// Large assemblies.
|
||||
// These get a built-in, non-removable power network interface.
|
||||
|
||||
/obj/item/electronic_assembly/large
|
||||
name = "electronic machine"
|
||||
name = "large circuit machine"
|
||||
icon_state = "setup_large"
|
||||
desc = "It's a case, for building large electronics with."
|
||||
desc = "A case for building large electronic assemblies."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
max_components = IC_COMPONENTS_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
max_components = /obj/item/electronic_assembly::max_components_large_assembly
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_large_assembly
|
||||
can_anchor = TRUE
|
||||
supports_builtin_powernet = TRUE
|
||||
|
||||
/obj/item/electronic_assembly/large/Initialize(mapload, printed = FALSE)
|
||||
. = ..()
|
||||
add_builtin_powernet()
|
||||
|
||||
/obj/item/electronic_assembly/large/default
|
||||
name = "type-a electronic machine"
|
||||
name = "basic large circuit machine"
|
||||
|
||||
/obj/item/electronic_assembly/large/scope
|
||||
name = "type-b electronic machine"
|
||||
name = "oscilloscope large circuit machine"
|
||||
icon_state = "setup_large_scope"
|
||||
desc = "It's a case, for building large electronics with. This one resembles an oscilloscope."
|
||||
desc = "A case for building large electronic assemblies. This one resembles an oscilloscope."
|
||||
|
||||
/obj/item/electronic_assembly/large/terminal
|
||||
name = "type-c electronic machine"
|
||||
name = "terminal large circuit machine"
|
||||
icon_state = "setup_large_terminal"
|
||||
desc = "It's a case, for building large electronics with. This one resembles a computer terminal."
|
||||
desc = "A case for building large electronic assemblies. This one resembles a computer terminal."
|
||||
|
||||
/obj/item/electronic_assembly/large/arm
|
||||
name = "type-d electronic machine"
|
||||
name = "robotic arm large circuit machine"
|
||||
icon_state = "setup_large_arm"
|
||||
desc = "It's a case, for building large electronics with. This one resembles a robotic arm."
|
||||
desc = "A case for building large electronic assemblies. This one resembles a robotic arm."
|
||||
|
||||
/obj/item/electronic_assembly/large/tall
|
||||
name = "type-e electronic machine"
|
||||
name = "tall large circuit machine"
|
||||
icon_state = "setup_large_tall"
|
||||
desc = "It's a case, for building large electronics with. This one has a tall design."
|
||||
desc = "A case for building large electronic assemblies. This one has a tall design."
|
||||
|
||||
/obj/item/electronic_assembly/large/industrial
|
||||
name = "type-f electronic machine"
|
||||
name = "industrial large circuit machine"
|
||||
icon_state = "setup_large_industrial"
|
||||
desc = "It's a case, for building large electronics with. This one resembles some kind of industrial machinery."
|
||||
desc = "A case for building large electronic assemblies. This one resembles some kind of industrial machinery."
|
||||
|
||||
|
||||
// Drone assemblies, which can move with the locomotion circuit.
|
||||
|
||||
/obj/item/electronic_assembly/drone
|
||||
name = "electronic drone"
|
||||
name = "circuit drone"
|
||||
icon_state = "setup_drone"
|
||||
desc = "It's a case, for building mobile electronics with."
|
||||
desc = "A mobile case for building electronic assemblies."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 1.5
|
||||
max_complexity = IC_COMPLEXITY_BASE * 1.5
|
||||
max_components = /obj/item/electronic_assembly::max_components_drone
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_drone
|
||||
can_anchor = FALSE
|
||||
supports_builtin_locomotion = TRUE
|
||||
|
||||
/obj/item/electronic_assembly/drone/Initialize(mapload, printed = FALSE)
|
||||
. = ..()
|
||||
add_builtin_locomotion()
|
||||
|
||||
/obj/item/electronic_assembly/drone/can_move()
|
||||
return TRUE
|
||||
|
||||
/obj/item/electronic_assembly/drone/default
|
||||
name = "type-a electronic drone"
|
||||
name = "basic circuit drone"
|
||||
|
||||
/obj/item/electronic_assembly/drone/arms
|
||||
name = "type-b electronic drone"
|
||||
name = "armed circuit drone"
|
||||
icon_state = "setup_drone_arms"
|
||||
desc = "It's a case, for building mobile electronics with. This one is armed and dangerous."
|
||||
desc = "A mobile case for building weapon-capable electronic assemblies."
|
||||
|
||||
/obj/item/electronic_assembly/drone/medbot
|
||||
name = "type-d electronic drone"
|
||||
name = "medical circuit drone"
|
||||
icon_state = "setup_drone_medbot"
|
||||
desc = "It's a case, for building mobile electronics with. This one resembles a Medibot."
|
||||
desc = "A mobile case for building electronic assemblies. This one resembles a Medibot."
|
||||
|
||||
/obj/item/electronic_assembly/drone/genbot
|
||||
name = "type-e electronic drone"
|
||||
name = "utility circuit drone"
|
||||
icon_state = "setup_drone_genbot"
|
||||
desc = "It's a case, for building mobile electronics with. This one has a generic bot design."
|
||||
desc = "A mobile case for building electronic assemblies. This one has a generic bot design."
|
||||
|
||||
/obj/item/electronic_assembly/drone/android
|
||||
name = "type-f electronic drone"
|
||||
name = "android circuit drone"
|
||||
icon_state = "setup_drone_android"
|
||||
desc = "It's a case, for building mobile electronics with. This one has a hominoid design."
|
||||
desc = "A mobile case for building electronic assemblies. This one has a hominoid design."
|
||||
|
||||
|
||||
// Wall mounted assemblies.
|
||||
// These get a built-in, non-removable power network interface.
|
||||
|
||||
/obj/item/electronic_assembly/wallmount
|
||||
name = "wall-mounted electronic assembly"
|
||||
name = "medium wall-mounted circuit case"
|
||||
icon_state = "setup_wallmount_medium"
|
||||
desc = "It's a case, for building medium-sized electronics with. It has a magnetized \
|
||||
desc = "A case for building medium electronic assemblies. It has a magnetized \
|
||||
backing to allow it to stick to walls."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
max_components = IC_COMPONENTS_BASE * 2
|
||||
max_complexity = IC_COMPLEXITY_BASE * 2
|
||||
var/max_components_wallmount_heavy = 110
|
||||
var/max_complexity_wallmount_heavy = 240
|
||||
var/max_components_wallmount_light = IC_COMPONENTS_BASE
|
||||
var/max_complexity_wallmount_light = IC_COMPLEXITY_BASE
|
||||
var/max_components_wallmount_tiny = 12
|
||||
var/max_complexity_wallmount_tiny = 30
|
||||
max_components = /obj/item/electronic_assembly::max_components_wallmount
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_wallmount
|
||||
can_anchor = TRUE
|
||||
supports_builtin_powernet = TRUE
|
||||
|
||||
/obj/item/electronic_assembly/wallmount/Initialize(mapload, printed = FALSE)
|
||||
. = ..()
|
||||
add_builtin_powernet()
|
||||
|
||||
/obj/item/electronic_assembly/wallmount/proc/mount_assembly(turf/on_wall, mob/user)
|
||||
if(get_dist(on_wall,user) > 1)
|
||||
if(get_dist(on_wall, user) > 1)
|
||||
return
|
||||
|
||||
var/ndir = get_dir(on_wall, user)
|
||||
if(!(ndir in GLOB.cardinals))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(user)
|
||||
if(!istype(T, /turf/simulated/floor))
|
||||
to_chat(user, SPAN_WARNING("You cannot place \the [src] on this spot!"))
|
||||
return
|
||||
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 75, 1)
|
||||
user.visible_message("\The [user] attaches \the [src] to the wall.",
|
||||
|
||||
user.visible_message(
|
||||
"\The [user] attaches \the [src] to the wall.",
|
||||
SPAN_NOTICE("You attach \the [src] to the wall."),
|
||||
"<span class='italics'>You hear clicking.</span>")
|
||||
if(isrobot(user)) //Robots cannot unequip/drop items, for Safety Reasons.
|
||||
"<span class='italics'>You hear clicking.</span>"
|
||||
)
|
||||
|
||||
if(isrobot(user)) // Robots cannot unequip/drop items, for safety reasons.
|
||||
forceMove(T)
|
||||
user.drop_item(T)
|
||||
else
|
||||
user.drop_item(T)
|
||||
|
||||
anchored = TRUE
|
||||
on_anchored()
|
||||
set_pixel_offsets()
|
||||
@@ -222,31 +320,58 @@
|
||||
pixel_y = DIR2PIXEL_Y(dir)
|
||||
|
||||
/obj/item/electronic_assembly/wallmount/heavy
|
||||
name = "heavy wall-mounted electronic assembly"
|
||||
name = "large wall-mounted circuit machine"
|
||||
icon_state = "setup_wallmount_large"
|
||||
desc = "It's a case, for building large electronics with. It has a magnetized backing \
|
||||
desc = "A case for building large electronic assemblies. It has a magnetized backing \
|
||||
to allow it to stick to walls."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
max_components = IC_COMPONENTS_BASE * 4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 4
|
||||
max_components = /obj/item/electronic_assembly/wallmount::max_components_wallmount_heavy
|
||||
max_complexity = /obj/item/electronic_assembly/wallmount::max_complexity_wallmount_heavy
|
||||
|
||||
/obj/item/electronic_assembly/wallmount/light
|
||||
name = "light wall-mounted electronic assembly"
|
||||
name = "small wall-mounted circuit case"
|
||||
icon_state = "setup_wallmount_small"
|
||||
desc = "It's a case, for building small electronics with. It has a magnetized backing \
|
||||
desc = "A case for building small electronic assemblies. It has a magnetized backing \
|
||||
to allow it to stick to walls."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
max_components = IC_COMPONENTS_BASE
|
||||
max_complexity = IC_COMPLEXITY_BASE
|
||||
max_components = /obj/item/electronic_assembly/wallmount::max_components_wallmount_light
|
||||
max_complexity = /obj/item/electronic_assembly/wallmount::max_complexity_wallmount_light
|
||||
|
||||
/obj/item/electronic_assembly/wallmount/tiny
|
||||
name = "tiny wall-mounted electronic assembly"
|
||||
name = "tiny wall-mounted circuit case"
|
||||
icon_state = "setup_wallmount_tiny"
|
||||
desc = "It's a case, for building tiny electronics with. It has a magnetized backing \
|
||||
desc = "A case for building tiny electronic assemblies. It has a magnetized backing \
|
||||
to allow it to stick to walls."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_components = IC_COMPONENTS_BASE / 2
|
||||
max_complexity = IC_COMPLEXITY_BASE / 2
|
||||
max_components = /obj/item/electronic_assembly/wallmount::max_components_wallmount_tiny
|
||||
max_complexity = /obj/item/electronic_assembly/wallmount::max_complexity_wallmount_tiny
|
||||
|
||||
|
||||
// Built-in circuits.
|
||||
|
||||
/obj/item/electronic_assembly/proc/add_builtin_powernet()
|
||||
if(!supports_builtin_powernet)
|
||||
return
|
||||
|
||||
for(var/obj/item/integrated_circuit/passive/power/powernet/P in contents)
|
||||
return
|
||||
|
||||
var/obj/item/integrated_circuit/passive/power/powernet/builtin/P = new(src)
|
||||
P.removable = FALSE
|
||||
P.assembly = src
|
||||
force_add_circuit(P)
|
||||
|
||||
/obj/item/electronic_assembly/proc/add_builtin_locomotion()
|
||||
if(!supports_builtin_locomotion)
|
||||
return
|
||||
|
||||
for(var/obj/item/integrated_circuit/manipulation/locomotion/builtin/L in contents)
|
||||
return
|
||||
|
||||
var/obj/item/integrated_circuit/manipulation/locomotion/builtin/L = new(src)
|
||||
L.removable = FALSE
|
||||
L.assembly = src
|
||||
force_add_circuit(L)
|
||||
|
||||
/obj/item/electronic_assembly/proc/get_assembly_holder()
|
||||
return src
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
/*
|
||||
* core/device.dm
|
||||
* Base device support for electronics-related items that are not themselves circuit assemblies.
|
||||
*/
|
||||
|
||||
/obj/item/assembly/electronic_assembly
|
||||
name = "electronic device"
|
||||
desc = "It's a case for building electronics with. It can be attached to other small devices."
|
||||
desc = "A case for building electronics that can attach to other small devices."
|
||||
icon_state = "setup_device"
|
||||
// Whether the assembly panel is open for direct circuit access.
|
||||
var/opened = 0
|
||||
|
||||
var/obj/item/electronic_assembly/device/EA
|
||||
@@ -61,17 +67,17 @@
|
||||
set src in usr
|
||||
set category = "Object"
|
||||
set name = "Open/Close Device Assembly"
|
||||
set desc = "Open or close device assembly!"
|
||||
set desc = "Opens or closes the device assembly."
|
||||
|
||||
toggle_open(usr)
|
||||
|
||||
/obj/item/electronic_assembly/device
|
||||
name = "electronic device"
|
||||
icon_state = "setup_device"
|
||||
desc = "It's a tiny electronic device with specific use for attaching to other devices."
|
||||
desc = "A tiny electronic device designed to attach to other devices."
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_components = IC_COMPONENTS_BASE * 3/4
|
||||
max_complexity = IC_COMPLEXITY_BASE * 3/4
|
||||
max_components = /obj/item/electronic_assembly::max_components_device
|
||||
max_complexity = /obj/item/electronic_assembly::max_complexity_device
|
||||
|
||||
var/obj/item/assembly/electronic_assembly/holder
|
||||
var/obj/item/integrated_circuit/built_in/device_input/input
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
/*
|
||||
* core/helpers.dm
|
||||
* Utility procs for integrated electronics, including formatting, data conversion, cloning, list handling, and shared validation.
|
||||
*/
|
||||
|
||||
/obj/item/integrated_circuit/proc/setup_io(list/io_list, io_type, list/io_default_list)
|
||||
var/list/io_list_copy = io_list.Copy()
|
||||
io_list.Cut()
|
||||
var/i = 0
|
||||
for(var/io_entry in io_list_copy)
|
||||
i++
|
||||
|
||||
var/default_data = null
|
||||
var/io_type_override = null
|
||||
|
||||
// Override the default data.
|
||||
if(LAZYLEN(io_default_list)) // List containing special pin types that need to be added.
|
||||
default_data = io_default_list["[i]"] // This is deliberately text because the index is a number in text form.
|
||||
if(LAZYLEN(io_default_list))
|
||||
default_data = io_default_list["[i]"]
|
||||
|
||||
// Override the pin type.
|
||||
if(io_list_copy[io_entry])
|
||||
@@ -19,25 +27,32 @@
|
||||
io_list += new io_type(src, io_entry, default_data)
|
||||
|
||||
/obj/item/integrated_circuit/proc/set_pin_data(pin_type, pin_number, datum/new_data)
|
||||
if (istype(new_data) && !isweakref(new_data))
|
||||
if(istype(new_data) && !isweakref(new_data))
|
||||
new_data = WEAKREF(new_data)
|
||||
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
if (!pin)
|
||||
if(!pin)
|
||||
CRASH("Invalid pin ref.")
|
||||
return pin.write_data_to_pin(new_data)
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_data(pin_type, pin_number, var/resolve_weakrefs = TRUE)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
if(!pin)
|
||||
return null
|
||||
return pin.get_data(resolve_weakrefs)
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_data_as_type(pin_type, pin_number, as_type)
|
||||
var/datum/integrated_io/pin = get_pin_ref(pin_type, pin_number)
|
||||
if(!pin)
|
||||
return null
|
||||
return pin.data_as_type(as_type)
|
||||
|
||||
/obj/item/integrated_circuit/proc/activate_pin(pin_number)
|
||||
var/datum/integrated_io/activate/A = activators[pin_number]
|
||||
if(!A)
|
||||
return FALSE
|
||||
A.push_data(pin_number)
|
||||
return TRUE
|
||||
|
||||
/datum/integrated_io/proc/get_data(var/resolve_weakrefs = TRUE)
|
||||
if(resolve_weakrefs && isweakref(data))
|
||||
@@ -45,6 +60,9 @@
|
||||
return data
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_pin_ref(pin_type, pin_number)
|
||||
if(!pin_number || pin_number < 1)
|
||||
return null
|
||||
|
||||
switch(pin_type)
|
||||
if(IC_INPUT)
|
||||
if(pin_number > inputs.len)
|
||||
@@ -58,26 +76,389 @@
|
||||
if(pin_number > activators.len)
|
||||
return null
|
||||
return activators[pin_number]
|
||||
|
||||
return null
|
||||
|
||||
/obj/item/integrated_circuit/proc/handle_wire(datum/integrated_io/pin, obj/item/integrated_electronics/tool)
|
||||
if(!pin || !tool)
|
||||
return FALSE
|
||||
|
||||
if(istype(tool, /obj/item/integrated_electronics/wirer))
|
||||
var/obj/item/integrated_electronics/wirer/wirer = tool
|
||||
if(pin)
|
||||
wirer.wire(pin, usr)
|
||||
return 1
|
||||
wirer.wire(pin, usr)
|
||||
return TRUE
|
||||
|
||||
else if(istype(tool, /obj/item/integrated_electronics/debugger))
|
||||
if(istype(tool, /obj/item/integrated_electronics/debugger))
|
||||
var/obj/item/integrated_electronics/debugger/debugger = tool
|
||||
if(pin)
|
||||
debugger.write_data(pin, usr)
|
||||
return 1
|
||||
return 0
|
||||
debugger.write_data(pin, usr)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/proc/XorEncrypt(string, key)
|
||||
if(!string || !key ||!istext(string)||!istext(key))
|
||||
return
|
||||
if(!string || !key || !istext(string) || !istext(key))
|
||||
return null
|
||||
|
||||
var/r
|
||||
for(var/i = 1 to length(string))
|
||||
r += ascii2text(text2ascii(string,i) ^ text2ascii(key,(i-1)%length(string)+1))
|
||||
r += ascii2text(text2ascii(string, i) ^ text2ascii(key, (i - 1) % length(key) + 1))
|
||||
return r
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Integrated circuit helper procs.
|
||||
// These are intentionally generic so new circuits can reuse them
|
||||
// instead of duplicating null, list, text, number, and boolean checks.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
/proc/ic_is_null(value)
|
||||
return isnull(value)
|
||||
|
||||
/proc/ic_is_text(value)
|
||||
return istext(value)
|
||||
|
||||
/proc/ic_is_number(value)
|
||||
return isnum(value)
|
||||
|
||||
/proc/ic_is_list(value)
|
||||
return islist(value)
|
||||
|
||||
/proc/ic_is_ref(value)
|
||||
if(isweakref(value))
|
||||
return TRUE
|
||||
if(istype(value, /datum))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/proc/ic_is_safe_ref_atom(atom/A)
|
||||
if(!istype(A))
|
||||
return FALSE
|
||||
if(istype(A, /mob/abstract/ghost))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/proc/ic_truthy(value)
|
||||
if(isnull(value))
|
||||
return FALSE
|
||||
|
||||
if(isnum(value))
|
||||
return value != 0
|
||||
|
||||
if(istext(value))
|
||||
return length(value) > 0
|
||||
|
||||
if(islist(value))
|
||||
var/list/L = value
|
||||
return L.len > 0
|
||||
|
||||
return TRUE
|
||||
|
||||
/proc/ic_falsey(value)
|
||||
return !ic_truthy(value)
|
||||
|
||||
/proc/ic_safe_number(value, default_value = 0)
|
||||
if(isnum(value))
|
||||
return value
|
||||
|
||||
if(istext(value))
|
||||
var/converted = text2num(value)
|
||||
if(!isnull(converted))
|
||||
return converted
|
||||
|
||||
return default_value
|
||||
|
||||
/proc/ic_safe_text(value, default_value = "")
|
||||
if(isnull(value))
|
||||
return default_value
|
||||
|
||||
if(istext(value))
|
||||
return value
|
||||
|
||||
if(isnum(value))
|
||||
return num2text(value)
|
||||
|
||||
if(isweakref(value))
|
||||
var/datum/weakref/W = value
|
||||
var/datum/resolved = W.resolve()
|
||||
if(resolved)
|
||||
return "[resolved]"
|
||||
return default_value
|
||||
|
||||
return "[value]"
|
||||
|
||||
/proc/ic_safe_bool(value)
|
||||
return ic_truthy(value)
|
||||
|
||||
/proc/ic_display_value(value)
|
||||
if(isnull(value))
|
||||
return "null"
|
||||
|
||||
if(isweakref(value))
|
||||
var/datum/weakref/W = value
|
||||
var/datum/resolved = W.resolve()
|
||||
if(resolved)
|
||||
return "[resolved]"
|
||||
return "null ref"
|
||||
|
||||
if(islist(value))
|
||||
var/list/L = value
|
||||
return ic_list_to_text(L, ", ")
|
||||
|
||||
if(istext(value))
|
||||
return value
|
||||
|
||||
if(isnum(value))
|
||||
return num2text(value)
|
||||
|
||||
return "[value]"
|
||||
|
||||
/proc/ic_type_text(value)
|
||||
if(isnull(value))
|
||||
return "null"
|
||||
|
||||
if(isweakref(value))
|
||||
return "weakref"
|
||||
|
||||
if(isnum(value))
|
||||
return "number"
|
||||
|
||||
if(istext(value))
|
||||
return "string"
|
||||
|
||||
if(islist(value))
|
||||
return "list"
|
||||
|
||||
if(istype(value, /datum))
|
||||
return "ref"
|
||||
|
||||
return "unknown"
|
||||
|
||||
/proc/ic_list_to_text(list/L, separator = ", ")
|
||||
if(!islist(L))
|
||||
return ""
|
||||
|
||||
var/list/output = list()
|
||||
for(var/entry in L)
|
||||
output += ic_display_value(entry)
|
||||
|
||||
return jointext(output, separator)
|
||||
|
||||
/proc/ic_text_to_list(text, separator = ",")
|
||||
if(!istext(text))
|
||||
return list()
|
||||
|
||||
var/list/output = list()
|
||||
var/list/split_values = splittext(text, separator)
|
||||
|
||||
for(var/entry in split_values)
|
||||
output += trim(entry)
|
||||
|
||||
return output
|
||||
|
||||
/proc/ic_copy_list(list/L)
|
||||
if(!islist(L))
|
||||
return list()
|
||||
|
||||
return L.Copy()
|
||||
|
||||
/proc/ic_filter_nulls(list/L)
|
||||
if(!islist(L))
|
||||
return list()
|
||||
|
||||
var/list/output = list()
|
||||
for(var/entry in L)
|
||||
if(!isnull(entry))
|
||||
output += entry
|
||||
|
||||
return output
|
||||
|
||||
/proc/ic_list_contains(list/L, value)
|
||||
if(!islist(L))
|
||||
return FALSE
|
||||
|
||||
return L.Find(value) ? TRUE : FALSE
|
||||
|
||||
/proc/ic_list_length(list/L)
|
||||
if(!islist(L))
|
||||
return 0
|
||||
|
||||
return L.len
|
||||
|
||||
/proc/ic_clamp_number(value, minimum, maximum)
|
||||
var/number = ic_safe_number(value, minimum)
|
||||
|
||||
if(number < minimum)
|
||||
return minimum
|
||||
|
||||
if(number > maximum)
|
||||
return maximum
|
||||
|
||||
return number
|
||||
|
||||
/proc/ic_percent(value, maximum)
|
||||
var/number = ic_safe_number(value, 0)
|
||||
var/max_number = ic_safe_number(maximum, 0)
|
||||
|
||||
if(max_number <= 0)
|
||||
return 0
|
||||
|
||||
return (number / max_number) * 100
|
||||
|
||||
/proc/ic_range_check(value, minimum, maximum)
|
||||
var/number = ic_safe_number(value, 0)
|
||||
|
||||
if(number < minimum)
|
||||
return -1
|
||||
|
||||
if(number > maximum)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/proc/ic_range_text(value, minimum, maximum)
|
||||
var/range_result = ic_range_check(value, minimum, maximum)
|
||||
|
||||
if(range_result < 0)
|
||||
return "low"
|
||||
|
||||
if(range_result > 0)
|
||||
return "high"
|
||||
|
||||
return "normal"
|
||||
|
||||
/proc/ic_format_status(label, value)
|
||||
return "[ic_safe_text(label, "Status")]: [ic_display_value(value)]"
|
||||
|
||||
/proc/ic_format_warning(label, value)
|
||||
return "WARNING: [ic_safe_text(label, "Value")] [ic_display_value(value)]"
|
||||
|
||||
/proc/ic_format_error(label, value)
|
||||
return "ERROR: [ic_safe_text(label, "Value")] [ic_display_value(value)]"
|
||||
|
||||
/proc/ic_join_lines(list/L)
|
||||
if(!islist(L))
|
||||
return ""
|
||||
|
||||
var/list/output = list()
|
||||
for(var/entry in L)
|
||||
if(isnull(entry))
|
||||
continue
|
||||
output += ic_display_value(entry)
|
||||
|
||||
return jointext(output, "\n")
|
||||
|
||||
/proc/ic_make_saveable_value(value)
|
||||
if(isnull(value) || isnum(value) || istext(value))
|
||||
return value
|
||||
|
||||
if(isweakref(value))
|
||||
var/datum/weakref/W = value
|
||||
var/datum/resolved = W.resolve()
|
||||
if(resolved)
|
||||
return "[resolved]"
|
||||
return null
|
||||
|
||||
if(islist(value))
|
||||
var/list/source_list = value
|
||||
var/list/new_list = list()
|
||||
|
||||
for(var/entry in source_list)
|
||||
new_list += ic_make_saveable_value(entry)
|
||||
|
||||
return new_list
|
||||
|
||||
return "[value]"
|
||||
|
||||
/proc/ic_sanitize_template_value(value)
|
||||
var/text_value = ic_display_value(value)
|
||||
text_value = replacetext(text_value, "\n", " ")
|
||||
text_value = replacetext(text_value, ascii2text(13), " ")
|
||||
return text_value
|
||||
|
||||
/proc/ic_apply_template(template, value_1 = null, value_2 = null, value_3 = null, value_4 = null, value_5 = null, value_6 = null, value_7 = null, value_8 = null)
|
||||
if(!istext(template))
|
||||
return ""
|
||||
|
||||
var/output = template
|
||||
output = replacetext(output, "{1}", ic_sanitize_template_value(value_1))
|
||||
output = replacetext(output, "{2}", ic_sanitize_template_value(value_2))
|
||||
output = replacetext(output, "{3}", ic_sanitize_template_value(value_3))
|
||||
output = replacetext(output, "{4}", ic_sanitize_template_value(value_4))
|
||||
output = replacetext(output, "{5}", ic_sanitize_template_value(value_5))
|
||||
output = replacetext(output, "{6}", ic_sanitize_template_value(value_6))
|
||||
output = replacetext(output, "{7}", ic_sanitize_template_value(value_7))
|
||||
output = replacetext(output, "{8}", ic_sanitize_template_value(value_8))
|
||||
|
||||
return output
|
||||
|
||||
/proc/ic_get_nested_list_value(list/L, index, default_value = null)
|
||||
if(!islist(L))
|
||||
return default_value
|
||||
|
||||
var/number_index = round(ic_safe_number(index, 0))
|
||||
|
||||
if(number_index < 1 || number_index > L.len)
|
||||
return default_value
|
||||
|
||||
return L[number_index]
|
||||
|
||||
/proc/ic_set_nested_list_value(list/L, index, value)
|
||||
if(!islist(L))
|
||||
return list()
|
||||
|
||||
var/number_index = round(ic_safe_number(index, 0))
|
||||
|
||||
if(number_index < 1 || number_index > IC_MAX_LIST_LENGTH)
|
||||
return L
|
||||
|
||||
while(L.len < number_index)
|
||||
L += null
|
||||
|
||||
L[number_index] = value
|
||||
return L
|
||||
|
||||
/proc/ic_number_or_null(value)
|
||||
if(isnum(value))
|
||||
return value
|
||||
|
||||
if(istext(value))
|
||||
var/converted = text2num(value)
|
||||
if(!isnull(converted))
|
||||
return converted
|
||||
|
||||
return null
|
||||
|
||||
/proc/ic_add_numbers(value_1, value_2)
|
||||
var/A = ic_number_or_null(value_1)
|
||||
var/B = ic_number_or_null(value_2)
|
||||
|
||||
if(isnull(A) || isnull(B))
|
||||
return null
|
||||
|
||||
return A + B
|
||||
|
||||
/proc/ic_subtract_numbers(value_1, value_2)
|
||||
var/A = ic_number_or_null(value_1)
|
||||
var/B = ic_number_or_null(value_2)
|
||||
|
||||
if(isnull(A) || isnull(B))
|
||||
return null
|
||||
|
||||
return A - B
|
||||
|
||||
/proc/ic_multiply_numbers(value_1, value_2)
|
||||
var/A = ic_number_or_null(value_1)
|
||||
var/B = ic_number_or_null(value_2)
|
||||
|
||||
if(isnull(A) || isnull(B))
|
||||
return null
|
||||
|
||||
return A * B
|
||||
|
||||
/proc/ic_divide_numbers(value_1, value_2)
|
||||
var/A = ic_number_or_null(value_1)
|
||||
var/B = ic_number_or_null(value_2)
|
||||
|
||||
if(isnull(A) || isnull(B) || B == 0)
|
||||
return null
|
||||
|
||||
return A / B
|
||||
|
||||
@@ -29,6 +29,9 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit.
|
||||
return
|
||||
|
||||
/obj/item/integrated_circuit/proc/get_printer_spawn_flags()
|
||||
return spawn_flags
|
||||
|
||||
/obj/item/integrated_circuit/Destroy()
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
qdel(I)
|
||||
@@ -70,7 +73,7 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
/obj/item/integrated_circuit/verb/rename_component()
|
||||
set name = "Rename Circuit"
|
||||
set category = "Object"
|
||||
set desc = "Rename your circuit, useful to stay organized."
|
||||
set desc = "Renames the circuit to make assemblies easier to organize."
|
||||
|
||||
var/mob/M = usr
|
||||
if(!check_interactivity(M))
|
||||
@@ -175,7 +178,8 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
HTML += "<br><span class='highlight'>Power Draw: [power_draw_idle] W (Idle)</span>"
|
||||
if(power_draw_per_use)
|
||||
HTML += "<br><span class='highlight'>Power Draw: [power_draw_per_use] W (Active)</span>" // Borgcode says that powercells' checked_use() takes joules as input.
|
||||
HTML += "<br><span class='highlight'>[extended_desc]</span>"
|
||||
if(extended_desc)
|
||||
HTML += "<br><span class='highlight'>[extended_desc]</span>"
|
||||
|
||||
var/datum/browser/B = new(user, assembly ? "assembly-[REF(assembly)]" : "circuit-[REF(src)]", (displayed_name && displayed_name != name) ? "[displayed_name] ([name])" : name, window_width, window_height)
|
||||
B.set_content(HTML.Join())
|
||||
@@ -319,7 +323,7 @@ a creative player the means to solve many problems. Circuits are held inside an
|
||||
|
||||
/obj/item/integrated_circuit/proc/pull_data()
|
||||
for(var/datum/integrated_io/I in inputs)
|
||||
I.push_data()
|
||||
I.pull_data()
|
||||
|
||||
/obj/item/integrated_circuit/proc/draw_idle_power()
|
||||
if(assembly)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Pins both hold data for circuits, as well move data between them. Some also cause circuits to do their function. DATA_CHANNEL pins are the data holding/moving kind,
|
||||
where as PULSE_CHANNEL causes circuits to work() when their pulse hits them.
|
||||
whereas PULSE_CHANNEL causes circuits to work() when their pulse hits them.
|
||||
|
||||
|
||||
A visualization of how pins work is below. Imagine the below image involves an addition circuit.
|
||||
@@ -68,14 +68,15 @@ list[](
|
||||
|
||||
if(islist(input))
|
||||
var/list/my_list = input
|
||||
var/result = "list\[[my_list.len]\]("
|
||||
if(my_list.len)
|
||||
var/list_length = length(my_list)
|
||||
var/result = "list\[[list_length]\]("
|
||||
if(list_length)
|
||||
result += "<br>"
|
||||
var/pos = 0
|
||||
for(var/line in my_list)
|
||||
result += "[display_data(line)]"
|
||||
pos++
|
||||
if(pos != my_list.len)
|
||||
if(pos != list_length)
|
||||
result += ",<br>"
|
||||
result += "<br>"
|
||||
result += ")"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/boolean_pin.dm
|
||||
* Boolean pin type behavior and conversion for TRUE/FALSE style circuit values.
|
||||
*/
|
||||
|
||||
// These pins only contain 0 or 1. Null is not allowed.
|
||||
/datum/integrated_io/boolean
|
||||
name = "boolean pin"
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/char_pin.dm
|
||||
* Character/string single-character pin behavior and validation.
|
||||
*/
|
||||
|
||||
// These pins can only contain a 1 character string or null.
|
||||
/datum/integrated_io/char
|
||||
name = "char pin"
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/color_pin.dm
|
||||
* Color pin parsing, validation, and display handling for circuit color values.
|
||||
*/
|
||||
|
||||
// These pins can only contain a color (in the form of #FFFFFF) or null.
|
||||
/datum/integrated_io/color
|
||||
name = "color pin"
|
||||
@@ -13,18 +18,19 @@
|
||||
if(isnull(new_data) || istext(new_data))
|
||||
if(istext(new_data))
|
||||
new_data = uppertext(new_data)
|
||||
if(length(new_data) != 7) // We can hex if we want to, we can leave your strings behind
|
||||
return // Cause your strings don't hex and if they don't hex
|
||||
var/friends = copytext(new_data, 2, 8) // Well they're are no strings of mine
|
||||
// I say, we can go where we want to, a place where they will never find
|
||||
if(length(new_data) != 7)
|
||||
return
|
||||
if(copytext(new_data, 1, 2) != "#")
|
||||
return
|
||||
var/hex_digits = copytext(new_data, 2, 8)
|
||||
var/safety_dance = 1
|
||||
while(safety_dance >= 7) // And we can act like we come from out of this world.log
|
||||
var/hex = copytext(friends, safety_dance, safety_dance+1)
|
||||
if(!(hex in list("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F")))
|
||||
return // Leave the fake one far behind,
|
||||
while(safety_dance <= 6)
|
||||
var/hex = copytext(hex_digits, safety_dance, safety_dance + 1)
|
||||
if(!findtext("0123456789ABCDEF", hex))
|
||||
return
|
||||
safety_dance++
|
||||
|
||||
data = new_data // And we can hex
|
||||
data = new_data
|
||||
holder.on_data_written()
|
||||
|
||||
// This randomizes the color.
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/dir_pin.dm
|
||||
* Direction pin conversion and validation for BYOND direction constants.
|
||||
*/
|
||||
|
||||
// These pins can only contain directions (1,2,4,8...) or null.
|
||||
/datum/integrated_io/dir
|
||||
name = "dir pin"
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
// These pins contain a list. Null is not allowed.
|
||||
/*
|
||||
* core/special_pins/list_pin.dm
|
||||
* List pin serialization, display, cloning, and safety handling for list-valued circuit data.
|
||||
*/
|
||||
|
||||
// These pins contain a list.
|
||||
// Lists may contain strings, numbers, weakrefs, nested lists, or null.
|
||||
// Individual circuits are responsible for deciding what data types they accept.
|
||||
|
||||
/datum/integrated_io/list
|
||||
name = "list pin"
|
||||
data = list()
|
||||
@@ -6,14 +14,10 @@
|
||||
/datum/integrated_io/list/ask_for_pin_data(mob/user)
|
||||
interact(user)
|
||||
|
||||
// Positionless remove/Edit are a bit weird,
|
||||
// not sure if adding these buttons is quite a good idea.
|
||||
// They introduce uncertainty, since, in case of 2 elements,
|
||||
// they will work just with the 1st one
|
||||
/datum/integrated_io/list/proc/interact(mob/user)
|
||||
var/list/my_list = data
|
||||
var/t = "<h2>[src]</h2><br>"
|
||||
t += "List length: [my_list.len]<br>"
|
||||
t += "List length: [length(my_list)]<br>"
|
||||
t += "<a href='byond://?src=[REF(src)]'>Refresh</a> | "
|
||||
t += "<a href='byond://?src=[REF(src)];add=1'>Add</a> | "
|
||||
t += "<a href='byond://?src=[REF(src)];remove=1'>Remove</a> | "
|
||||
@@ -21,113 +25,161 @@
|
||||
t += "<a href='byond://?src=[REF(src)];swap=1'>Swap</a> | "
|
||||
t += "<a href='byond://?src=[REF(src)];clear=1'>Clear</a><br>"
|
||||
t += "<hr>"
|
||||
// Iterating by index simplifies editing/deletion in game,
|
||||
// since the href_list["pos"] var is consistent
|
||||
|
||||
for(var/i = 1; i <= length(my_list); i++)
|
||||
t += "#[i] | [display_data(my_list[i])] | "
|
||||
t += "<a href='byond://?src=[REF(src)];edit=1;pos=[i]'>Edit</a> | "
|
||||
t += "<a href='byond://?src=[REF(src)];remove=1;pos=[i]'>Remove</a><br>"
|
||||
|
||||
var/datum/browser/B = new(user, "list_pin_[REF(src)]", null, 500, 400)
|
||||
B.set_content(t)
|
||||
B.open(FALSE)
|
||||
|
||||
/datum/integrated_io/list/proc/add_to_list(mob/user, new_entry)
|
||||
if(!new_entry && user)
|
||||
new_entry = ask_for_data_type(user)
|
||||
// is_valid can't be used here, since is_valid checks "data" and has no arguments
|
||||
if(!isnull(new_entry))
|
||||
Add(new_entry)
|
||||
if(isnull(new_entry) && user)
|
||||
new_entry = ask_for_data_type(user, null, list("string", "number", "null"))
|
||||
|
||||
Add(new_entry)
|
||||
|
||||
/datum/integrated_io/list/proc/Add(new_entry)
|
||||
if(!islist(data))
|
||||
data = list()
|
||||
|
||||
var/list/my_list = data
|
||||
if(my_list.len > IC_MAX_LIST_LENGTH)
|
||||
|
||||
if(length(my_list) >= IC_MAX_LIST_LENGTH)
|
||||
my_list.Cut(1, 2)
|
||||
my_list.Add(new_entry)
|
||||
|
||||
my_list += list(new_entry)
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/proc/remove_from_list_by_position(mob/user, position)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
|
||||
if(!length(my_list))
|
||||
to_chat(user, SPAN_WARNING("The list is empty, there's nothing to remove."))
|
||||
return
|
||||
if(!position)
|
||||
|
||||
if(isnull(position))
|
||||
return
|
||||
if(position > my_list.len)
|
||||
|
||||
position = round(position)
|
||||
|
||||
if(position < 1 || position > length(my_list))
|
||||
return
|
||||
var/target_entry = my_list[position]
|
||||
// Should be able to remove nulls, since we can add a null to the list from the outside.
|
||||
my_list -= target_entry
|
||||
|
||||
my_list.Cut(position, position + 1)
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/proc/remove_from_list(mob/user, target_entry)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
|
||||
if(!length(my_list))
|
||||
to_chat(user, SPAN_WARNING("The list is empty, there's nothing to remove."))
|
||||
return
|
||||
if(!target_entry)
|
||||
|
||||
if(isnull(target_entry))
|
||||
target_entry = input("Which piece of data do you want to remove?", "Remove") as null|anything in my_list
|
||||
if(target_entry)
|
||||
my_list -= target_entry
|
||||
|
||||
if(!isnull(target_entry))
|
||||
var/position = my_list.Find(target_entry)
|
||||
if(position)
|
||||
my_list.Cut(position, position + 1)
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/proc/edit_in_list(mob/user, target_entry)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
|
||||
if(!length(my_list))
|
||||
to_chat(user, SPAN_WARNING("The list is empty, there's nothing to modify."))
|
||||
return
|
||||
if(!target_entry)
|
||||
|
||||
if(isnull(target_entry))
|
||||
target_entry = input("Which piece of data do you want to edit?", "Edit") as null|anything in my_list
|
||||
if(target_entry)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry)
|
||||
var/i = my_list.Find(target_entry)
|
||||
if(edited_entry)
|
||||
my_list[i] = edited_entry
|
||||
|
||||
/datum/integrated_io/list/proc/edit_in_list_by_position(mob/user, var/position)
|
||||
if(!isnull(target_entry))
|
||||
var/i = my_list.Find(target_entry)
|
||||
if(i)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry, list("string", "number", "null"))
|
||||
my_list[i] = edited_entry
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/proc/edit_in_list_by_position(mob/user, position)
|
||||
var/list/my_list = data
|
||||
if(!my_list.len)
|
||||
|
||||
if(!length(my_list))
|
||||
to_chat(user, SPAN_WARNING("The list is empty, there's nothing to modify."))
|
||||
return
|
||||
if(!position)
|
||||
return
|
||||
if(position > my_list.len)
|
||||
return
|
||||
var/target_entry = my_list[position]
|
||||
if(target_entry)
|
||||
var/edited_entry = ask_for_data_type(user, target_entry)
|
||||
if(edited_entry)
|
||||
my_list[position] = edited_entry
|
||||
|
||||
/datum/integrated_io/list/proc/swap_inside_list(mob/user, var/first_target, var/second_target)
|
||||
if(isnull(position))
|
||||
return
|
||||
|
||||
position = round(position)
|
||||
|
||||
if(position < 1 || position > length(my_list))
|
||||
return
|
||||
|
||||
var/target_entry = my_list[position]
|
||||
var/edited_entry = ask_for_data_type(user, target_entry, list("string", "number", "null"))
|
||||
my_list[position] = edited_entry
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/proc/swap_inside_list(mob/user, first_target, second_target)
|
||||
var/list/my_list = data
|
||||
if(my_list.len <= 1)
|
||||
|
||||
if(length(my_list) <= 1)
|
||||
to_chat(user, SPAN_WARNING("The list is empty, or too small to do any meaningful swapping."))
|
||||
return
|
||||
if(!first_target)
|
||||
|
||||
if(isnull(first_target))
|
||||
first_target = input("Which piece of data do you want to swap? (1)", "Swap") as null|anything in my_list
|
||||
|
||||
if(first_target)
|
||||
if(!second_target)
|
||||
second_target = input("Which piece of data do you want to swap? (2)", "Swap") as null|anything in my_list - first_target
|
||||
if(isnull(first_target))
|
||||
return
|
||||
|
||||
if(second_target)
|
||||
var/first_pos = my_list.Find(first_target)
|
||||
var/second_pos = my_list.Find(second_target)
|
||||
my_list.Swap(first_pos, second_pos)
|
||||
if(isnull(second_target))
|
||||
second_target = input("Which piece of data do you want to swap? (2)", "Swap") as null|anything in my_list - first_target
|
||||
|
||||
if(isnull(second_target))
|
||||
return
|
||||
|
||||
var/first_pos = my_list.Find(first_target)
|
||||
var/second_pos = my_list.Find(second_target)
|
||||
|
||||
if(first_pos && second_pos)
|
||||
my_list.Swap(first_pos, second_pos)
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/proc/clear_list(mob/user)
|
||||
var/list/my_list = data
|
||||
my_list.Cut()
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/scramble()
|
||||
var/list/my_list = data
|
||||
my_list = shuffle(my_list)
|
||||
data = shuffle(my_list)
|
||||
push_data()
|
||||
|
||||
/datum/integrated_io/list/write_data_to_pin(var/new_data)
|
||||
if(islist(new_data))
|
||||
var/list/new_list = new_data
|
||||
// Sanitize the input - no nulls allowed.
|
||||
while(new_list.Remove(null) == 1)
|
||||
data = new_list.Copy()
|
||||
if(isnull(new_data))
|
||||
data = list()
|
||||
holder.on_data_written()
|
||||
return
|
||||
|
||||
if(!islist(new_data))
|
||||
return
|
||||
|
||||
var/list/new_list = new_data
|
||||
var/list/sanitized = list()
|
||||
|
||||
for(var/value in new_list)
|
||||
if(sanitized.len >= IC_MAX_LIST_LENGTH)
|
||||
break
|
||||
if(isnull(value) || isnum(value) || istext(value) || isweakref(value) || islist(value))
|
||||
sanitized += list(value)
|
||||
|
||||
data = sanitized
|
||||
holder.on_data_written()
|
||||
|
||||
/datum/integrated_io/list/display_pin_type()
|
||||
return IC_FORMAT_LIST
|
||||
@@ -135,8 +187,9 @@
|
||||
/datum/integrated_io/list/Topic(href, href_list, state = GLOB.always_state)
|
||||
if(!holder.check_interactivity(usr))
|
||||
return
|
||||
|
||||
if(..())
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(href_list["add"])
|
||||
add_to_list(usr)
|
||||
@@ -159,5 +212,7 @@
|
||||
else
|
||||
edit_in_list(usr)
|
||||
|
||||
holder.interact(usr) // Refresh the main UI,
|
||||
interact(usr) // and the list UI.
|
||||
holder.interact(usr)
|
||||
interact(usr)
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/number_pin.dm
|
||||
* Number pin conversion, validation, and formatting.
|
||||
*/
|
||||
|
||||
// These pins can only contain numbers (int and floating point) or null.
|
||||
/datum/integrated_io/number
|
||||
name = "number pin"
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/ref_pin.dm
|
||||
* Reference pin behavior for passing object references between circuits.
|
||||
*/
|
||||
|
||||
// These pins only contain weakrefs or null.
|
||||
/datum/integrated_io/ref
|
||||
name = "ref pin"
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/special_pins/string_pin.dm
|
||||
* String pin conversion, validation, and formatting.
|
||||
*/
|
||||
|
||||
// These pins can only contain text and null.
|
||||
/datum/integrated_io/string
|
||||
name = "string pin"
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* core/tools.dm
|
||||
* Tools used to manipulate integrated electronics, such as wiring, debugging, and assembly maintenance helpers.
|
||||
*/
|
||||
|
||||
#define WIRE "wire"
|
||||
#define WIRING "wiring"
|
||||
#define UNWIRE "unwire"
|
||||
@@ -176,6 +181,7 @@
|
||||
icon_state = "detailer"
|
||||
item_flags = ITEM_FLAG_NO_BLUDGEON
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
// User-selected detail color used for assembly and wearable overlays.
|
||||
var/detail_color = COLOR_ASSEMBLY_WHITE
|
||||
var/static/list/color_list = list(
|
||||
"black" = COLOR_ASSEMBLY_BLACK,
|
||||
@@ -217,7 +223,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits
|
||||
name = "circuit kit"
|
||||
desc = "This kit is essential for any circuitry projects."
|
||||
desc = "A kit containing basic tools and parts for circuit projects."
|
||||
icon = 'icons/obj/assemblies/electronic_tools.dmi'
|
||||
icon_state = "circuit_kit"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
@@ -279,7 +285,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini
|
||||
name = "circuit box"
|
||||
desc = "Used to partition categories of circuits, for a neater workspace."
|
||||
desc = "Stores circuits by category for easier organization."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
display_contents_with_number = TRUE
|
||||
pickup_blacklist = list(
|
||||
@@ -299,7 +305,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/arithmetic
|
||||
name = "arithmetic circuit box"
|
||||
desc = "Warning: Contains math."
|
||||
desc = "Contains arithmetic and numeric utility circuits."
|
||||
icon_state = "box_arithmetic"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/arithmetic
|
||||
@@ -310,7 +316,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/trig
|
||||
name = "trig circuit box"
|
||||
desc = "Danger: Contains more math."
|
||||
desc = "Contains trigonometric circuits."
|
||||
icon_state = "box_trig"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/trig
|
||||
@@ -321,7 +327,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/input
|
||||
name = "input circuit box"
|
||||
desc = "Tell these circuits everything you know."
|
||||
desc = "Contains circuits that read data from the surrounding environment."
|
||||
icon_state = "box_input"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/input
|
||||
@@ -332,7 +338,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/output
|
||||
name = "output circuit box"
|
||||
desc = "Circuits to interface with the world beyond itself."
|
||||
desc = "Contains circuits that display, announce, or transmit data."
|
||||
icon_state = "box_output"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/output
|
||||
@@ -343,7 +349,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/memory
|
||||
name = "memory circuit box"
|
||||
desc = "Machines can be quite forgetful without these."
|
||||
desc = "Contains memory circuits for storing circuit data."
|
||||
icon_state = "box_memory"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/memory
|
||||
@@ -354,7 +360,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/logic
|
||||
name = "logic circuit box"
|
||||
desc = "May or may not be Turing complete."
|
||||
desc = "Contains logic circuits for boolean-style control and comparisons."
|
||||
icon_state = "box_logic"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/logic
|
||||
@@ -365,18 +371,55 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/time
|
||||
name = "time circuit box"
|
||||
desc = "No time machine parts, sadly."
|
||||
desc = "Contains timer and clock circuits."
|
||||
icon_state = "box_time"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/time
|
||||
)
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/time/fill()
|
||||
var/list/basic_time_circuits = list(
|
||||
/obj/item/integrated_circuit/time/delay,
|
||||
/obj/item/integrated_circuit/time/delay/five_sec,
|
||||
/obj/item/integrated_circuit/time/delay/one_sec,
|
||||
/obj/item/integrated_circuit/time/delay/half_sec,
|
||||
/obj/item/integrated_circuit/time/delay/tenth_sec,
|
||||
/obj/item/integrated_circuit/time/ticker/fast,
|
||||
/obj/item/integrated_circuit/time/ticker,
|
||||
/obj/item/integrated_circuit/time/ticker/slow,
|
||||
/obj/item/integrated_circuit/time/ticker/very_slow,
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
)
|
||||
for(var/circuit_type in basic_time_circuits)
|
||||
for(var/i in 1 to 4)
|
||||
new circuit_type(src)
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/time/all
|
||||
spawn_flags_to_use = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/time/all/fill()
|
||||
var/list/all_time_circuits = list(
|
||||
/obj/item/integrated_circuit/time/delay,
|
||||
/obj/item/integrated_circuit/time/delay/five_sec,
|
||||
/obj/item/integrated_circuit/time/delay/one_sec,
|
||||
/obj/item/integrated_circuit/time/delay/half_sec,
|
||||
/obj/item/integrated_circuit/time/delay/tenth_sec,
|
||||
/obj/item/integrated_circuit/time/delay/custom,
|
||||
/obj/item/integrated_circuit/time/ticker/rapid,
|
||||
/obj/item/integrated_circuit/time/ticker/fast,
|
||||
/obj/item/integrated_circuit/time/ticker,
|
||||
/obj/item/integrated_circuit/time/ticker/slow,
|
||||
/obj/item/integrated_circuit/time/ticker/very_slow,
|
||||
/obj/item/integrated_circuit/time/ticker/custom,
|
||||
/obj/item/integrated_circuit/time/clock
|
||||
)
|
||||
for(var/circuit_type in all_time_circuits)
|
||||
for(var/i in 1 to 4)
|
||||
new circuit_type(src)
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/reagents
|
||||
name = "reagent circuit box"
|
||||
desc = "Unlike most electronics, these circuits are supposed to come in contact with liquids."
|
||||
desc = "Contains circuits for handling reagents and containers."
|
||||
icon_state = "box_reagents"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/reagent
|
||||
@@ -387,7 +430,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/transfer
|
||||
name = "transfer circuit box"
|
||||
desc = "Useful for moving data representing something arbitrary to another arbitrary virtual place."
|
||||
desc = "Contains circuits for routing data between pins and devices."
|
||||
icon_state = "box_transfer"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/transfer
|
||||
@@ -398,7 +441,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/converter
|
||||
name = "converter circuit box"
|
||||
desc = "Transform one piece of data to another type of data with these."
|
||||
desc = "Contains circuits for converting data between supported formats."
|
||||
icon_state = "box_converter"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/converter
|
||||
@@ -409,7 +452,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/smart
|
||||
name = "smart box"
|
||||
desc = "Sentience not included."
|
||||
desc = "Contains smart control circuits for navigation and automation."
|
||||
icon_state = "box_ai"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/smart
|
||||
@@ -420,7 +463,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/manipulation
|
||||
name = "manipulation box"
|
||||
desc = "Make your machines actually useful with these."
|
||||
desc = "Contains circuits that perform physical actions through an assembly."
|
||||
icon_state = "box_manipulation"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/manipulation
|
||||
@@ -431,7 +474,7 @@
|
||||
|
||||
/obj/item/storage/bag/circuits/mini/power
|
||||
name = "power circuit box"
|
||||
desc = "Electronics generally require electricity."
|
||||
desc = "Contains circuits that generate, receive, or transmit power."
|
||||
icon_state = "box_power"
|
||||
spawn_types = list(
|
||||
/obj/item/integrated_circuit/passive/power,
|
||||
|
||||
Reference in New Issue
Block a user