Merge pull request #5854 from Citadel-Station-13/upstream-merge-36055

[MIRROR] Techwebs update: Protolathe/Circuit imprinters combined into techfabs!
This commit is contained in:
deathride58
2018-03-09 19:25:12 +00:00
committed by GitHub
31 changed files with 654 additions and 799 deletions

View File

@@ -1,125 +0,0 @@
/*///////////////Circuit Imprinter (By Darem)////////////////////////
Used to print new circuit boards (for computers and similar systems) and AI modules. Each circuit board pattern are stored in
a /datum/desgin on the linked R&D console. You can then print them out in a fasion similar to a regular lathe. However, instead of
using metal and glass, it uses glass and reagents (usually sulfuric acis).
*/
/obj/machinery/rnd/circuit_imprinter
name = "circuit imprinter"
desc = "Manufactures circuit boards for the construction of machines."
icon_state = "circuit_imprinter"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/circuit_imprinter
var/efficiency_coeff
var/datum/component/material_container/materials //Store for hyper speed!
var/list/categories = list(
"AI Modules",
"Computer Boards",
"Teleportation Machinery",
"Medical Machinery",
"Engineering Machinery",
"Exosuit Modules",
"Hydroponics Machinery",
"Subspace Telecomms",
"Research Machinery",
"Misc. Machinery",
"Computer Parts"
)
/obj/machinery/rnd/circuit_imprinter/Initialize()
materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), 0,
FALSE, list(/obj/item/stack, /obj/item/stack/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
create_reagents(0)
RefreshParts()
return ..()
/obj/machinery/rnd/circuit_imprinter/RefreshParts()
reagents.maximum_volume = 0
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.maximum_volume += G.volume
G.reagents.trans_to(src, G.reagents.total_volume)
GET_COMPONENT(materials, /datum/component/material_container)
materials.max_amount = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
materials.max_amount += M.rating * 75000
var/T = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
T += M.rating
efficiency_coeff = 2 ** (T - 1) //Only 1 manipulator here, you're making runtimes Razharas
/obj/machinery/rnd/circuit_imprinter/blob_act(obj/structure/blob/B)
if (prob(50))
qdel(src)
/obj/machinery/rnd/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material
var/list/all_materials = being_built.reagents_list + being_built.materials
GET_COMPONENT(materials, /datum/component/material_container)
var/A = materials.amount(M)
if(!A)
A = reagents.get_reagent_amount(M)
return round(A / max(1, (all_materials[M]/efficiency_coeff)))
//we eject the materials upon deconstruction.
/obj/machinery/rnd/circuit_imprinter/on_deconstruction()
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.trans_to(G, G.reagents.maximum_volume)
GET_COMPONENT(materials, /datum/component/material_container)
materials.retrieve_all()
..()
/obj/machinery/rnd/circuit_imprinter/disconnect_console()
linked_console.linked_imprinter = null
..()
/obj/machinery/rnd/circuit_imprinter/proc/user_try_print_id(id)
if((!linked_console && requires_console) || !id)
return FALSE
var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id)
if(!istype(D))
return FALSE
var/power = 1000
for(var/M in D.materials)
power += round(D.materials[M] / 5)
power = max(4000, power)
use_power(power)
var/list/efficient_mats = list()
for(var/MAT in D.materials)
efficient_mats[MAT] = D.materials[MAT]/efficiency_coeff
if(!materials.has_materials(efficient_mats))
say("Not enough materials to complete prototype.")
return FALSE
for(var/R in D.reagents_list)
if(!reagents.has_reagent(R, D.reagents_list[R]/efficiency_coeff))
say("Not enough reagents to complete prototype.")
return FALSE
busy = TRUE
flick("circuit_imprinter_ani", src)
materials.use_amount(efficient_mats)
for(var/R in D.reagents_list)
reagents.remove_reagent(R, D.reagents_list[R]/efficiency_coeff)
var/P = D.build_path
addtimer(CALLBACK(src, .proc/reset_busy), 16)
addtimer(CALLBACK(src, .proc/do_print, P, efficient_mats, D.dangerous_construction), 16)
return TRUE
/obj/machinery/rnd/circuit_imprinter/proc/do_print(path, list/matlist, notify_admins)
if(notify_admins && usr)
investigate_log("[key_name(usr)] built [path] at a circuit imprinter.", INVESTIGATE_RESEARCH)
message_admins("[ADMIN_LOOKUPFLW(usr)] has built [path] at a circuit imprinter.")
var/obj/item/I = new path(get_turf(src))
I.materials = matlist.Copy()
SSblackbox.record_feedback("nested tally", "circuit_printed", 1, list("[type]", "[path]"))

View File

