Move autolathe design datums to techweb datums (#19202)

* testing makes me feel good

* invalid lists

* get rid of those boards

* show expected mats

* oop

* error

* wip techweb porting

* more techweb entries

* ported too

* disable those for now

* okay nevermind i guess

* already exists

* assemblies

* moar

* welding helmet

* many entries

* lol tg

* fix test

* again

* fixagain

* more moved

* update techweb test

* catch that too

* screeee

* more fixes

* missing announcement

* orphaned sleevecard

* some more fixing

* test

* more

* oops

* glasses

* illegal icons

* non starting

* it's starting

* messed up

* cleanup

* more generic stuff

* morrrreee

* the plastic set

* oops

* correct value

* barbed wires

* more cleaning

* many more

* gone

* cleanup

* no longer

* do not allow duped designs

* it's own node

* proper order no dupes

* last of the broken nodes

* fix bad path

* cleanup

* more test more limits

* gone

* almost done

* these are gone

* syringe gun

* bioregenerator design

* all moved

* organized and webbed

* more fixes

* oops

* cleaning up

* organization

* clean up

* organize

* organized

* didn't save

* wrong mat

* adds many missing ammo types

* svd doesn't exist

* 10mm pistol added

* magazines not casings

* these are pistols

* this is used by like, one weapon

* m1 is ancient

* this is hunting

* extremely botched untested lathe

* disk junk

* rough foundations

* slowly converting

* slowly building this

* local materials

* almost

* big reorganization

* more cleanup

* more cleaning

* lathe stuff

* small fixes

* oops

* many fixes

* mat fix

* more fixes

* actually isolate the hacked designs

* protolathe hacking

* imprinter hacking

* missing ammos

* sheet printing for autolathe

* fixs

* again

* fixed test

* test test

* fix

* fix

* WHY

* fix it...

* here we go

* material print

* on turf

* body disk

* consistant name

* Many weapons to hacked lathe

* missing node

* wrong section

* fixes

* this list should be unified

* ammo boxes

* don't do single shells anymore

* wat

* specifics

* snowflake

* not needed

* already available

* pickaxe too

* tweak

* removed unneeded node

* missing surgery items

* Apply suggestion from @Cameron-The-Raven

* Adds RMS

* typo

* illegal needs hacked

* disabled material weapons

* circuit testing

* STRING TEST

* test

* fixing some things

* huh?

* hidden circuits

* some flakey boards

* grammar

* fixes

* more hidden

* wrong board

* security cams

* alert consoles

* spaceheater is simple enough to not have one

* pcus

* cargo vendors

* tcomms stuff

* solar tracker circuit

* artifact stuff

* SM stuff

* illegal machines

* med machines

* no longer needed

* more stuff

* these are not standard

* moreeee

* doppler and more

* organized

* finishing

* oop

* use the define

* inheret

* dopper fixes

* space heater

* doing some organization

* explain the var

* some tweaks

* wrong one

* fixed test

* material test too

* simple roto gens

* use the define

* emergency power node

* tgui fixes for icons

* not needed

* color blended material designs

* icons for large research

* oops

* unshit that

* use stack here

* center math

* .

* .

* .

* .

* .

* unifi

* fix these

* NO COPYPASTA

* ILLEEGGALLL

* mandate descriptions

* agony

* actually lets do this

* use macros

* description

* desc

* desc

* desc

* desc

* desc

* desc

* gps desc

* telecomms component desc

---------

Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
Will
2026-03-20 19:38:00 -04:00
committed by GitHub
co-authored by Cameron Lennox Kashargul
parent 4c61dc7932
commit 0c8488b0ae
126 changed files with 5731 additions and 2372 deletions
+385 -189
View File
@@ -1,6 +1,6 @@
/obj/machinery/autolathe
name = "autolathe"
desc = "It produces items using metal and glass."
desc = "It produces items using steel, glass, plastic and maybe some more."
icon_state = "autolathe"
density = TRUE
anchored = TRUE
@@ -14,114 +14,393 @@
var/static/datum/category_collection/autolathe/autolathe_recipes
var/hacked = 0
var/disabled = 0
var/shocked = 0
var/busy = 0
var/mat_efficiency = 1
var/build_time = 50
///Is the autolathe hacked via wiring
var/hacked = FALSE
///Is the autolathe disabled via wiring
var/disabled = FALSE
///Did we recently shock a mob who medled with the wiring
var/shocked = FALSE
///Are we currently printing something
var/busy = FALSE
var/datum/wires/autolathe/wires = null
var/mb_rating = 0
var/man_rating = 0
var/filtertext
/// Reference to a remote material inventory, such as an ore silo.
var/datum/component/remote_materials/rmat
///Coefficient applied to consumed materials. Lower values result in lower material consumption.
var/creation_efficiency = 1.6
///Designs related to the autolathe
var/datum/techweb/autounlocking/stored_research
///Designs imported from technology disks that we can print.
var/list/imported_designs = list()
///The container to hold materials
var/datum/component/material_container/materials
///direction we output onto (if 0, on top of us)
var/drop_direction = 0
//looping sound for printing items
var/datum/looping_sound/lathe_print/print_sound
/obj/machinery/autolathe/Initialize(mapload)
rmat = AddComponent( \
/datum/component/remote_materials, \
mapload, \
mat_container_signals = list( \
COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/autolathe, AfterMaterialInsert) \
))
print_sound = new(list(src), FALSE, TRUE)
materials = AddComponent( \
/datum/component/material_container, \
subtypesof(/datum/material), \
0, \
MATCONTAINER_EXAMINE, \
container_signals = list(COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/autolathe, AfterMaterialInsert)) \
)
. = ..()
if(!autolathe_recipes)
autolathe_recipes = new()
wires = new(src)
if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe])
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe] = new /datum/techweb/autounlocking/autolathe
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe]
default_apply_parts()
RefreshParts()
/obj/machinery/autolathe/Destroy()
qdel(wires)
wires = null
QDEL_NULL(wires)
QDEL_NULL(print_sound)
return ..()
/obj/machinery/autolathe/examine(mob/user)
. = ..()
if(!in_range(user, src) && !isobserver(user))
return
. += span_notice("Material usage cost at <b>[creation_efficiency * 100]%</b>.")
if(drop_direction)
. += span_notice("Currently configured to drop printed objects <b>[dir2text(drop_direction)]</b>.")
. += span_notice("Alt-click to reset.")
else
. += span_notice("Drag towards a direction (while next to it) to change drop direction.")
. += span_notice("Its maintenance panel is [!panel_open ? "closed" : "open"].")
/*
/obj/machinery/autolathe/add_context(atom/source, list/context, obj/item/held_item, mob/user)
if(drop_direction)
context[SCREENTIP_CONTEXT_ALT_LMB] = "Reset Drop"
return CONTEXTUAL_SCREENTIP_SET
if(isnull(held_item))
return NONE
if(held_item.tool_behaviour == TOOL_SCREWDRIVER)
context[SCREENTIP_CONTEXT_LMB] = "[panel_open ? "Close" : "Open"] Panel"
return CONTEXTUAL_SCREENTIP_SET
if(panel_open && held_item.tool_behaviour == TOOL_CROWBAR)
context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
return CONTEXTUAL_SCREENTIP_SET
/obj/machinery/autolathe/crowbar_act(mob/living/user, obj/item/tool)
. = NONE
if(default_deconstruction_crowbar(tool))
return ITEM_INTERACT_SUCCESS
/obj/machinery/autolathe/screwdriver_act(mob/living/user, obj/item/tool)
. = ITEM_INTERACT_BLOCKING
if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", tool))
return ITEM_INTERACT_SUCCESS
*/
/obj/machinery/autolathe/tgui_status(mob/user)
if(disabled)
return STATUS_CLOSE
return ..()
/obj/machinery/autolathe/attack_hand(mob/user as mob)
interact(user)
/obj/machinery/autolathe/interact(mob/user)
if(panel_open)
return wires.Interact(user)
if(stat & (NOPOWER | EMPED))
return
if(shocked && !(stat & NOPOWER))
shock(user, 50)
return
tgui_interact(user)
/obj/machinery/autolathe/proc/AfterMaterialInsert(datum/source, obj/item/item_inserted, id_inserted, amount_inserted)
SIGNAL_HANDLER
flick("autolathe_loading", src)//plays metal insertion animation
// use_power(min(1000, amount_inserted / 100))
SStgui.update_uis(src)
/obj/machinery/autolathe/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Autolathe", name)
ui.open()
/obj/machinery/autolathe/tgui_status(mob/user)
if(disabled)
return STATUS_CLOSE
return ..()
/**
* Converts all the designs supported by this autolathe into UI data
* Arguments
*
* * list/designs - the list of techweb designs we are trying to send to the UI
*/
/obj/machinery/autolathe/proc/handle_designs(list/designs)
PRIVATE_PROC(TRUE)
if(!length(designs))
return list()
var/list/output = list()
var/datum/asset/spritesheet_batched/research_designs/spritesheet = get_asset_datum(/datum/asset/spritesheet_batched/research_designs)
var/size32x32 = "[spritesheet.name]32x32"
for(var/design_id in designs)
var/datum/design_techweb/design = SSresearch.techweb_design_by_id(design_id)
if(design.make_reagent)
continue
if(!hacked && (RND_CATEGORY_HACKED in design.category))
continue
//compute cost & maximum number of printable items
var/coeff = (ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency)
var/list/cost = list()
for(var/id in design.materials)
var/datum/material/mat = get_material_by_name(id)
cost[mat.name] = OPTIMAL_COST(design.materials[id] * coeff)
//create & send ui data
var/css_id = sanitize_css_class_name(design.id)
var/size = spritesheet.icon_size_id(css_id)
var/list/design_data = list(
"name" = design.name,
"desc" = design.get_description(),
"cost" = cost,
"id" = design.id,
"categories" = design.category,
"icon" = "[size == size32x32 ? "" : "[size] "][css_id]"
)
output += list(design_data)
return output
/obj/machinery/autolathe/tgui_static_data(mob/user)
var/list/data = ..()
var/list/data = materials.tgui_static_data()
var/list/categories = list()
var/list/recipes = list()
for(var/datum/category_group/autolathe/A in autolathe_recipes.categories)
categories += A.name
for(var/datum/category_item/autolathe/M in A.items)
if(M.hidden && !hacked)
continue
if(M.man_rating > man_rating)
continue
recipes.Add(list(list(
"category" = A.name,
"name" = M.name,
"ref" = REF(M),
"requirements" = M.resources,
"hidden" = M.hidden,
"coeff_applies" = !M.no_scale,
"is_stack" = M.is_stack,
)))
data["recipes"] = recipes
data["categories"] = categories
var/list/material_data = rmat.mat_container?.tgui_static_data(user)
if(material_data)
data += material_data
data["designs"] = handle_designs(stored_research.researched_designs)
data["designs"] += handle_designs(imported_designs)
return data
/obj/machinery/autolathe/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet_batched/sheetmaterials)
get_asset_datum(/datum/asset/spritesheet_batched/sheetmaterials),
get_asset_datum(/datum/asset/spritesheet_batched/research_designs),
)
/obj/machinery/autolathe/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
var/list/data = ..()
data["busy"] = busy
var/list/data = list()
data["materialtotal"] = materials.total_amount()
data["materialsmax"] = materials.max_amount
data["active"] = busy
data["materials"] = materials.tgui_data()
var/list/material_data = rmat.mat_container?.tgui_data(user, TRUE)
if(material_data)
data["materials"] = material_data
data["mat_efficiency"] = mat_efficiency
return data
/obj/machinery/autolathe/interact(mob/user)
if(panel_open)
return wires.Interact(user)
/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
if(disabled)
to_chat(user, span_danger("\The [src] is disabled!"))
add_fingerprint(ui.user)
//sanity checks to start printing
if(action != "make")
stack_trace("unknown autolathe ui_act: [action]")
return
if(shocked)
shock(user, 50)
if(disabled)
atom_say("Unable to print, voltage mismatch in internal wiring.")
return
tgui_interact(user)
if(busy)
atom_say("The autolathe is busy. Please wait for completion of previous operation.")
return
//validate design
var/design_id = params["id"]
if(!design_id)
return
var/valid_design = stored_research.researched_designs[design_id]
valid_design ||= imported_designs[design_id]
if(!valid_design)
return
var/datum/design_techweb/design = SSresearch.techweb_design_by_id(design_id)
if(isnull(design))
stack_trace("got passed an invalid design id: [design_id] and somehow made it past all checks")
return
if(!(design.build_type & AUTOLATHE))
atom_say("This fabricator does not have the necessary keys to decrypt this design.")
return
//validate print quantity
var/build_count = params["multiplier"]
if(isnull(build_count))
return
build_count = text2num(build_count)
if(isnull(build_count))
return
build_count = clamp(build_count, 1, 50)
// Check for materials required. For custom material items decode their required materials
var/list/materials_needed = list()
for(var/id, amount_needed in design.materials)
var/datum/material = get_material_by_name(id)
if(!istype(material, /datum/material))
CRASH("Autolathe ui_act got passed an invalid material id: [material]")
materials_needed[material] += amount_needed
//checks for available materials
var/material_cost_coefficient = ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency
if(!materials.has_materials(materials_needed, material_cost_coefficient, build_count))
atom_say("Not enough materials to begin production.")
return
//compute power & time to print 1 item
var/charge_per_item = 0
for(var/material, amount in design.materials)
charge_per_item += amount
charge_per_item = ROUND_UP((charge_per_item / (MAX_STACK_SIZE * SHEET_MATERIAL_AMOUNT)) * material_cost_coefficient * active_power_usage)
var/build_time_per_item = (design.construction_time * design.lathe_time_factor) ** 0.8
//do the printing sequentially
busy = TRUE
icon_state = "autolathe_n"
SStgui.update_uis(src)
// play this after all checks passed individually for each item.
print_sound.start()
var/turf/target_location
if(drop_direction)
target_location = get_step(src, drop_direction)
if(target_location.density)
target_location = get_turf(src)
else
target_location = get_turf(src)
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, build_count, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target_location), build_time_per_item)
return TRUE
/**
* Callback for start_making, actually makes the item
* Arguments
*
* * datum/design/design - the design we are trying to print
* * items_remaining - the number of designs left out to print
* * build_time_per_item - the time taken to print 1 item
* * material_cost_coefficient - the cost efficiency to print 1 design
* * charge_per_item - the amount of power to print 1 item
* * list/materials_needed - the list of materials to print 1 item
* * turf/target - the location to drop the printed item on
*/
/obj/machinery/autolathe/proc/do_make_item(datum/design_techweb/design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, list/materials_needed, turf/target)
PROTECTED_PROC(TRUE)
if(items_remaining <= 0) // how
finalize_build()
return
if(stat & (NOPOWER|EMPED))
atom_say("Unable to continue production, power failure.")
finalize_build()
return
if(!use_power_oneoff(charge_per_item)) // provide the wait time until lathe is ready
var/area/my_area = get_area(src)
var/obj/machinery/power/apc/my_apc = my_area.apc
if(!QDELETED(my_apc))
atom_say("Unable to continue production, power grid overload.")
else
atom_say("Unable to continue production, no APC in area.")
finalize_build()
return
var/is_stack = ispath(design.build_path, /obj/item/stack)
if(!materials.has_materials(materials_needed, material_cost_coefficient, is_stack ? items_remaining : 1))
atom_say("Unable to continue production, missing materials.")
finalize_build()
return
materials.use_materials(materials_needed, material_cost_coefficient, is_stack ? items_remaining : 1)
var/atom/movable/created
if(is_stack)
var/obj/item/stack/stack_item = initial(design.build_path)
var/max_stack_amount = initial(stack_item.max_amount)
var/number_to_make = (initial(stack_item.amount) * items_remaining)
while(number_to_make > max_stack_amount)
created = new stack_item(null, max_stack_amount) //it's imporant to spawn things in nullspace, since obj's like stacks qdel when they enter a tile/merge with other stacks of the same type, resulting in runtimes.
if(isitem(created))
created.pixel_x = rand(-6, 6)
created.pixel_y = rand(-6, 6)
created.forceMove(target)
number_to_make -= max_stack_amount
created = new stack_item(target, number_to_make)
else
created = design.create_item(target)
split_materials_uniformly(materials_needed, material_cost_coefficient, created)
if(isitem(created))
created.pixel_x = rand(-6, 6)
created.pixel_y = rand(-6, 6)
if(is_stack)
items_remaining = 0
else
items_remaining -= 1
if(items_remaining <= 0)
finalize_build()
return
addtimer(CALLBACK(src, PROC_REF(do_make_item), design, items_remaining, build_time_per_item, material_cost_coefficient, charge_per_item, materials_needed, target), build_time_per_item)
/**
* Resets the icon state and busy flag
* Called at the end of do_make_item's timer loop
*/
/obj/machinery/autolathe/proc/finalize_build()
PROTECTED_PROC(TRUE)
print_sound.stop()
icon_state = initial(icon_state)
busy = FALSE
SStgui.update_uis(src)
/obj/machinery/autolathe/MouseDrop(over_object, src_location, over_location)
if(isobserver(usr) || !Adjacent(usr))
return
if(busy)
balloon_alert(usr, "printing started!")
return
var/direction = get_dir(src, over_location)
if(!direction)
return
drop_direction = direction
balloon_alert(usr, "dropping [dir2text(drop_direction)]")
/obj/machinery/autolathe/click_alt(mob/user)
if(!drop_direction)
return CLICK_ACTION_BLOCKING
if(busy)
balloon_alert(user, "busy printing!")
return CLICK_ACTION_SUCCESS
balloon_alert(user, "drop direction reset")
drop_direction = 0
return CLICK_ACTION_SUCCESS
/obj/machinery/autolathe/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(is_robot_module(O))
return
if(busy)
to_chat(user, span_notice("\The [src] is busy. Please wait for completion of previous operation."))
return
@@ -141,110 +420,53 @@
//Don't eat multitools or wirecutters used on an open lathe.
if(O.has_tool_quality(TOOL_MULTITOOL) || O.has_tool_quality(TOOL_WIRECUTTER))
wires.Interact(user)
return
if(is_robot_module(O))
return 0
if(istype(O,/obj/item/ammo_magazine/clip) || istype(O,/obj/item/ammo_magazine/s357) || istype(O,/obj/item/ammo_magazine/s38) || istype (O,/obj/item/ammo_magazine/s44)/* VOREstation Edit*/) // Prevents ammo recycling exploit with speedloaders.
to_chat(user, "\The [O] is too hazardous to recycle with the autolathe!")
else
to_chat(user, "close the panel first!")
return
return ..()
if(!istype(O, /obj/item/disk/design_disk))
return ..()
/obj/machinery/autolathe/attack_hand(mob/user as mob)
interact(user)
// The rest has to do with loading from design disks
user.visible_message(span_notice("[user] begins to load \the [O] in \the [src]..."),
balloon_alert(user, "uploading design..."),
span_hear("You hear the chatter of a floppy drive."))
busy = TRUE
/obj/machinery/autolathe/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
add_fingerprint(ui.user)
if(busy)
to_chat(ui.user, span_notice("The autolathe is busy. Please wait for completion of previous operation."))
if(!do_after(user, 1.5 SECONDS, target = src))
busy = FALSE
update_static_data_for_all_viewers()
balloon_alert(user, "interrupted!")
return
switch(action)
if("make")
var/datum/category_item/autolathe/making = locate(params["make"])
if(!istype(making))
return
if(making.hidden && !hacked)
return
var/multiplier = (params["multiplier"] || 1)
var/obj/item/disk/design_disk/disky = O
var/list/not_imported
for(var/datum/design_techweb/blueprint as anything in disky.blueprints)
if(!blueprint)
continue
if(blueprint.build_type & AUTOLATHE)
imported_designs[blueprint.id] = TRUE
else
LAZYADD(not_imported, blueprint.name)
if(making.is_stack)
var/max_sheets
for(var/material in making.resources)
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
var/sheets = round(rmat.mat_container.get_material_amount(material) / round(making.resources[material] * coeff))
if(isnull(max_sheets) || max_sheets > sheets)
max_sheets = sheets
if(!isnull(rmat.mat_container.get_material_amount(material)) && rmat.mat_container.get_material_amount(material) < round(making.resources[material] * coeff))
max_sheets = 0
//Build list of multipliers for sheets.
multiplier = tgui_input_number(ui.user, "How many do you want to print? (0-[max_sheets])", null, null, max_sheets, 0)
if(!multiplier || multiplier <= 0 || (multiplier != round(multiplier)) || multiplier > max_sheets || tgui_status(ui.user, state) != STATUS_INTERACTIVE)
return FALSE
if(not_imported)
to_chat(user, span_warning("The following design[length(not_imported) > 1 ? "s" : ""] couldn't be imported: [english_list(not_imported)]"))
//Check if we still have the materials.
var/coeff = (making.no_scale ? 1 : mat_efficiency) //stacks are unaffected by production coefficient
busy = FALSE
update_static_data_for_all_viewers()
return TRUE
if(!rmat.can_use_resource())
return
/obj/machinery/autolathe/RefreshParts()
. = ..()
var/mat_capacity = 0
for(var/obj/item/stock_parts/matter_bin/new_matter_bin in component_parts)
mat_capacity += new_matter_bin.rating * (37.5*SHEET_MATERIAL_AMOUNT)
materials.max_amount = mat_capacity
if(LAZYLEN(making.resources))
if(!rmat.mat_container.has_materials(making.resources, coeff, multiplier))
return
rmat.use_materials(making.resources, coeff, multiplier)
busy = making.name
update_use_power(USE_POWER_ACTIVE)
update_icon() // So lid closes
sleep(build_time)
busy = 0
update_use_power(USE_POWER_IDLE)
update_icon() // So lid opens
//Sanity check.
if(!making || !src)
return
//Create the desired item.
var/obj/item/I = new making.path(src.loc)
if(LAZYLEN(I.matter)) // Sadly we must obey the laws of equivalent exchange.
I.matter.Cut()
else
I.matter = list()
for(var/material in making.resources) // Handle the datum's autoscaling for waste, so we're properly wasting material, but not so much if we have efficiency.
I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
flick("[initial(icon_state)]_finish", src)
if(multiplier > 1)
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
S.set_amount(multiplier)
else
for(multiplier; multiplier > 1; --multiplier) // Create multiple items if it's not a stack.
I = new making.path(src.loc)
// We've already deducted the cost of multiple items. Process the matter the same.
if(LAZYLEN(I.matter))
I.matter.Cut()
else
I.matter = list()
for(var/material in making.resources)
I.matter[material] = round(making.resources[material] / (making.no_scale ? 1 : 1.25)) * (making.no_scale ? 1 : mat_efficiency)
return TRUE
return FALSE
var/efficiency = 1.8
for(var/obj/item/stock_parts/motor/new_servo in component_parts)
efficiency -= new_servo.rating * 0.2
creation_efficiency = max(1, round(efficiency, 0.1)) // creation_efficiency goes 1.6 -> 1.4 -> 1.2 -> 1 per level of servo efficiency
/obj/machinery/autolathe/update_icon()
cut_overlays()
@@ -257,29 +479,3 @@
return
if(busy)
icon_state = "[icon_state]_work"
//Updates overall lathe storage size.
/obj/machinery/autolathe/RefreshParts()
..()
mb_rating = 0
man_rating = 0
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
mb_rating += MB.rating
for(var/obj/item/stock_parts/manipulator/M in component_parts)
man_rating += M.rating
rmat.set_local_size(mb_rating * 75000)
build_time = 50 / man_rating
mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5
update_tgui_static_data(usr)
/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
flick("autolathe_loading", src)//plays metal insertion animation
// use_power(min(1000, amount_inserted / 100))
SStgui.update_uis(src)
/obj/machinery/autolathe/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Storing up to <b>[rmat.local_size]</b> material units.<br>Material consumption at <b>[mat_efficiency*100]%</b>.")
+18 -13
View File
@@ -50,7 +50,7 @@
/obj/machinery/computer/cryopod/dorms
name = "residential oversight console"
desc = "An interface between visitors and the residential oversight systems tasked with keeping track of all visitors in the deeper section of the colony."
circuit = "/obj/item/circuitboard/robotstoragecontrol"
circuit = /obj/item/circuitboard/robotstoragecontrol
storage_type = "visitors"
storage_name = "Residential Oversight Control"
@@ -59,7 +59,7 @@
/obj/machinery/computer/cryopod/travel
name = "docking oversight console"
desc = "An interface between visitors and the docking oversight systems tasked with keeping track of all visitors who enter or exit from the docks."
circuit = "/obj/item/circuitboard/robotstoragecontrol"
circuit = /obj/item/circuitboard/robotstoragecontrol
storage_type = "visitors"
storage_name = "Travel Oversight Control"
@@ -68,7 +68,7 @@
/obj/machinery/computer/cryopod/gateway
name = "gateway oversight console"
desc = "An interface between visitors and the gateway oversight systems tasked with keeping track of all visitors who enter or exit from the gateway."
circuit = "/obj/item/circuitboard/robotstoragecontrol"
circuit = /obj/item/circuitboard/robotstoragecontrol
storage_type = "visitors"
storage_name = "Travel Oversight Control"
@@ -152,29 +152,34 @@
*/
/obj/item/circuitboard/cryopodcontrol
name = "Circuit board (Cryogenic Oversight Console)"
build_path = "/obj/machinery/computer/cryopod"
name = T_BOARD("Cryogenic Oversight Console")
build_path = /obj/machinery/computer/cryopod
origin_tech = list(TECH_DATA = 3)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/robotstoragecontrol
name = "Circuit board (Robotic Storage Console)"
build_path = "/obj/machinery/computer/cryopod/robot"
name = T_BOARD("Robotic Storage Console")
build_path = /obj/machinery/computer/cryopod/robot
origin_tech = list(TECH_DATA = 3)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/dormscontrol
name = "Circuit board (Residential Oversight Console)"
build_path = "/obj/machinery/computer/cryopod/door/dorms"
name = T_BOARD("Residential Oversight Console")
build_path = /obj/machinery/computer/cryopod/dorms
origin_tech = list(TECH_DATA = 3)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/travelcontrol
name = "Circuit board (Travel Oversight Console - Docks)"
build_path = "/obj/machinery/computer/cryopod/door/travel"
name = T_BOARD("Travel Oversight Console - Docks")
build_path = /obj/machinery/computer/cryopod/travel
origin_tech = list(TECH_DATA = 3)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/gatewaycontrol
name = "Circuit board (Travel Oversight Console - Gateway)"
build_path = "/obj/machinery/computer/cryopod/door/gateway"
name = T_BOARD("Travel Oversight Console - Gateway")
build_path = /obj/machinery/computer/cryopod/gateway
origin_tech = list(TECH_DATA = 3)
hidden = TRUE // todo - Make properly constructable in round
//Decorative structures to go alongside cryopods.
/obj/structure/cryofeed
+11 -9
View File
@@ -6,6 +6,7 @@
dir = NORTH
icon_state = "doppler"
circuit = /obj/item/circuitboard/doppler_array
/obj/machinery/doppler_array/Initialize(mapload)
. = ..()
@@ -29,15 +30,7 @@
var/turf/our_turf = get_turf(src)
if(our_turf.Distance(epicenter) > 100)
return
/* There is no way to rotate these... Why?
var/direct = get_dir(our_turf,epicenter)
if(!(direct & dir))
return
*/
var/message = "Explosive disturbance detected - Epicenter at: grid ([x0],[y0],[z0]). Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range]. Temporal displacement of tachyons: [seconds_taken] seconds."
audible_message(span_npc_say(span_name("[src]") + " states coldly, \"[message]\""))
atom_say("Explosive disturbance detected - Epicenter at: grid ([x0],[y0],[z0]). Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range]. Temporal displacement of tachyons: [seconds_taken] seconds.")
/obj/machinery/doppler_array/power_change()
..()
@@ -45,3 +38,12 @@
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]_off"
/obj/machinery/doppler_array/attackby(obj/item/W, mob/user, attack_modifier, click_parameters)
add_fingerprint(user)
if(default_deconstruction_screwdriver(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
if(default_part_replacement(user, W))
return
@@ -2,7 +2,6 @@
name = T_BOARD("cycling airlock button")
build_path = /obj/machinery/access_button
board_type = new /datum/frame/frame_types/button
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/airlock_cycling/attackby(obj/item/I as obj, mob/user as mob)
if(I.has_tool_quality(TOOL_MULTITOOL))
+1 -1
View File
@@ -207,7 +207,7 @@ Just a object used in constructing fire alarms
icon_state = "door_electronics"
desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees celsius!\""
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
matter = RECYCLE_CIRCUIT_MATERIALS
*/
/obj/machinery/partyalarm
name = "\improper PARTY BUTTON"
+3 -3
View File
@@ -41,12 +41,12 @@ GLOBAL_LIST(construction_frame_floor)
/datum/frame/frame_types/computer
name = "Computer"
icon_override = 'icons/obj/stock_parts_vr.dmi' //VOREStation Edit
icon_override = 'icons/obj/stock_parts_vr.dmi'
frame_class = FRAME_CLASS_COMPUTER
/datum/frame/frame_types/machine
name = "Machine"
icon_override = 'icons/obj/stock_parts_vr.dmi' //VOREStation Edit
icon_override = 'icons/obj/stock_parts_vr.dmi'
frame_class = FRAME_CLASS_MACHINE
/datum/frame/frame_types/conveyor
@@ -213,7 +213,7 @@ GLOBAL_LIST(construction_frame_floor)
/datum/frame/frame_types/injector_maker
name = "Ready-to-Use Medicine 3000"
frame_class = FRAME_CLASS_MACHINE
circuit = /obj/machinery/atmospheric_field_generator
circuit = /obj/item/circuitboard/injector_maker
frame_size = 3
// Refinery machines
+1 -1
View File
@@ -1,5 +1,5 @@
/obj/item/circuitboard/machine/vitals_monitor
name = "circuit board (vitals monitor)"
name = T_BOARD("vitals monitor")
build_path = /obj/machinery/vitals_monitor
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 3, TECH_BIO = 4, TECH_ENGINEERING = 2)
@@ -18,6 +18,9 @@
drop_sound = 'sound/items/drop/device.ogg'
pickup_sound = 'sound/items/pickup/device.ogg'
/// If true, this board should be ignored during the circuitboard printing unit test, and give an examine hint that the board may be hard to get if so.
var/hidden = FALSE
/obj/item/circuitboard/Destroy()
if(isobject(board_type)) // Some boards use text instead of an instance...
QDEL_NULL(board_type)
@@ -12,6 +12,8 @@
continue
nice_list += list("[req_components[A]] [initial(A.name)]")
. += "Required components: [english_list(nice_list)]."
if(hidden) // Notify the player that this board cannot be printed easily, so don't lose it!
. += span_danger("It might be hard to find a replacement for a circuit this unique.")
// VOREStation specific circuit boards!
@@ -63,21 +65,18 @@
name = T_BOARD("timeclock")
build_path = /obj/machinery/computer/timeclock
board_type = new /datum/frame/frame_types/timeclock_terminal
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
// Board for the ID restorer in id_restorer_vr.dm
/obj/item/circuitboard/id_restorer
name = T_BOARD("ID restoration console")
build_path = /obj/machinery/computer/id_restorer
board_type = new /datum/frame/frame_types/id_restorer
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/security/xenobio
name = T_BOARD("xenobiology camera monitor")
build_path = /obj/machinery/computer/security/xenobio
network = list(NETWORK_XENOBIO)
req_access = list()
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/machine/rdserver
name = T_BOARD("R&D Server")
@@ -17,6 +17,7 @@
/obj/item/circuitboard/security/tv
name = T_BOARD("security camera monitor - television")
build_path = /obj/machinery/computer/security/wooden_tv
hidden = TRUE
/obj/item/circuitboard/security/engineering
name = T_BOARD("engineering camera monitor")
@@ -42,6 +42,7 @@
/obj/item/circuitboard/card/centcom
name = T_BOARD("CentCom ID card modification console")
build_path = /obj/machinery/computer/card/centcom
hidden = TRUE // Mapper only centcom machine
/obj/item/circuitboard/teleporter
name = T_BOARD("teleporter control console")
@@ -54,7 +55,7 @@
/obj/item/circuitboard/skills/pcu
name = T_BOARD("employment records PCU")
build_path = /obj/machinery/computer/skills
build_path = /obj/machinery/computer/skills // this needs to be fixed someday, a pcu subtype needs to be made, but it affects all maps...
/obj/item/circuitboard/stationalert_engineering
name = T_BOARD("station alert console (engineering)")
@@ -75,6 +76,7 @@
/obj/item/circuitboard/pod
name = T_BOARD("massdriver control")
build_path = /obj/machinery/computer/pod
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/robotics
name = T_BOARD("robotics control console")
@@ -110,6 +112,7 @@
name = T_BOARD("turbine control console")
build_path = /obj/machinery/computer/turbine_computer
origin_tech = list(TECH_DATA = 2, TECH_POWER = 2)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/solar_control
name = T_BOARD("solar control console")
@@ -158,16 +161,19 @@
name = T_BOARD("mining shuttle console")
build_path = /obj/machinery/computer/shuttle_control/mining
origin_tech = list(TECH_DATA = 2)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/engineering_shuttle
name = T_BOARD("engineering shuttle console")
build_path = /obj/machinery/computer/shuttle_control/engineering
origin_tech = list(TECH_DATA = 2)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/research_shuttle
name = T_BOARD("research shuttle console")
build_path = /obj/machinery/computer/shuttle_control/research
origin_tech = list(TECH_DATA = 2)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/aifixer
name = T_BOARD("AI integrity restorer")
@@ -178,22 +184,27 @@
/obj/item/circuitboard/helm
name = T_BOARD("helm control console")
build_path = /obj/machinery/computer/ship/helm
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/engine
name = T_BOARD("engine control console")
build_path = /obj/machinery/computer/ship/engines
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/nav
name = T_BOARD("navigation console")
build_path = /obj/machinery/computer/ship/navigation
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/nav/tele
name = T_BOARD("navigation telescreen")
build_path = /obj/machinery/computer/ship/navigation/telescreen
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/sensors
name = T_BOARD("sensors console")
build_path = /obj/machinery/computer/ship/sensors
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/area_atmos
name = T_BOARD("area air control console")
@@ -204,6 +215,7 @@
name = T_BOARD("prison shuttle control console")
build_path = /obj/machinery/computer/prison_shuttle
origin_tech = list(TECH_DATA = 2)
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/rcon_console
name = T_BOARD("RCON remote control console")
@@ -9,6 +9,7 @@
origin_tech = list(TECH_DATA = 3)
var/shuttle_category = null // Shuttle datum's category must exactly equal this to auto-detect
var/shuttle_tag = null // If set, link constructed console to this shuttle. If null, auto-detect.
hidden = TRUE // todo - Make properly constructable in round
/obj/item/circuitboard/shuttle_console/deconstruct(obj/machinery/computer/shuttle_control/M)
shuttle_tag = M.shuttle_tag
@@ -10,37 +10,31 @@
name = T_BOARD("guestpass console")
build_path = /obj/machinery/computer/guestpass
board_type = new /datum/frame/frame_types/guest_pass_console
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/status_display
name = T_BOARD("status display")
build_path = /obj/machinery/status_display
board_type = new /datum/frame/frame_types/display
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/ai_status_display
name = T_BOARD("ai status display")
build_path = /obj/machinery/ai_status_display
board_type = new /datum/frame/frame_types/display
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/newscaster
name = T_BOARD("newscaster")
build_path = /obj/machinery/newscaster
board_type = new /datum/frame/frame_types/newscaster
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/atm
name = T_BOARD("atm")
build_path = /obj/machinery/atm
board_type = new /datum/frame/frame_types/atm
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/request
name = T_BOARD("request console")
build_path = /obj/machinery/requests_console
board_type = new /datum/frame/frame_types/supply_request_console
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
//Alarm
@@ -48,20 +42,16 @@
name = T_BOARD("fire alarm")
build_path = /obj/machinery/firealarm
board_type = new /datum/frame/frame_types/fire_alarm
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/airalarm
name = T_BOARD("air alarm")
build_path = /obj/machinery/alarm
board_type = new /datum/frame/frame_types/air_alarm
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/intercom
name = T_BOARD("intercom")
build_path = /obj/item/radio/intercom
board_type = new /datum/frame/frame_types/intercom
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/intercom/Destroy()
if(istype(loc, /obj/item/radio/intercom))
@@ -73,19 +63,16 @@
name = T_BOARD("keycard authenticator")
build_path = /obj/machinery/keycard_auth
board_type = new /datum/frame/frame_types/keycard_authenticator
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/geiger
name = T_BOARD("geiger counter")
build_path = /obj/item/geiger/wall
board_type = new /datum/frame/frame_types/geiger
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/electrochromic
name = T_BOARD("electrochromic button")
build_path = /obj/machinery/button/windowtint
board_type = new /datum/frame/frame_types/button
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
//Computer
@@ -93,7 +80,6 @@
name = T_BOARD("holopad")
build_path = /obj/machinery/hologram/holopad
board_type = new /datum/frame/frame_types/holopad
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
/obj/item/circuitboard/scanner_console
name = T_BOARD("body scanner console")
@@ -113,7 +99,6 @@
name = T_BOARD("photocopier")
build_path = /obj/machinery/photocopier
board_type = new /datum/frame/frame_types/photocopier
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/motor = 1,
@@ -124,7 +109,6 @@
name = T_BOARD("fax")
build_path = /obj/machinery/photocopier/faxmachine
board_type = new /datum/frame/frame_types/fax
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/motor = 1,
@@ -165,7 +149,6 @@
name = T_BOARD("washing machine")
build_path = /obj/machinery/washing_machine
board_type = new /datum/frame/frame_types/washing_machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/motor = 1,
/obj/item/stock_parts/gear = 2)
@@ -16,7 +16,6 @@
name = T_BOARD("space heater")
build_path = /obj/machinery/space_heater
board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/micro_laser = 4,
/obj/item/stock_parts/capacitor = 4,
@@ -4,7 +4,6 @@
build_path = /obj/machinery/microwave
board_type = new /datum/frame/frame_types/microwave
contain_parts = 0
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/console_screen = 1,
/obj/item/stock_parts/capacitor = 1,
@@ -17,7 +16,6 @@
desc = "The circuitboard for an oven."
build_path = /obj/machinery/appliance/cooker/oven
board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/capacitor = 3,
/obj/item/stock_parts/scanning_module = 1,
@@ -6,7 +6,6 @@
name = T_BOARD("papershredder")
build_path = /obj/machinery/papershredder
board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stock_parts/motor = 1,
/obj/item/stock_parts/gear = 2,
@@ -15,7 +15,6 @@
name = T_BOARD("smart centrifuge")
build_path = /obj/machinery/smart_centrifuge
board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
origin_tech = list(TECH_MAGNET = 3, TECH_DATA = 2, TECH_MATERIAL = 3)
req_components = list(
/obj/item/stock_parts/scanning_module = 1,
@@ -7,7 +7,6 @@
build_path = /obj/machinery/recycling/crusher
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MATERIAL = 2)
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/motor = 1,
@@ -21,7 +20,6 @@
build_path = /obj/machinery/recycling/sorter
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MATERIAL = 2)
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/motor = 1,
@@ -33,7 +31,6 @@
build_path = /obj/machinery/recycling/stamper
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MATERIAL = 2)
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/stack/cable_coil = 2,
/obj/item/stock_parts/gear = 2,
@@ -20,6 +20,7 @@
/obj/item/stock_parts/matter_bin = 2,
/obj/item/stock_parts/manipulator = 2,
/obj/item/reagent_containers/glass/beaker = 2)
hidden = TRUE // Base types aren't cared for, a fully unlocked lathe shouldn't be easy to make
/obj/item/circuitboard/machine/protolathe/department
name = T_BOARD("departmental protolathe")
@@ -27,21 +28,27 @@
/obj/item/circuitboard/machine/protolathe/department/engineering
name = T_BOARD("departmental protolathe (engineering)")
build_path = /obj/machinery/rnd/production/protolathe/department/engineering
hidden = FALSE
/obj/item/circuitboard/machine/protolathe/department/service
name = T_BOARD("departmental protolathe (service)")
build_path = /obj/machinery/rnd/production/protolathe/department/service
hidden = FALSE
/obj/item/circuitboard/machine/protolathe/department/medical
name = T_BOARD("departmental protolathe (medical)")
build_path = /obj/machinery/rnd/production/protolathe/department/medical
hidden = FALSE
/obj/item/circuitboard/machine/protolathe/department/cargo
name = T_BOARD("departmental protolathe (cargo)")
build_path = /obj/machinery/rnd/production/protolathe/department/cargo
hidden = FALSE
/obj/item/circuitboard/machine/protolathe/department/science
name = T_BOARD("departmental protolathe (science)")
build_path = /obj/machinery/rnd/production/protolathe/department/science
hidden = FALSE
/obj/item/circuitboard/machine/protolathe/department/security
name = T_BOARD("departmental protolathe (security)")
build_path = /obj/machinery/rnd/production/protolathe/department/security
hidden = FALSE
/obj/item/circuitboard/circuit_imprinter
name = T_BOARD("circuit imprinter")
@@ -54,7 +61,7 @@
/obj/item/reagent_containers/glass/beaker = 2)
/obj/item/circuitboard/mechfab
name = "Circuit board (Exosuit Fabricator)"
name = T_BOARD("Exosuit Fabricator")
build_path = /obj/machinery/mecha_part_fabricator_tg
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
@@ -65,7 +72,7 @@
/obj/item/stock_parts/console_screen = 1)
/obj/item/circuitboard/prosthetics
name = "Circuit board (Prosthetics Fabricator)"
name = T_BOARD("Prosthetics Fabricator")
build_path = /obj/machinery/mecha_part_fabricator_tg/prosthetics
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 3)
@@ -76,7 +83,7 @@
/obj/item/stock_parts/console_screen = 1)
/obj/item/circuitboard/ntnet_relay
name = "Circuit board (NTNet Quantum Relay)"
name = T_BOARD("NTNet Quantum Relay")
build_path = /obj/machinery/ntnet_relay
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_DATA = 4)
@@ -121,3 +128,11 @@
/obj/item/stock_parts/scanning_module = 1,
/obj/item/stock_parts/manipulator = 1,
/obj/item/stock_parts/micro_laser = 1)
/obj/item/circuitboard/doppler_array
name = T_BOARD("doppler array")
build_path = /obj/machinery/doppler_array
board_type = new /datum/frame/frame_types/machine
origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 1, TECH_DATA = 3)
req_components = list(
/obj/item/stock_parts/scanning_module = 4)