/obj/machinery/mecha_part_fabricator
icon = 'icons/obj/robotics.dmi'
icon_state = "fab-idle"
name = "exosuit fabricator"
desc = "Nothing is being built."
density = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 20
active_power_usage = 5000
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/machine/mechfab
var/time_coeff = 1
var/component_coeff = 1
var/datum/techweb/specialized/autounlocking/exofab/stored_research
var/sync = 0
var/part_set
var/datum/design/being_built
var/list/queue = list()
var/processing_queue = 0
var/screen = "main"
var/temp
var/list/part_sets = list(
"Cyborg",
"Ripley",
"Firefighter",
"Odysseus",
"Gygax",
"Durand",
"H.O.N.K",
"Phazon",
"Exosuit Equipment",
"Cyborg Upgrade Modules",
"Misc"
)
/obj/machinery/mecha_part_fabricator/Initialize()
var/datum/component/material_container/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
stored_research = new
return ..()
/obj/machinery/mecha_part_fabricator/RefreshParts()
var/T = 0
//maximum stocking amount (default 300000, 600000 at T4)
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
T += M.rating
GET_COMPONENT(materials, /datum/component/material_container)
materials.max_amount = (200000 + (T*50000))
//resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55)
T = 1.15
for(var/obj/item/stock_parts/micro_laser/Ma in component_parts)
T -= Ma.rating*0.15
component_coeff = T
//building time adjustment coefficient (1 -> 0.8 -> 0.6)
T = -1
for(var/obj/item/stock_parts/manipulator/Ml in component_parts)
T += Ml.rating
time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01)
/obj/machinery/mecha_part_fabricator/emag_act()
if(obj_flags & EMAGGED)
return
obj_flags |= EMAGGED
req_access = list()
say("DB error \[Code 0x00F1\]")
sleep(10)
say("Attempting auto-repair...")
sleep(15)
say("User DB corrupted \[Code 0x00FA\]. Truncating data structure...")
sleep(30)
say("User DB truncated. Please contact your Nanotrasen system operator for future assistance.")
/obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name)
var/output = ""
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(D.build_type & MECHFAB)
if(!(set_name in D.category))
continue
output += "
[output_part_info(D)]
\["
if(check_resources(D))
output += "
Build | "
output += "
Add to queue\]\[
?\]
"
return output
/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D)
var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10]sec"
return output
/obj/machinery/mecha_part_fabricator/proc/output_part_cost(datum/design/D)
var/i = 0
var/output
for(var/c in D.materials)
output += "[i?" | ":null][get_resource_cost_w_coeff(D, c)] [material2name(c)]"
i++
return output
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
var/output
GET_COMPONENT(materials, /datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
output += "[M.name]: [M.amount] cm³"
if(M.amount >= MINERAL_MATERIAL_AMOUNT)
output += "- Remove \[1\]"
if(M.amount >= (MINERAL_MATERIAL_AMOUNT * 10))
output += " | \[10\]"
output += " | \[All\]"
output += "
"
return output
/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D)
var/list/resources = list()
for(var/R in D.materials)
resources[R] = get_resource_cost_w_coeff(D, R)
return resources
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
if(D.reagents_list.len) // No reagents storage - no reagent designs.
return FALSE
GET_COMPONENT(materials, /datum/component/material_container)
if(materials.has_materials(get_resources_w_coeff(D)))
return TRUE
return FALSE
/obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D)
being_built = D
desc = "It's building \a [initial(D.name)]."
var/list/res_coef = get_resources_w_coeff(D)
GET_COMPONENT(materials, /datum/component/material_container)
materials.use_amount(res_coef)
add_overlay("fab-active")
use_power = ACTIVE_POWER_USE
updateUsrDialog()
sleep(get_construction_time_w_coeff(D))
use_power = IDLE_POWER_USE
cut_overlay("fab-active")
desc = initial(desc)
var/location = get_step(src,(dir))
var/obj/item/I = new D.build_path(location)
I.materials = res_coef
say("\The [I] is complete.")
being_built = null
updateUsrDialog()
return TRUE
/obj/machinery/mecha_part_fabricator/proc/update_queue_on_page()
send_byjax(usr,"mecha_fabricator.browser","queue",list_queue())
return
/obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(set_name)
if(set_name in part_sets)
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(D.build_type & MECHFAB)
if(set_name in D.category)
add_to_queue(D)
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(D)
if(!istype(queue))
queue = list()
if(D)
queue[++queue.len] = D
return queue.len
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index)
if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>queue.len))
return FALSE
queue.Cut(index,++index)
return TRUE
/obj/machinery/mecha_part_fabricator/proc/process_queue()
var/datum/design/D = queue[1]
if(!D)
remove_from_queue(1)
if(queue.len)
return process_queue()
else
return
temp = null
while(D)
if(stat&(NOPOWER|BROKEN))
return FALSE
if(!check_resources(D))
say("Not enough resources. Queue processing stopped.")
temp = {"Not enough resources to build next part.
Try again | Return"}
return FALSE
remove_from_queue(1)
build_part(D)
D = listgetindex(queue, 1)
say("Queue processing finished successfully.")
/obj/machinery/mecha_part_fabricator/proc/list_queue()
var/output = "Queue contains:"
if(!istype(queue) || !queue.len)
output += "
Nothing"
else
output += ""
var/i = 0
for(var/datum/design/D in queue)
i++
var/obj/part = D.build_path
output += "- "
output += initial(part.name) + " - "
output += "[i>1?"↑":null] "
output += "[i↓
":null] "
output += "Remove"
output += ""
output += "\[Process queue | Clear queue\]"
return output
/obj/machinery/mecha_part_fabricator/proc/sync()
temp = "Updating local R&D database..."
updateUsrDialog()
sleep(30) //only sleep if called by user
for(var/obj/machinery/computer/rdconsole/RDC in oview(7,src))
RDC.stored_research.copy_research_to(stored_research)
temp = "Processed equipment designs.
"
//check if the tech coefficients have changed
temp += "Return"
updateUsrDialog()
say("Successfully synchronized with R&D server.")
return
temp = "Unable to connect to local R&D Database.
Please check your connections and try again.
Return"
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, resource, roundto = 1)
return round(D.materials[resource]*component_coeff, roundto)
/obj/machinery/mecha_part_fabricator/proc/get_construction_time_w_coeff(datum/design/D, roundto = 1) //aran
return round(initial(D.construction_time)*time_coeff, roundto)
/obj/machinery/mecha_part_fabricator/ui_interact(mob/user as mob)
. = ..()
var/dat, left_part
user.set_machine(src)
var/turf/exit = get_step(src,(dir))
if(exit.density)
say("Error! Part outlet is obstructed.")
return
if(temp)
left_part = temp
else if(being_built)
var/obj/I = being_built.build_path
left_part = {"Building [initial(I.name)].
Please wait until completion..."}
else
switch(screen)
if("main")
left_part = output_available_resources()+"
"
left_part += "Sync with R&D servers
"
for(var/part_set in part_sets)
left_part += "[part_set] - \[Add all parts to queue\]
"
if("parts")
left_part += output_parts_list(part_set)
left_part += "
Return"
dat = {"
[name]
|
[left_part]
|
[list_queue()]
|
"}
user << browse(dat, "window=mecha_fabricator;size=1000x430")
onclose(user, "mecha_fabricator")
return
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
if(..())
return
var/datum/topic_input/afilter = new /datum/topic_input(href,href_list)
if(href_list["part_set"])
var/tpart_set = afilter.getStr("part_set")
if(tpart_set)
if(tpart_set=="clear")
part_set = null
else
part_set = tpart_set
screen = "parts"
if(href_list["part"])
var/T = afilter.getStr("part")
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(D.build_type & MECHFAB)
if(D.id == T)
if(!processing_queue)
build_part(D)
else
add_to_queue(D)
break
if(href_list["add_to_queue"])
var/T = afilter.getStr("add_to_queue")
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(D.build_type & MECHFAB)
if(D.id == T)
add_to_queue(D)
break
return update_queue_on_page()
if(href_list["remove_from_queue"])
remove_from_queue(afilter.getNum("remove_from_queue"))
return update_queue_on_page()
if(href_list["partset_to_queue"])
add_part_set_to_queue(afilter.get("partset_to_queue"))
return update_queue_on_page()
if(href_list["process_queue"])
spawn(0)
if(processing_queue || being_built)
return FALSE
processing_queue = 1
process_queue()
processing_queue = 0
if(href_list["clear_temp"])
temp = null
if(href_list["screen"])
screen = href_list["screen"]
if(href_list["queue_move"] && href_list["index"])
var/index = afilter.getNum("index")
var/new_index = index + afilter.getNum("queue_move")
if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index))
if(ISINRANGE(new_index,1,queue.len))
queue.Swap(index,new_index)
return update_queue_on_page()
if(href_list["clear_queue"])
queue = list()
return update_queue_on_page()
if(href_list["sync"])
sync()
if(href_list["part_desc"])
var/T = afilter.getStr("part_desc")
for(var/v in stored_research.researched_designs)
var/datum/design/D = stored_research.researched_designs[v]
if(D.build_type & MECHFAB)
if(D.id == T)
var/obj/part = D.build_path
temp = {"[initial(part.name)] description:
[initial(part.desc)]
Return
"}
break
if(href_list["remove_mat"] && href_list["material"])
GET_COMPONENT(materials, /datum/component/material_container)
materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"])
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/on_deconstruction()
GET_COMPONENT(materials, /datum/component/material_container)
materials.retrieve_all()
..()
/obj/machinery/mecha_part_fabricator/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
var/stack_name = material2name(id_inserted)
add_overlay("fab-load-[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[stack_name]"), 10)
updateUsrDialog()
/obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params)
if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W))
return TRUE
if(default_deconstruction_crowbar(W))
return TRUE
return ..()
/obj/machinery/mecha_part_fabricator/proc/material2name(ID)
return copytext(ID,2)
/obj/machinery/mecha_part_fabricator/proc/is_insertion_ready(mob/user)
if(panel_open)
to_chat(user, "You can't load [src] while it's opened!")
return FALSE
if(being_built)
to_chat(user, "\The [src] is currently processing! Please wait until completion.")
return FALSE
return TRUE