@@ -1,200 +0,0 @@
/obj/machinery/rnd/circuit_imprinter/department
name = "Department Circuit Imprinter"
desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!"
icon_state = "circuit_imprinter"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/circuit_imprinter/department
requires_console = FALSE
var/list/datum/design/cached_designs
var/list/datum/design/matching_designs
var/department_tag = "Unidentified" //used for material distribution among other things.
var/datum/techweb/stored_research
var/datum/techweb/host_research
var/screen = DEPPRINTER_SCREEN_PRIMARY
/obj/machinery/rnd/circuit_imprinter/department/science
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE
department_tag = "Science"
/obj/machinery/rnd/circuit_imprinter/department/Initialize()
. = ..()
stored_research = new
cached_designs = list()
host_research = SSresearch.science_tech
matching_designs = list()
update_research()
/obj/machinery/rnd/circuit_imprinter/department/Destroy()
QDEL_NULL(stored_research)
return ..()
/obj/machinery/rnd/circuit_imprinter/department/user_try_print_id(id, amount)
var/datum/design/D = get_techweb_design_by_id(id)
if(!D || !(D.departmental_flags & allowed_department_flags))
say("Warning: Printing failed. Please update the research data with the on-screen button!")
return FALSE
. = ..()
/obj/machinery/rnd/circuit_imprinter/department/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/rnd/circuit_imprinter/department/interact(mob/user)
user.set_machine(src)
var/datum/browser/popup = new(user, "rndconsole", name, 460, 550)
popup.set_content(generate_ui())
popup.open()
/obj/machinery/rnd/circuit_imprinter/department/proc/search(string)
matching_designs.Cut()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(!(D.build_type & IMPRINTER) || !(D.departmental_flags & allowed_department_flags))
continue
if(findtext(D.name,string))
matching_designs.Add(D)
/obj/machinery/rnd/circuit_imprinter/department/proc/update_research()
host_research.copy_research_to(stored_research, TRUE)
update_designs()
/obj/machinery/rnd/circuit_imprinter/department/proc/update_designs()
cached_designs.Cut()
for(var/i in stored_research.researched_designs)
var/datum/design/d = stored_research.researched_designs[i]
if((d.departmental_flags & allowed_department_flags) && (d.build_type & IMPRINTER))
cached_designs |= d
/obj/machinery/rnd/circuit_imprinter/department/proc/generate_ui()
var/list/ui = list()
ui += ui_header()
switch(screen)
if(DEPPRINTER_SCREEN_MATERIALS)
ui += ui_materials()
if(DEPPRINTER_SCREEN_CHEMICALS)
ui += ui_chemicals()
if(DEPPRINTER_SCREEN_SEARCH)
ui += ui_search()
else
ui += ui_department_imprinter()
for(var/i in 1 to length(ui))
if(!findtextEx(ui[i], RDSCREEN_NOBREAK))
ui[i] += "<br>"
ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "")
return ui.Join("")
/obj/machinery/rnd/circuit_imprinter/department/proc/ui_search() //Legacy code
var/list/l = list()
l += "<h2>Search Results:</h2>"
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
<input type='hidden' name='search' value='to_search'>\
<input type='text' name='to_search'>\
<input type='submit' value='Search'>\
</form><HR>"
var/coeff = efficiency_coeff
for(var/datum/design/D in matching_designs)
var/temp_materials
var/check_materials = TRUE
var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
temp_materials += " | "
if (!check_mat(D, M))
check_materials = FALSE
temp_materials += " <span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
else
temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]"
if (check_materials)
l += "<A href='?src=[REF(src)];imprint=[D.id]'>[D.name]</A>[temp_materials]"
else
l += "<span class='linkOff'>[D.name]</span>[temp_materials]"
l += "</div>"
return l
/obj/machinery/rnd/circuit_imprinter/department/proc/ui_department_imprinter()
var/list/l = list()
var/coeff = efficiency_coeff
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
<input type='hidden' name='search' value='to_search'>\
<input type='text' name='to_search'>\
<input type='submit' value='Search'>\
</form><HR>"
for(var/datum/design/D in cached_designs)
var/temp_materials
var/check_materials = TRUE
var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
temp_materials += " | "
if (!check_mat(D, M))
check_materials = FALSE
temp_materials += " <span class='bad'>[all_materials[M]/coeff] [CallMaterialName(M)]</span>"
else
temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]"
if (check_materials)
l += "<A href='?src=[REF(src)];imprint=[D.id]'>[D.name]</A>[temp_materials]"
else
l += "<span class='linkOff'>[D.name]</span>[temp_materials]"
l += "</div>"
return l
/obj/machinery/rnd/circuit_imprinter/department/proc/ui_header()
var/list/l = list()
l += "<div class='statusDisplay'><b>[host_research.organization] [department_tag] Department Circuit Imprinter</b>"
l += "Security protocols: [(obj_flags & EMAGGED) ? "<font color='red'>Disabled</font>" : "<font color='green'>Enabled</font>"]"
l += "<A href='?src=[REF(src)];switch_screen=[DEPPRINTER_SCREEN_MATERIALS]'><B>Material Amount:</B> [materials.total_amount] / [materials.max_amount]</A>"
l += "<A href='?src=[REF(src)];switch_screen=[DEPPRINTER_SCREEN_CHEMICALS]'><B>Chemical volume:</B> [reagents.total_volume] / [reagents.maximum_volume]</A>"
l += "<a href='?src=[REF(src)];sync_research=1'>Synchronize Research</a>"
l += "<a href='?src=[REF(src)];switch_screen=[DEPPRINTER_SCREEN_PRIMARY]'>Main Screen</a></div>[RDSCREEN_NOBREAK]"
return l
/obj/machinery/rnd/circuit_imprinter/department/proc/ui_materials()
var/list/l = list()
l += "<div class='statusDisplay'><h3>Material Storage:</h3>"
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
l += "* [M.amount] of [M.name]: "
if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=1'>Eject</A> [RDSCREEN_NOBREAK]"
if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=5'>5x</A> [RDSCREEN_NOBREAK]"
if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=50'>All</A>[RDSCREEN_NOBREAK]"
l += ""
l += "</div>[RDSCREEN_NOBREAK]"
return l
/obj/machinery/rnd/circuit_imprinter/department/proc/ui_chemicals()
var/list/l = list()
l += "<div class='statusDisplay'><A href='?src=[REF(src)];disposeall=1'>Disposal All Chemicals in Storage</A>"
l += "<h3>Chemical Storage:</h3>"
for(var/datum/reagent/R in reagents.reagent_list)
l += "[R.name]: [R.volume]"
l += "<A href='?src=[REF(src)];dispose=[R.id]'>Purge</A>"
l += "</div>"
return l
/obj/machinery/rnd/circuit_imprinter/department/Topic(raw, ls)
if(..())
return
add_fingerprint(usr)
usr.set_machine(src)
if(ls["switch_screen"])
screen = text2num(ls["switch_screen"])
if(ls["imprint"]) //Causes the circuit_imprinter to build something.
if(busy)
say("Warning: Fabricators busy!")
else
user_try_print_id(ls["imprint"])
if(ls["search"]) //Search for designs with name matching pattern
search(ls["to_search"])
screen = DEPPRINTER_SCREEN_SEARCH
if(ls["sync_research"])
update_research()
say("Synchronizing research with host technology database.")
if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it)
reagents.del_reagent(ls["dispose"])
if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents.
reagents.clear_reagents()
if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material
materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"])

View File

