mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 01:49:19 +00:00
443 lines
15 KiB
Plaintext
443 lines
15 KiB
Plaintext
/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",
|
|
"Exosuit Ammunition",
|
|
"Cyborg Upgrade Modules",
|
|
"Misc"
|
|
)
|
|
|
|
/obj/machinery/mecha_part_fabricator/Initialize()
|
|
var/static/list/allowed_types = list(
|
|
/datum/material/iron,
|
|
/datum/material/glass,
|
|
/datum/material/silver,
|
|
/datum/material/gold,
|
|
/datum/material/diamond,
|
|
/datum/material/plasma,
|
|
/datum/material/uranium,
|
|
/datum/material/bananium,
|
|
/datum/material/titanium,
|
|
/datum/material/bluespace
|
|
)
|
|
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, allowed_types, 0, TRUE, /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
|
|
var/datum/component/material_container/materials = GetComponent(/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/examine(mob/user)
|
|
. = ..()
|
|
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
|
if(in_range(user, src) || isobserver(user))
|
|
. += "<span class='notice'>The status display reads: Storing up to <b>[materials.max_amount]</b> material units.<br>Material consumption at <b>[component_coeff*100]%</b>.<br>Build time reduced by <b>[100-time_coeff*100]%</b>.</span>"
|
|
|
|
/obj/machinery/mecha_part_fabricator/emag_act()
|
|
. = ..()
|
|
if(obj_flags & EMAGGED)
|
|
return
|
|
obj_flags |= EMAGGED
|
|
req_access = list()
|
|
INVOKE_ASYNC(src, .proc/error_action_sucessful)
|
|
return TRUE
|
|
|
|
/obj/machinery/mecha_part_fabricator/proc/error_action_sucessful()
|
|
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 = SSresearch.techweb_design_by_id(v)
|
|
if(D.build_type & MECHFAB)
|
|
if(!(set_name in D.category))
|
|
continue
|
|
output += "<div class='part'>[output_part_info(D)]<br>\["
|
|
if(check_resources(D))
|
|
output += "<a href='?src=[REF(src)];part=[D.id]'>Build</a> | "
|
|
output += "<a href='?src=[REF(src)];add_to_queue=[D.id]'>Add to queue</a>\]\[<a href='?src=[REF(src)];part_desc=[D.id]'>?</a>\]</div>"
|
|
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)
|
|
var/datum/material/M = c
|
|
output += "[i?" | ":null][get_resource_cost_w_coeff(D, M)] [M.name]"
|
|
i++
|
|
return output
|
|
|
|
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
|
|
var/output
|
|
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
|
for(var/mat_id in materials.materials)
|
|
var/datum/material/M = mat_id
|
|
var/amount = materials.materials[mat_id]
|
|
output += "<span class=\"res_name\">[M.name]: </span>[amount] cm³"
|
|
if(amount >= MINERAL_MATERIAL_AMOUNT)
|
|
output += "<span style='font-size:80%;'>- Remove \[<a href='?src=[REF(src)];remove_mat=1;material=[REF(mat_id)]'>1</a>\]"
|
|
if(amount >= (MINERAL_MATERIAL_AMOUNT * 10))
|
|
output += " | \[<a href='?src=[REF(src)];remove_mat=10;material=[REF(M)]'>10</a>\]"
|
|
output += " | \[<a href='?src=[REF(src)];remove_mat=50;material=[REF(M)]'>All</a>\]</span>"
|
|
output += "<br/>"
|
|
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)
|
|
var/datum/material/M = R
|
|
resources[M] = get_resource_cost_w_coeff(D, M)
|
|
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
|
|
var/datum/component/material_container/materials = GetComponent(/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)
|
|
|
|
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
|
materials.use_materials(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.material_flags |= MATERIAL_NO_EFFECTS //Find a better way to do this.
|
|
I.set_custom_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 = SSresearch.techweb_design_by_id(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 = {"<span class='alert'>Not enough resources to build next part.</span><br>
|
|
<a href='?src=[REF(src)];process_queue=1'>Try again</a> | <a href='?src=[REF(src)];clear_temp=1'>Return</a><a>"}
|
|
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 = "<b>Queue contains:</b>"
|
|
if(!istype(queue) || !queue.len)
|
|
output += "<br>Nothing"
|
|
else
|
|
output += "<ol>"
|
|
var/i = 0
|
|
for(var/datum/design/D in queue)
|
|
i++
|
|
var/obj/part = D.build_path
|
|
output += "<li[!check_resources(D)?" style='color: #f00;'":null]>"
|
|
output += initial(part.name) + " - "
|
|
output += "[i>1?"<a href='?src=[REF(src)];queue_move=-1;index=[i]' class='arrow'>↑</a>":null] "
|
|
output += "[i<queue.len?"<a href='?src=[REF(src)];queue_move=+1;index=[i]' class='arrow'>↓</a>":null] "
|
|
output += "<a href='?src=[REF(src)];remove_from_queue=[i]'>Remove</a></li>"
|
|
|
|
output += "</ol>"
|
|
output += "\[<a href='?src=[REF(src)];process_queue=1'>Process queue</a> | <a href='?src=[REF(src)];clear_queue=1'>Clear queue</a>\]"
|
|
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.<br>"
|
|
//check if the tech coefficients have changed
|
|
temp += "<a href='?src=[REF(src)];clear_temp=1'>Return</a>"
|
|
|
|
updateUsrDialog()
|
|
say("Successfully synchronized with R&D server.")
|
|
return
|
|
|
|
temp = "Unable to connect to local R&D Database.<br>Please check your connections and try again.<br><a href='?src=[REF(src)];clear_temp=1'>Return</a>"
|
|
updateUsrDialog()
|
|
return
|
|
|
|
/obj/machinery/mecha_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, var/datum/material/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 = {"<TT>Building [initial(I.name)].<BR>
|
|
Please wait until completion...</TT>"}
|
|
else
|
|
switch(screen)
|
|
if("main")
|
|
left_part = output_available_resources()+"<hr>"
|
|
left_part += "<a href='?src=[REF(src)];sync=1'>Sync with R&D servers</a><hr>"
|
|
for(var/part_set in part_sets)
|
|
left_part += "<a href='?src=[REF(src)];part_set=[part_set]'>[part_set]</a> - \[<a href='?src=[REF(src)];partset_to_queue=[part_set]'>Add all parts to queue</a>\]<br>"
|
|
if("parts")
|
|
left_part += output_parts_list(part_set)
|
|
left_part += "<hr><a href='?src=[REF(src)];screen=main'>Return</a>"
|
|
dat = {"<html>
|
|
<head>
|
|
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
|
<title>[name] data</title>
|
|
<style>
|
|
.res_name {font-weight: bold; text-transform: capitalize;}
|
|
.red {color: #f00;}
|
|
.part {margin-bottom: 10px;}
|
|
.arrow {text-decoration: none; font-size: 10px;}
|
|
body, table {height: 100%;}
|
|
td {vertical-align: top; padding: 5px;}
|
|
html, body {padding: 0px; margin: 0px;}
|
|
h1 {font-size: 18px; margin: 5px 0px;}
|
|
</style>
|
|
<script language='javascript' type='text/javascript'>
|
|
[js_byjax]
|
|
</script>
|
|
</head><body>
|
|
<body>
|
|
<table style='width: 100%;'>
|
|
<tr>
|
|
<td style='width: 65%; padding-right: 10px;'>
|
|
[left_part]
|
|
</td>
|
|
<td style='width: 35%; background: #ccc;' id='queue'>
|
|
[list_queue()]
|
|
</td>
|
|
<tr>
|
|
</table>
|
|
</body>
|
|
</html>"}
|
|
user << browse(dat, "window=mecha_fabricator;size=1000x430")
|
|
onclose(user, "mecha_fabricator")
|
|
return
|
|
|
|
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
|
|
if(..())
|
|
return
|
|
if(href_list["part_set"])
|
|
var/tpart_set = href_list["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 = href_list["part"]
|
|
for(var/v in stored_research.researched_designs)
|
|
var/datum/design/D = SSresearch.techweb_design_by_id(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 = href_list["add_to_queue"]
|
|
for(var/v in stored_research.researched_designs)
|
|
var/datum/design/D = SSresearch.techweb_design_by_id(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(text2num(href_list["remove_from_queue"]))
|
|
return update_queue_on_page()
|
|
if(href_list["partset_to_queue"])
|
|
add_part_set_to_queue(href_list["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 = text2num(href_list["index"])
|
|
var/new_index = index + text2num(href_list["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 = href_list["part_desc"]
|
|
for(var/v in stored_research.researched_designs)
|
|
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
|
if(D.build_type & MECHFAB)
|
|
if(D.id == T)
|
|
var/obj/part = D.build_path
|
|
temp = {"<h1>[initial(part.name)] description:</h1>
|
|
[initial(part.desc)]<br>
|
|
<a href='?src=[REF(src)];clear_temp=1'>Return</a>
|
|
"}
|
|
break
|
|
|
|
if(href_list["remove_mat"] && href_list["material"])
|
|
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
|
var/datum/material/Mat = locate(href_list["material"])
|
|
materials.retrieve_sheets(text2num(href_list["remove_mat"]), Mat)
|
|
|
|
updateUsrDialog()
|
|
return
|
|
|
|
/obj/machinery/mecha_part_fabricator/on_deconstruction()
|
|
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
|
materials.retrieve_all()
|
|
..()
|
|
|
|
/obj/machinery/mecha_part_fabricator/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
|
|
var/datum/material/M = id_inserted
|
|
add_overlay("fab-load-[M.name]")
|
|
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "fab-load-[M.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/is_insertion_ready(mob/user)
|
|
if(panel_open)
|
|
to_chat(user, "<span class='warning'>You can't load [src] while it's opened!</span>")
|
|
return FALSE
|
|
if(being_built)
|
|
to_chat(user, "<span class='warning'>\The [src] is currently processing! Please wait until completion.</span>")
|
|
return FALSE
|
|
|
|
return TRUE
|