@@ -1,244 +0,0 @@
/obj/machinery/rnd/protolathe/department
name = "department protolathe"
desc = "A special protolathe with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!"
icon_state = "protolathe"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/protolathe/department
requires_console = FALSE
var/list/datum/design/cached_designs
var/list/datum/design/matching_designs
var/department_tag = "Unidentified" //used for material distribution among other things.
var/datum/techweb/stored_research
var/datum/techweb/host_research
var/screen = DEPLATHE_SCREEN_PRIMARY
/obj/machinery/rnd/protolathe/department/engineering
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_ENGINEERING
department_tag = "Engineering"
circuit = /obj/item/circuitboard/machine/protolathe/department/engineering
/obj/machinery/rnd/protolathe/department/service
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SERVICE
department_tag = "Service"
circuit = /obj/item/circuitboard/machine/protolathe/department/service
/obj/machinery/rnd/protolathe/department/medical
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_MEDICAL
department_tag = "Medical"
circuit = /obj/item/circuitboard/machine/protolathe/department/medical
/obj/machinery/rnd/protolathe/department/cargo
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_CARGO
department_tag = "Cargo"
circuit = /obj/item/circuitboard/machine/protolathe/department/cargo
/obj/machinery/rnd/protolathe/department/science
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE
department_tag = "Science"
circuit = /obj/item/circuitboard/machine/protolathe/department/science
/obj/machinery/rnd/protolathe/department/security
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SECURITY
department_tag = "Security"
circuit = /obj/item/circuitboard/machine/protolathe/department/security
/obj/machinery/rnd/protolathe/department/Initialize()
. = ..()
matching_designs = list()
cached_designs = list()
stored_research = new
host_research = SSresearch.science_tech
update_research()
/obj/machinery/rnd/protolathe/department/Destroy()
QDEL_NULL(stored_research)
return ..()
/obj/machinery/rnd/protolathe/department/user_try_print_id(id, amount)
var/datum/design/D = get_techweb_design_by_id(id)
if(!D || !(D.departmental_flags & allowed_department_flags))
say("Warning: Printing failed. Please update the research data with the on-screen button!")
return FALSE
. = ..()
/obj/machinery/rnd/protolathe/department/attack_hand(mob/user)
if(..())
return
interact(user)
/obj/machinery/rnd/protolathe/department/interact(mob/user)
user.set_machine(src)
var/datum/browser/popup = new(user, "rndconsole", name, 460, 550)
popup.set_content(generate_ui())
popup.open()
/obj/machinery/rnd/protolathe/department/proc/search(string)
matching_designs.Cut()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(!(D.build_type & PROTOLATHE) || !(D.departmental_flags & allowed_department_flags))
continue
if(findtext(D.name,string))
matching_designs.Add(D)
/obj/machinery/rnd/protolathe/department/proc/update_research()
host_research.copy_research_to(stored_research, TRUE)
update_designs()
/obj/machinery/rnd/protolathe/department/proc/update_designs()
cached_designs.Cut()
for(var/i in stored_research.researched_designs)
var/datum/design/d = stored_research.researched_designs[i]
if((d.departmental_flags & allowed_department_flags) && (d.build_type & PROTOLATHE))
cached_designs |= d
/obj/machinery/rnd/protolathe/department/proc/generate_ui()
var/list/ui = list()
ui += ui_header()
switch(screen)
if(DEPLATHE_SCREEN_MATERIALS)
ui += ui_materials()
if(DEPLATHE_SCREEN_CHEMICALS)
ui += ui_chemicals()
if(DEPLATHE_SCREEN_SEARCH)
ui += ui_search()
else
ui += ui_department_lathe()
for(var/i in 1 to length(ui))
if(!findtextEx(ui[i], RDSCREEN_NOBREAK))
ui[i] += "<br>"
ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "")
return ui.Join("")
/obj/machinery/rnd/protolathe/department/proc/ui_search() //Legacy code
var/list/l = list()
var/coeff = efficiency_coeff
l += "<h2>Search Results:</h2>"
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
<input type='hidden' name='search' value='to_search'>\
<input type='text' name='to_search'>\
<input type='submit' value='Search'>\
</form><HR>"
for(var/datum/design/D in matching_designs)
var/temp_material
var/c = 50
var/t
var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
t = check_mat(D, M)
temp_material += " | "
if (t < 1)
temp_material += "<span class='bad'>[all_materials[M]*coeff] [CallMaterialName(M)]</span>"
else
temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]"
c = min(c,t)
if (c >= 1)
l += "<A href='?src=[REF(src)];build=[D.id];amount=1'>[D.name]</A>[RDSCREEN_NOBREAK]"
if(c >= 5)
l += "<A href='?src=[REF(src)];build=[D.id];amount=5'>x5</A>[RDSCREEN_NOBREAK]"
if(c >= 10)
l += "<A href='?src=[REF(src)];build=[D.id];amount=10'>x10</A>[RDSCREEN_NOBREAK]"
l += "[temp_material][RDSCREEN_NOBREAK]"
else
l += "<span class='linkOff'>[D.name]</span>[temp_material][RDSCREEN_NOBREAK]"
l += ""
l += "</div>"
return l
/obj/machinery/rnd/protolathe/department/proc/ui_department_lathe()
var/list/l = list()
var/coeff = efficiency_coeff
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
<input type='hidden' name='search' value='to_search'>\
<input type='text' name='to_search'>\
<input type='submit' value='Search'>\
</form><HR>"
for(var/datum/design/D in cached_designs)
var/temp_material
var/c = 50
var/t
var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
t = check_mat(D, M)
temp_material += " | "
if (t < 1)
temp_material += "<span class='bad'>[all_materials[M]*coeff] [CallMaterialName(M)]</span>"
else
temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]"
c = min(c,t)
if (c >= 1)
l += "<A href='?src=[REF(src)];build=[D.id];amount=1'>[D.name]</A>[RDSCREEN_NOBREAK]"
if(c >= 5)
l += "<A href='?src=[REF(src)];build=[D.id];amount=5'>x5</A>[RDSCREEN_NOBREAK]"
if(c >= 10)
l += "<A href='?src=[REF(src)];build=[D.id];amount=10'>x10</A>[RDSCREEN_NOBREAK]"
l += "[temp_material][RDSCREEN_NOBREAK]"
else
l += "<span class='linkOff'>[D.name]</span>[temp_material][RDSCREEN_NOBREAK]"
l += ""
l += "</div>"
return l
/obj/machinery/rnd/protolathe/department/proc/ui_header()
var/list/l = list()
l += "<div class='statusDisplay'><b>[host_research.organization] [department_tag] Department Lathe</b>"
l += "Security protocols: [(obj_flags & EMAGGED) ? "<font color='red'>Disabled</font>" : "<font color='green'>Enabled</font>"]"
l += "<A href='?src=[REF(src)];switch_screen=[DEPLATHE_SCREEN_MATERIALS]'><B>Material Amount:</B> [materials.total_amount] / [materials.max_amount]</A>"
l += "<A href='?src=[REF(src)];switch_screen=[DEPLATHE_SCREEN_CHEMICALS]'><B>Chemical volume:</B> [reagents.total_volume] / [reagents.maximum_volume]</A>"
l += "<a href='?src=[REF(src)];sync_research=1'>Synchronize Research</a>"
l += "<a href='?src=[REF(src)];switch_screen=[DEPLATHE_SCREEN_PRIMARY]'>Main Screen</a></div>[RDSCREEN_NOBREAK]"
return l
/obj/machinery/rnd/protolathe/department/proc/ui_materials()
var/list/l = list()
l += "<div class='statusDisplay'><h3>Material Storage:</h3>"
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
l += "* [M.amount] of [M.name]: "
if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=1'>Eject</A> [RDSCREEN_NOBREAK]"
if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=5'>5x</A> [RDSCREEN_NOBREAK]"
if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=50'>All</A>[RDSCREEN_NOBREAK]"
l += ""
l += "</div>[RDSCREEN_NOBREAK]"
return l
/obj/machinery/rnd/protolathe/department/proc/ui_chemicals()
var/list/l = list()
l += "<div class='statusDisplay'><A href='?src=[REF(src)];disposeall=1'>Disposal All Chemicals in Storage</A>"
l += "<h3>Chemical Storage:</h3>"
for(var/datum/reagent/R in reagents.reagent_list)
l += "[R.name]: [R.volume]"
l += "<A href='?src=[REF(src)];dispose=[R.id]'>Purge</A>"
l += "</div>"
return l
/obj/machinery/rnd/protolathe/department/Topic(raw, ls)
if(..())
return
add_fingerprint(usr)
usr.set_machine(src)
if(ls["switch_screen"])
screen = text2num(ls["switch_screen"])
if(ls["build"]) //Causes the Protolathe to build something.
if(busy)
say("Warning: Fabricators busy!")
else
user_try_print_id(ls["build"], ls["amount"])
if(ls["search"]) //Search for designs with name matching pattern
search(ls["to_search"])
screen = DEPLATHE_SCREEN_SEARCH
if(ls["sync_research"])
update_research()
say("Synchronizing research with host technology database.")
if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it)
reagents.del_reagent(ls["dispose"])
if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents.
reagents.clear_reagents()
if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material
materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"])
updateUsrDialog()

View File

@@ -0,0 +1,328 @@
/obj/machinery/rnd/production
name = "technology fabricator"
desc = "Makes researched and prototype items with materials and energy."
container_type = OPENCONTAINER
var/consoleless_interface = FALSE //Whether it can be used without a console.
var/efficiency_coeff = 1 //Materials needed / coeff = actual.
var/list/categories = list()
var/datum/component/material_container/materials //Store for hyper speed!
var/allowed_department_flags = ALL
var/production_animation //What's flick()'d on print.
var/allowed_buildtypes = NONE
var/list/datum/design/cached_designs
var/list/datum/design/matching_designs
var/department_tag = "Unidentified" //used for material distribution among other things.
var/datum/techweb/stored_research
var/datum/techweb/host_research
var/screen = RESEARCH_FABRICATOR_SCREEN_MAIN
var/selected_category
/obj/machinery/rnd/production/Initialize()
. = ..()
create_reagents(0)
materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0,
FALSE, list(/obj/item/stack), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
RefreshParts()
matching_designs = list()
cached_designs = list()
stored_research = new
host_research = SSresearch.science_tech
update_research()
/obj/machinery/rnd/production/proc/update_research()
host_research.copy_research_to(stored_research, TRUE)
update_designs()
/obj/machinery/rnd/production/proc/update_designs()
cached_designs.Cut()
for(var/i in stored_research.researched_designs)
var/datum/design/d = stored_research.researched_designs[i]
if((d.departmental_flags & allowed_department_flags) && (d.build_type & allowed_buildtypes))
cached_designs |= d
/obj/machinery/rnd/production/RefreshParts()
calculate_efficiency()
/obj/machinery/rnd/production/attack_hand(mob/user)
interact(user) //remove this snowflake shit when the refactor of storage components or some other pr that unsnowflakes attack_hand on machinery is in
/obj/machinery/rnd/production/interact(mob/user)
if(!consoleless_interface)
return ..()
user.set_machine(src)
var/datum/browser/popup = new(user, "rndconsole", name, 460, 550)
popup.set_content(generate_ui())
popup.open()
/obj/machinery/rnd/production/Destroy()
QDEL_NULL(stored_research)
return ..()
/obj/machinery/rnd/production/proc/calculate_efficiency()
efficiency_coeff = 1
if(reagents) //If reagents/materials aren't initialized, don't bother, we'll be doing this again after reagents init anyways.
reagents.maximum_volume = 0
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.maximum_volume += G.volume
G.reagents.trans_to(src, G.reagents.total_volume)
if(materials)
materials.max_amount = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
materials.max_amount += M.rating * 75000
//we eject the materials upon deconstruction.
/obj/machinery/rnd/production/on_deconstruction()
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.trans_to(G, G.reagents.maximum_volume)
materials.retrieve_all()
return ..()
/obj/machinery/rnd/production/proc/do_print(path, amount, list/matlist, notify_admins)
if(notify_admins)
investigate_log("[key_name(usr)] built [amount] of [path] at [src]([type]).", INVESTIGATE_RESEARCH)
message_admins("[ADMIN_LOOKUPFLW(usr)] has built [amount] of [path] at a [src]([type]).")
for(var/i in 1 to amount)
var/obj/item/I = new path(get_turf(src))
if(!istype(I, /obj/item/stack/sheet) && !istype(I, /obj/item/stack/ore/bluespace_crystal))
I.materials = matlist.Copy()
SSblackbox.record_feedback("nested tally", "item_printed", amount, list("[type]", "[path]"))
/obj/machinery/rnd/production/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material
var/list/all_materials = being_built.reagents_list + being_built.materials
var/A = materials.amount(M)
if(!A)
A = reagents.get_reagent_amount(M)
return round(A / max(1, (all_materials[M]/efficiency_coeff)))
/obj/machinery/rnd/production/proc/user_try_print_id(id, amount)
if((!istype(linked_console) && requires_console) || !id)
return FALSE
if(istext(amount))
amount = text2num(amount)
if(isnull(amount))
amount = 1
var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id)
if(!istype(D))
return FALSE
if(!(D.departmental_flags & allowed_department_flags))
say("Warning: Printing failed: This fabricator does not have the necessary keys to decrypt design schematics. Please update the research data with the on-screen button and contact Nanotrasen Support!")
return FALSE
if(D.build_type && !(D.build_type & allowed_buildtypes))
say("This machine does not have the necessary manipulation systems for this design. Please contact Nanotrasen Support!")
return FALSE
var/power = 1000
amount = CLAMP(amount, 1, 50)
for(var/M in D.materials)
power += round(D.materials[M] * amount / 35)
power = min(3000, power)
use_power(power)
var/list/efficient_mats = list()
for(var/MAT in D.materials)
efficient_mats[MAT] = D.materials[MAT]/efficiency_coeff
if(!materials.has_materials(efficient_mats, amount))
say("Not enough materials to complete prototype[amount > 1? "s" : ""].")
return FALSE
for(var/R in D.reagents_list)
if(!reagents.has_reagent(R, D.reagents_list[R]*amount/efficiency_coeff))
say("Not enough reagents to complete prototype[amount > 1? "s" : ""].")
return FALSE
materials.use_amount(efficient_mats, amount)
for(var/R in D.reagents_list)
reagents.remove_reagent(R, D.reagents_list[R]*amount/efficiency_coeff)
busy = TRUE
if(production_animation)
flick(production_animation, src)
var/timecoeff = D.lathe_time_factor / efficiency_coeff
addtimer(CALLBACK(src, .proc/reset_busy), (30 * timecoeff * amount) ** 0.5)
addtimer(CALLBACK(src, .proc/do_print, D.build_path, amount, efficient_mats, D.dangerous_construction), (32 * timecoeff * amount) ** 0.8)
return TRUE
/obj/machinery/rnd/production/proc/search(string)
matching_designs.Cut()
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(!(D.build_type & allowed_buildtypes) || !(D.departmental_flags & allowed_department_flags))
continue
if(findtext(D.name,string))
matching_designs.Add(D)
/obj/machinery/rnd/production/proc/generate_ui()
var/list/ui = list()
ui += ui_header()
switch(screen)
if(RESEARCH_FABRICATOR_SCREEN_MATERIALS)
ui += ui_screen_materials()
if(RESEARCH_FABRICATOR_SCREEN_CHEMICALS)
ui += ui_screen_chemicals()
if(RESEARCH_FABRICATOR_SCREEN_SEARCH)
ui += ui_screen_search()
if(RESEARCH_FABRICATOR_SCREEN_CATEGORYVIEW)
ui += ui_screen_category_view()
else
ui += ui_screen_main()
for(var/i in 1 to length(ui))
if(!findtextEx(ui[i], RDSCREEN_NOBREAK))
ui[i] += "<br>"
ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "")
return ui.Join("")
/obj/machinery/rnd/production/proc/ui_header()
var/list/l = list()
l += "<div class='statusDisplay'><b>[host_research.organization] [department_tag] Department Lathe</b>"
l += "Security protocols: [(obj_flags & EMAGGED)? "<font color='red'>Disabled</font>" : "<font color='green'>Enabled</font>"]"
l += "<A href='?src=[REF(src)];switch_screen=[RESEARCH_FABRICATOR_SCREEN_MATERIALS]'><B>Material Amount:</B> [materials.total_amount] / [materials.max_amount]</A>"
l += "<A href='?src=[REF(src)];switch_screen=[RESEARCH_FABRICATOR_SCREEN_CHEMICALS]'><B>Chemical volume:</B> [reagents.total_volume] / [reagents.maximum_volume]</A>"
l += "<a href='?src=[REF(src)];sync_research=1'>Synchronize Research</a>"
l += "<a href='?src=[REF(src)];switch_screen=[RESEARCH_FABRICATOR_SCREEN_MAIN]'>Main Screen</a></div>[RDSCREEN_NOBREAK]"
return l
/obj/machinery/rnd/production/proc/ui_screen_materials()
var/list/l = list()
l += "<div class='statusDisplay'><h3>Material Storage:</h3>"
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
l += "* [M.amount] of [M.name]: "
if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=1'>Eject</A> [RDSCREEN_NOBREAK]"
if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=5'>5x</A> [RDSCREEN_NOBREAK]"
if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "<A href='?src=[REF(src)];ejectsheet=[M.id];eject_amt=50'>All</A>[RDSCREEN_NOBREAK]"
l += ""
l += "</div>[RDSCREEN_NOBREAK]"
return l
/obj/machinery/rnd/production/proc/ui_screen_chemicals()
var/list/l = list()
l += "<div class='statusDisplay'><A href='?src=[REF(src)];disposeall=1'>Disposal All Chemicals in Storage</A>"
l += "<h3>Chemical Storage:</h3>"
for(var/datum/reagent/R in reagents.reagent_list)
l += "[R.name]: [R.volume]"
l += "<A href='?src=[REF(src)];dispose=[R.id]'>Purge</A>"
l += "</div>"
return l
/obj/machinery/rnd/production/proc/ui_screen_search()
var/list/l = list()
var/coeff = efficiency_coeff
l += "<h2>Search Results:</h2>"
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
<input type='hidden' name='search' value='to_search'>\
<input type='text' name='to_search'>\
<input type='submit' value='Search'>\
</form><HR>"
for(var/datum/design/D in matching_designs)
l += design_menu_entry(D, coeff)
l += "</div>"
return l
/obj/machinery/rnd/production/proc/design_menu_entry(datum/design/D, coeff)
if(!istype(D))
return
if(!coeff)
coeff = efficiency_coeff
var/list/l = list()
var/temp_material
var/c = 50
var/t
var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
t = check_mat(D, M)
temp_material += " | "
if (t < 1)
temp_material += "<span class='bad'>[all_materials[M]*coeff] [CallMaterialName(M)]</span>"
else
temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]"
c = min(c,t)
if (c >= 1)
l += "<A href='?src=[REF(src)];build=[D.id];amount=1'>[D.name]</A>[RDSCREEN_NOBREAK]"
if(c >= 5)
l += "<A href='?src=[REF(src)];build=[D.id];amount=5'>x5</A>[RDSCREEN_NOBREAK]"
if(c >= 10)
l += "<A href='?src=[REF(src)];build=[D.id];amount=10'>x10</A>[RDSCREEN_NOBREAK]"
l += "[temp_material][RDSCREEN_NOBREAK]"
else
l += "<span class='linkOff'>[D.name]</span>[temp_material][RDSCREEN_NOBREAK]"
l += ""
return l
/obj/machinery/rnd/production/Topic(raw, ls)
if(..())
return
add_fingerprint(usr)
usr.set_machine(src)
if(ls["switch_screen"])
screen = text2num(ls["switch_screen"])
if(ls["build"]) //Causes the Protolathe to build something.
if(busy)
say("Warning: Fabricators busy!")
else
user_try_print_id(ls["build"], ls["amount"])
if(ls["search"]) //Search for designs with name matching pattern
search(ls["to_search"])
screen = RESEARCH_FABRICATOR_SCREEN_SEARCH
if(ls["sync_research"])
update_research()
say("Synchronizing research with host technology database.")
if(ls["category"])
selected_category = ls["category"]
if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it)
reagents.del_reagent(ls["dispose"])
if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents.
reagents.clear_reagents()
if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material
materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"])
updateUsrDialog()
/obj/machinery/rnd/production/proc/ui_screen_main()
var/list/l = list()
l += "<form name='search' action='?src=[REF(src)]'>\
<input type='hidden' name='src' value='[REF(src)]'>\
<input type='hidden' name='search' value='to_search'>\
<input type='hidden' name='type' value='proto'>\
<input type='text' name='to_search'>\
<input type='submit' value='Search'>\
</form><HR>"
l += list_categories(categories, RESEARCH_FABRICATOR_SCREEN_CATEGORYVIEW)
return l
/obj/machinery/rnd/production/proc/ui_screen_category_view()
if(!selected_category)
return ui_screen_main()
var/list/l = list()
l += "<div class='statusDisplay'><h3>Browsing [selected_category]:</h3>"
var/coeff = efficiency_coeff
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(!(selected_category in D.category)|| !(D.build_type & allowed_buildtypes))
continue
if(!(D.departmental_flags & allowed_department_flags))
continue
l += design_menu_entry(D, coeff)
l += "</div>"
return l
/obj/machinery/rnd/production/proc/list_categories(list/categories, menu_num)
if(!categories)
return
var/line_length = 1
var/list/l = "<table style='width:100%' align='center'><tr>"
for(var/C in categories)
if(line_length > 2)
l += "</tr><tr>"
line_length = 1
l += "<td><A href='?src=[REF(src)];category=[C];switch_screen=[menu_num]'>[C]</A></td>"
line_length++
l += "</tr></table></div>"
return l

View File

@@ -0,0 +1,32 @@
/obj/machinery/rnd/production/circuit_imprinter
name = "circuit imprinter"
desc = "Manufactures circuit boards for the construction of machines."
icon_state = "circuit_imprinter"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/circuit_imprinter
categories = list(
"AI Modules",
"Computer Boards",
"Teleportation Machinery",
"Medical Machinery",
"Engineering Machinery",
"Exosuit Modules",
"Hydroponics Machinery",
"Subspace Telecomms",
"Research Machinery",
"Misc. Machinery",
"Computer Parts"
)
production_animation = "circuit_imprinter_ani"
allowed_buildtypes = IMPRINTER
/obj/machinery/rnd/production/circuit_imprinter/calculate_efficiency()
. = ..()
var/T = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
T += M.rating
efficiency_coeff = 2 ** (T - 1) //Only 1 manipulator here, you're making runtimes Razharas
/obj/machinery/rnd/production/circuit_imprinter/disconnect_console()
linked_console.linked_imprinter = null
..()

View File

@@ -0,0 +1,13 @@
/obj/machinery/rnd/production/circuit_imprinter/department
name = "Department Circuit Imprinter"
desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!"
icon_state = "circuit_imprinter"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/circuit_imprinter/department
requires_console = FALSE
consoleless_interface = TRUE
/obj/machinery/rnd/production/circuit_imprinter/department/science
name = "department protolathe (Science)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE
department_tag = "Science"

View File

@@ -0,0 +1,44 @@
/obj/machinery/rnd/production/protolathe/department
name = "department protolathe"
desc = "A special protolathe with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!"
icon_state = "protolathe"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/protolathe/department
requires_console = FALSE
consoleless_interface = TRUE
/obj/machinery/rnd/production/protolathe/department/engineering
name = "department protolathe (Engineering)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_ENGINEERING
department_tag = "Engineering"
circuit = /obj/item/circuitboard/machine/protolathe/department/engineering
/obj/machinery/rnd/production/protolathe/department/service
name = "department protolathe (Service)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SERVICE
department_tag = "Service"
circuit = /obj/item/circuitboard/machine/protolathe/department/service
/obj/machinery/rnd/production/protolathe/department/medical
name = "department protolathe (Medical)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_MEDICAL
department_tag = "Medical"
circuit = /obj/item/circuitboard/machine/protolathe/department/medical
/obj/machinery/rnd/production/protolathe/department/cargo
name = "department protolathe (Cargo)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_CARGO
department_tag = "Cargo"
circuit = /obj/item/circuitboard/machine/protolathe/department/cargo
/obj/machinery/rnd/production/protolathe/department/science
name = "department protolathe (Science)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE
department_tag = "Science"
circuit = /obj/item/circuitboard/machine/protolathe/department/science
/obj/machinery/rnd/production/protolathe/department/security
name = "department protolathe (Security)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SECURITY
department_tag = "Security"
circuit = /obj/item/circuitboard/machine/protolathe/department/security

View File

@@ -0,0 +1,42 @@
/obj/machinery/rnd/production/techfab/department
name = "department techfab"
desc = "An advanced fabricator designed to print out the latest prototypes and circuits researched from Science. Contains hardware to sync to research networks. This one is department-locked and only possesses a limited set of decryption keys."
icon_state = "protolathe"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/techfab/department
/obj/machinery/rnd/production/techfab/department/engineering
name = "department techfab (Engineering)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_ENGINEERING
department_tag = "Engineering"
circuit = /obj/item/circuitboard/machine/techfab/department/engineering
/obj/machinery/rnd/production/techfab/department/service
name = "department techfab (Service)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SERVICE
department_tag = "Service"
circuit = /obj/item/circuitboard/machine/techfab/department/service
/obj/machinery/rnd/production/techfab/department/medical
name = "department techfab (Medical)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_MEDICAL
department_tag = "Medical"
circuit = /obj/item/circuitboard/machine/techfab/department/medical
/obj/machinery/rnd/production/techfab/department/cargo
name = "department techfab (Cargo)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_CARGO
department_tag = "Cargo"
circuit = /obj/item/circuitboard/machine/techfab/department/cargo
/obj/machinery/rnd/production/techfab/department/science
name = "department techfab (Science)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE
department_tag = "Science"
circuit = /obj/item/circuitboard/machine/techfab/department/science
/obj/machinery/rnd/production/techfab/department/security
name = "department techfab (Security)"
allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SECURITY
department_tag = "Security"
circuit = /obj/item/circuitboard/machine/techfab/department/security

View File

@@ -0,0 +1,32 @@
/obj/machinery/rnd/production/protolathe
name = "protolathe"
desc = "Converts raw materials into useful objects."
icon_state = "protolathe"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/protolathe
categories = list(
"Power Designs",
"Medical Designs",
"Bluespace Designs",
"Stock Parts",
"Equipment",
"Mining Designs",
"Electronics",
"Weapons",
"Ammo",
"Firing Pins",
"Computer Parts"
)
production_animation = "protolathe_n"
allowed_buildtypes = PROTOLATHE
/obj/machinery/rnd/production/protolathe/calculate_efficiency()
. = ..()
efficiency_coeff = 0
for(var/obj/item/stock_parts/manipulator/M in component_parts)
efficiency_coeff += M.rating
efficiency_coeff = max(1, efficiency_coeff)
/obj/machinery/rnd/production/protolathe/disconnect_console()
linked_console.linked_lathe = null
..()

View File

@@ -0,0 +1,35 @@
/obj/machinery/rnd/production/techfab
name = "technology fabricator"
desc = "Produces researched prototypes with raw materials and energy."
icon_state = "protolathe"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/techfab
categories = list(
"Power Designs",
"Medical Designs",
"Bluespace Designs",
"Stock Parts",
"Equipment",
"Mining Designs",
"Electronics",
"Weapons",
"Ammo",
"Firing Pins",
"Computer Parts",
"AI Modules",
"Computer Boards",
"Teleportation Machinery",
"Medical Machinery",
"Engineering Machinery",
"Exosuit Modules",
"Hydroponics Machinery",
"Subspace Telecomms",
"Research Machinery",
"Misc. Machinery",
"Computer Parts"
)
console_link = FALSE
production_animation = "protolathe_n"
requires_console = FALSE
consoleless_interface = TRUE
allowed_buildtypes = PROTOLATHE | IMPRINTER

View File

@@ -1,134 +0,0 @@
/*
Protolathe
Similar to an autolathe, you load glass and metal sheets (but not other objects) into it to be used as raw materials for the stuff
it creates. All the menus and other manipulation commands are in the R&D console.
Note: Must be placed west/left of and R&D console to function.
*/
/obj/machinery/rnd/protolathe
name = "protolathe"
desc = "Converts raw materials into useful objects."
icon_state = "protolathe"
container_type = OPENCONTAINER
circuit = /obj/item/circuitboard/machine/protolathe
var/efficiency_coeff
var/list/categories = list(
"Power Designs",
"Medical Designs",
"Bluespace Designs",
"Stock Parts",
"Equipment",
"Mining Designs",
"Electronics",
"Weapons",
"Ammo",
"Firing Pins",
"Computer Parts"
)
var/datum/component/material_container/materials //Store for hyper speed!
/obj/machinery/rnd/protolathe/Initialize()
create_reagents(0)
materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0,
FALSE, list(/obj/item/stack, /obj/item/stack/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert))
materials.precise_insertion = TRUE
RefreshParts()
return ..()
/obj/machinery/rnd/protolathe/RefreshParts()
reagents.maximum_volume = 0
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.maximum_volume += G.volume
G.reagents.trans_to(src, G.reagents.total_volume)
GET_COMPONENT(materials, /datum/component/material_container)
materials.max_amount = 0
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
materials.max_amount += M.rating * 75000
var/T = 1.2
for(var/obj/item/stock_parts/manipulator/M in component_parts)
T -= M.rating/10
efficiency_coeff = min(max(0, T), 1)
/obj/machinery/rnd/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material
var/list/all_materials = being_built.reagents_list + being_built.materials
GET_COMPONENT(materials, /datum/component/material_container)
var/A = materials.amount(M)
if(!A)
A = reagents.get_reagent_amount(M)
return round(A / max(1, (all_materials[M]*efficiency_coeff)))
//we eject the materials upon deconstruction.
/obj/machinery/rnd/protolathe/on_deconstruction()
for(var/obj/item/reagent_containers/glass/G in component_parts)
reagents.trans_to(G, G.reagents.maximum_volume)
GET_COMPONENT(materials, /datum/component/material_container)
materials.retrieve_all()
..()
/obj/machinery/rnd/protolathe/disconnect_console()
linked_console.linked_lathe = null
..()
/obj/machinery/rnd/protolathe/proc/user_try_print_id(id, amount)
if((!istype(linked_console) && requires_console) || !id)
return FALSE
if(istext(amount))
amount = text2num(amount)
if(isnull(amount))
amount = 1
var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id)
if(!istype(D))
return FALSE
if(D.make_reagents.len)
return FALSE
var/power = 1000
amount = CLAMP(amount, 1, 10)
for(var/M in D.materials)
power += round(D.materials[M] * amount / 5)
power = max(3000, power)
use_power(power)
var/list/efficient_mats = list()
for(var/MAT in D.materials)
efficient_mats[MAT] = D.materials[MAT]*efficiency_coeff
if(!materials.has_materials(efficient_mats, amount))
say("Not enough materials to complete prototype[amount > 1? "s" : ""].")
return FALSE
for(var/R in D.reagents_list)
if(!reagents.has_reagent(R, D.reagents_list[R]*efficiency_coeff))
say("Not enough reagents to complete prototype[amount > 1? "s" : ""].")
return FALSE
materials.use_amount(efficient_mats, amount)
for(var/R in D.reagents_list)
reagents.remove_reagent(R, D.reagents_list[R]*efficiency_coeff)
busy = TRUE
flick("protolathe_n", src)
var/timecoeff = efficiency_coeff * D.lathe_time_factor
addtimer(CALLBACK(src, .proc/reset_busy), (32 * timecoeff * amount) ** 0.8)
addtimer(CALLBACK(src, .proc/do_print, D.build_path, amount, efficient_mats, D.dangerous_construction), (32 * timecoeff * amount) ** 0.8)
return TRUE
/obj/machinery/rnd/protolathe/proc/do_print(path, amount, list/matlist, notify_admins)
if(notify_admins && usr)
investigate_log("[key_name(usr)] built [amount] of [path] at a protolathe.", INVESTIGATE_RESEARCH)
message_admins("[ADMIN_LOOKUPFLW(usr)] has built [amount] of [path] at a protolathe")
for(var/i in 1 to amount)
var/obj/item/I = new path(get_turf(src))
if(!istype(I, /obj/item/stack/sheet) && !istype(I, /obj/item/stack/ore/bluespace_crystal))
I.materials = matlist.Copy()
SSblackbox.record_feedback("nested tally", "item_printed", amount, list("[type]", "[path]"))

View File

@@ -27,8 +27,8 @@ doesn't have toxins access.
circuit = /obj/item/circuitboard/computer/rdconsole
var/obj/machinery/rnd/destructive_analyzer/linked_destroy //Linked Destructive Analyzer
var/obj/machinery/rnd/protolathe/linked_lathe //Linked Protolathe
var/obj/machinery/rnd/circuit_imprinter/linked_imprinter //Linked Circuit Imprinter
var/obj/machinery/rnd/production/protolathe/linked_lathe //Linked Protolathe
var/obj/machinery/rnd/production/circuit_imprinter/linked_imprinter //Linked Circuit Imprinter
req_access = list(ACCESS_TOX) //lA AND SETTING MANIPULATION REQUIRES SCIENTIST ACCESS.
@@ -70,16 +70,16 @@ doesn't have toxins access.
if(linked_destroy == null)
linked_destroy = D
D.linked_console = src
else if(istype(D, /obj/machinery/rnd/protolathe))
else if(istype(D, /obj/machinery/rnd/production/protolathe))
if(linked_lathe == null)
var/obj/machinery/rnd/protolathe/P = D
var/obj/machinery/rnd/production/protolathe/P = D
if(!P.console_link)
continue
linked_lathe = D
D.linked_console = src
else if(istype(D, /obj/machinery/rnd/circuit_imprinter))
else if(istype(D, /obj/machinery/rnd/production/circuit_imprinter))
if(linked_imprinter == null)
var/obj/machinery/rnd/circuit_imprinter/C = D
var/obj/machinery/rnd/production/circuit_imprinter/C = D
if(!C.console_link)
continue
linked_imprinter = D
@@ -720,11 +720,11 @@ doesn't have toxins access.
if(D.build_type)
var/lathes = list()
if(D.build_type & IMPRINTER)
lathes += "<span data-tooltip='Circuit Imprinter'>[machine_icon(/obj/machinery/rnd/circuit_imprinter)]</span>[RDSCREEN_NOBREAK]"
lathes += "<span data-tooltip='Circuit Imprinter'>[machine_icon(/obj/machinery/rnd/production/circuit_imprinter)]</span>[RDSCREEN_NOBREAK]"
if (linked_imprinter && D.id in stored_research.researched_designs)
l += "<A href='?src=[REF(src)];search=1;type=imprint;to_search=[D.name]'>Imprint</A>"
if(D.build_type & PROTOLATHE)
lathes += "<span data-tooltip='Protolathe'>[machine_icon(/obj/machinery/rnd/protolathe)]</span>[RDSCREEN_NOBREAK]"
lathes += "<span data-tooltip='Protolathe'>[machine_icon(/obj/machinery/rnd/production/protolathe)]</span>[RDSCREEN_NOBREAK]"
if (linked_lathe && D.id in stored_research.researched_designs)
l += "<A href='?src=[REF(src)];search=1;type=proto;to_search=[D.name]'>Construct</A>"
if(D.build_type & AUTOLATHE)

View File

@@ -16,7 +16,6 @@
var/shocked = FALSE
var/obj/machinery/computer/rdconsole/linked_console
var/obj/item/loaded_item = null //the item loaded inside the machine (currently only used by experimentor and destructive analyzer)
var/allowed_department_flags = ALL
/obj/machinery/rnd/proc/reset_busy()
busy = FALSE
@@ -47,8 +46,6 @@
if(panel_open)
wires.interact(user)
/obj/machinery/rnd/attackby(obj/item/O, mob/user, params)
if (shocked)
if(shock(user,50))
@@ -114,6 +111,6 @@
else
var/obj/item/stack/S = type_inserted
stack_name = initial(S.name)
use_power(max(1000, (MINERAL_MATERIAL_AMOUNT * amount_inserted / 100)))
use_power(min(1000, (amount_inserted / 100)))
add_overlay("protolathe_[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10)

View File

@@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/effect/clockwork/spatial_gateway,
/obj/structure/destructible/clockwork/powered/clockwork_obelisk,
/obj/item/device/warp_cube,
/obj/machinery/rnd/protolathe, //print tracking beacons, send shuttle
/obj/machinery/rnd/production/protolathe, //print tracking beacons, send shuttle
/obj/machinery/autolathe, //same
/obj/item/projectile/beam/wormhole,
/obj/effect/portal,