///////////////////////////// ///// Part Fabricator /////// ///////////////////////////// /obj/machinery/mecha_part_fabricator icon = 'icons/obj/robotics.dmi' icon_state = "fab-idle" name = "Exosuit Fabricator" desc = "Nothing is being built." density = 1 anchored = 1 use_power = 1 idle_power_usage = 20 active_power_usage = 5000 req_access = list(access_robotics) var/time_coeff = 1.5 //can be upgraded with research var/resource_coeff = 1.5 //can be upgraded with research var/list/resources = list( "metal"=0, "glass"=0, "gold"=0, "silver"=0, "diamond"=0, "phoron"=0, "uranium"=0, ) var/res_max_amount = 200000 var/datum/research/files var/id var/sync = 0 var/part_set var/obj/being_built var/list/queue = list() var/processing_queue = 0 var/screen = "main" var/opened = 0 var/temp var/output_dir = SOUTH //the direction relative to the fabber at which completed parts appear. var/list/part_sets = list( //set names must be unique "Robot"=list( /obj/item/robot_parts/robot_suit, /obj/item/robot_parts/chest, /obj/item/robot_parts/head, /obj/item/robot_parts/l_arm, /obj/item/robot_parts/r_arm, /obj/item/robot_parts/l_leg, /obj/item/robot_parts/r_leg, /obj/item/robot_parts/robot_component/binary_communication_device, /obj/item/robot_parts/robot_component/radio, /obj/item/robot_parts/robot_component/actuator, /obj/item/robot_parts/robot_component/diagnosis_unit, /obj/item/robot_parts/robot_component/camera, /obj/item/robot_parts/robot_component/armour ), "Ripley"=list( /obj/item/mecha_parts/chassis/ripley, /obj/item/mecha_parts/part/ripley_torso, /obj/item/mecha_parts/part/ripley_left_arm, /obj/item/mecha_parts/part/ripley_right_arm, /obj/item/mecha_parts/part/ripley_left_leg, /obj/item/mecha_parts/part/ripley_right_leg ), // "Hoverpod"=list( // /obj/structure/largecrate/hoverpod // Doesn't work, even with required vars. Why? - Gamerofthegame // ), "Odysseus"=list( /obj/item/mecha_parts/chassis/odysseus, /obj/item/mecha_parts/part/odysseus_torso, /obj/item/mecha_parts/part/odysseus_head, /obj/item/mecha_parts/part/odysseus_left_arm, /obj/item/mecha_parts/part/odysseus_right_arm, /obj/item/mecha_parts/part/odysseus_left_leg, /obj/item/mecha_parts/part/odysseus_right_leg ), "Gygax"=list( /obj/item/mecha_parts/chassis/gygax, /obj/item/mecha_parts/part/gygax_torso, /obj/item/mecha_parts/part/gygax_head, /obj/item/mecha_parts/part/gygax_left_arm, /obj/item/mecha_parts/part/gygax_right_arm, /obj/item/mecha_parts/part/gygax_left_leg, /obj/item/mecha_parts/part/gygax_right_leg, /obj/item/mecha_parts/part/gygax_armour ), "Durand"=list( /obj/item/mecha_parts/chassis/durand, /obj/item/mecha_parts/part/durand_torso, /obj/item/mecha_parts/part/durand_head, /obj/item/mecha_parts/part/durand_left_arm, /obj/item/mecha_parts/part/durand_right_arm, /obj/item/mecha_parts/part/durand_left_leg, /obj/item/mecha_parts/part/durand_right_leg, /obj/item/mecha_parts/part/durand_armour ), /*"H.O.N.K"=list( /obj/item/mecha_parts/chassis/honker, /obj/item/mecha_parts/part/honker_torso, /obj/item/mecha_parts/part/honker_head, /obj/item/mecha_parts/part/honker_left_arm, /obj/item/mecha_parts/part/honker_right_arm, /obj/item/mecha_parts/part/honker_left_leg, /obj/item/mecha_parts/part/honker_right_leg ), No need for HONK stuff*/ "Exosuit Equipment"=list( /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/tool/drill, /obj/item/mecha_parts/mecha_equipment/tool/extinguisher, /obj/item/mecha_parts/mecha_equipment/tool/cable_layer, /obj/item/mecha_parts/mecha_equipment/tool/sleeper, /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun, /obj/item/mecha_parts/mecha_equipment/tool/passenger, /obj/item/mecha_parts/chassis/firefighter, ///obj/item/mecha_parts/mecha_equipment/repair_droid, /obj/item/mecha_parts/mecha_equipment/generator, ///obj/item/mecha_parts/mecha_equipment/jetpack, //TODO MECHA JETPACK SPRITE MISSING /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg, ///obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar/mousetrap_mortar, HONK-related mech part ///obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar, Also HONK-related ///obj/item/mecha_parts/mecha_equipment/weapon/honker Thirdly HONK-related ), "Robotic Upgrade Modules" = list( /obj/item/borg/upgrade/reset, /obj/item/borg/upgrade/rename, /obj/item/borg/upgrade/restart, /obj/item/borg/upgrade/vtec, /obj/item/borg/upgrade/tasercooler, /obj/item/borg/upgrade/jetpack ), "Misc"=list(/obj/item/mecha_parts/mecha_tracking) ) /obj/machinery/mecha_part_fabricator/New() ..() component_parts = list() component_parts += new /obj/item/weapon/circuitboard/mechfab(src) component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/matter_bin(src) component_parts += new /obj/item/weapon/stock_parts/manipulator(src) component_parts += new /obj/item/weapon/stock_parts/micro_laser(src) component_parts += new /obj/item/weapon/stock_parts/console_screen(src) RefreshParts() // part_sets["Cyborg Upgrade Modules"] = typesof(/obj/item/borg/upgrade/) - /obj/item/borg/upgrade/ // Eh. This does it dymaically, but to support having the items referenced otherwhere in the code but not being constructable, going to do it manaully. for(var/part_set in part_sets) convert_part_set(part_set) files = new /datum/research(src) //Setup the research data holder. /* if(!id) for(var/obj/machinery/r_n_d/server/centcom/S in world) S.initialize() break */ return /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) T += M.rating res_max_amount = (187500+(T * 37500)) T = 0 for(var/obj/item/weapon/stock_parts/micro_laser/Ma in component_parts) T += Ma.rating if(T >= 1) T -= 1 var/diff diff = round(initial(resource_coeff) - (initial(resource_coeff)*(T))/25,0.01) if(resource_coeff!=diff) resource_coeff = diff T = 0 for(var/obj/item/weapon/stock_parts/manipulator/Ml in component_parts) T += Ml.rating if(T>= 1) T -= 1 diff = round(initial(time_coeff) - (initial(time_coeff)*(T))/25,0.01) if(time_coeff!=diff) time_coeff = diff /obj/machinery/mecha_part_fabricator/Del() for(var/atom/A in src) del A ..() return /obj/machinery/mecha_part_fabricator/proc/operation_allowed(mob/M) if(isrobot(M) || isAI(M)) return 1 if(!istype(req_access) || !req_access.len) return 1 else if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M for(var/ID in list(H.get_active_hand(), H.wear_id, H.belt)) if(src.check_access(ID)) return 1 M << "You don't have required permissions to use [src]" return 0 /obj/machinery/mecha_part_fabricator/proc/emag() sleep() switch(emagged) if(0) emagged = 0.5 src.visible_message("\icon[src] [src] beeps: \"DB error \[Code 0x00F1\]\"") sleep(10) src.visible_message("\icon[src] [src] beeps: \"Attempting auto-repair\"") sleep(15) src.visible_message("\icon[src] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"") sleep(30) src.visible_message("\icon[src] [src] beeps: \"User DB truncated. Please contact your Nanotrasen system operator for future assistance.\"") req_access = null emagged = 1 if(0.5) src.visible_message("\icon[src] [src] beeps: \"DB not responding \[Code 0x0003\]...\"") if(1) src.visible_message("\icon[src] [src] beeps: \"No records in User DB\"") return /obj/machinery/mecha_part_fabricator/proc/convert_part_set(set_name as text) var/list/parts = part_sets[set_name] if(istype(parts, /list)) for(var/i=1;i<=parts.len;i++) var/path = parts[i] var/part = new path(src) if(part) parts[i] = part //debug below if(!istype(parts[i],/obj/item)) return 0 return /obj/machinery/mecha_part_fabricator/proc/add_part_set(set_name as text,parts=null) if(set_name in part_sets)//attempt to create duplicate set return 0 if(isnull(parts)) part_sets[set_name] = list() else part_sets[set_name] = parts convert_part_set(set_name) return 1 /obj/machinery/mecha_part_fabricator/proc/add_part_to_set(set_name as text,part) if(!part) return 0 src.add_part_set(set_name)//if no "set_name" set exists, create var/list/part_set = part_sets[set_name] var/atom/apart if(ispath(part)) apart = new part(src) else apart = part if(!istype(apart)) return 0 for(var/obj/O in part_set) if(O.type == apart.type) del apart return 0 part_set[++part_set.len] = apart return 1 /obj/machinery/mecha_part_fabricator/proc/remove_part_set(set_name as text) for(var/i=1,i<=part_sets.len,i++) if(part_sets[i]==set_name) part_sets.Cut(i,++i) return /* proc/sanity_check() for(var/p in resources) var/index = resources.Find(p) index = resources.Find(p, ++index) if(index) //duplicate resource world << "Duplicate resource definition for [src](\ref[src])" return 0 for(var/set_name in part_sets) var/index = part_sets.Find(set_name) index = part_sets.Find(set_name, ++index) if(index) //duplicate part set world << "Duplicate part set definition for [src](\ref[src])" return 0 return 1 */ /* New() ..() src.add_part_to_set("Test",list("result"="/obj/item/mecha_parts/part/gygax_armour","time"=600,"metal"=75000,"diamond"=10000)) src.add_part_to_set("Test",list("result"="/obj/item/mecha_parts/part/ripley_left_arm","time"=200,"metal"=25000)) src.remove_part_set("Gygax") return */ /obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name) var/output = "" var/list/part_set = listgetindex(part_sets, set_name) if(istype(part_set)) for(var/obj/item/part in part_set) var/resources_available = check_resources(part) output += "
[output_part_info(part)]
\[[resources_available?"Build | ":null]Add to queue\]\[?\]
" return output /obj/machinery/mecha_part_fabricator/proc/output_part_info(var/obj/item/part) var/output = "[part.name] (Cost: [output_part_cost(part)]) [get_construction_time_w_coeff(part)/10]sec" return output /obj/machinery/mecha_part_fabricator/proc/output_part_cost(var/obj/item/part) var/i = 0 var/output if(part.vars.Find("construction_time") && part.vars.Find("construction_cost"))//The most efficient way to go about this. Not all objects have these vars, but if they don't then they CANNOT be made by the mech fab. Doing it this way reduces a major amount of typecasting and switches, while cutting down maintenece for them as well -Sieve for(var/c in part:construction_cost)//The check should ensure that anything without the var doesn't make it to this point if(c in resources) output += "[i?" | ":null][get_resource_cost_w_coeff(part,c)] [c]" i++ return output else return 0 /obj/machinery/mecha_part_fabricator/proc/output_available_resources() var/output for(var/resource in resources) var/amount = min(res_max_amount, resources[resource]) output += "[resource]: [amount] cm³" if(amount>0) output += " - Remove \[1\] | \[10\] | \[All\]" output += "
" return output /obj/machinery/mecha_part_fabricator/proc/remove_resources(var/obj/item/part) //Be SURE to add any new equipment to this switch, but don't be suprised if it spits out children objects if(part.vars.Find("construction_time") && part.vars.Find("construction_cost")) for(var/resource in part:construction_cost) if(resource in src.resources) src.resources[resource] -= get_resource_cost_w_coeff(part,resource) else return /obj/machinery/mecha_part_fabricator/proc/check_resources(var/obj/item/part) // if(istype(part, /obj/item/robot_parts) || istype(part, /obj/item/mecha_parts) || istype(part,/obj/item/borg/upgrade)) //Be SURE to add any new equipment to this switch, but don't be suprised if it spits out children objects if(part.vars.Find("construction_time") && part.vars.Find("construction_cost")) for(var/resource in part:construction_cost) if(resource in src.resources) if(src.resources[resource] < get_resource_cost_w_coeff(part,resource)) return 0 return 1 else return 0 /obj/machinery/mecha_part_fabricator/proc/build_part(var/obj/item/part) if(!part) return // critical exploit prevention, do not remove unless you replace it -walter0o if( !(locate(part, src.contents)) || !(part.vars.Find("construction_time")) || !(part.vars.Find("construction_cost")) ) // these 3 are the current requirements for an object being buildable by the mech_fabricator return src.being_built = new part.type(src) src.desc = "It's building [src.being_built]." src.remove_resources(part) src.overlays += "fab-active" src.use_power = 2 src.updateUsrDialog() sleep(get_construction_time_w_coeff(part)) src.use_power = 1 src.overlays -= "fab-active" src.desc = initial(src.desc) if(being_built) src.being_built.Move(get_step(src,output_dir)) src.visible_message("\icon[src] [src] beeps, \"The following has been completed: [src.being_built] is built\".") src.being_built = null src.updateUsrDialog() return 1 /obj/machinery/mecha_part_fabricator/proc/update_queue_on_page() send_byjax(usr,"mecha_fabricator.browser","queue",src.list_queue()) return /obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(set_name) if(set_name in part_sets) var/list/part_set = part_sets[set_name] if(islist(part_set)) for(var/obj/item/part in part_set) add_to_queue(part) return /obj/machinery/mecha_part_fabricator/proc/add_to_queue(part) if(!istype(queue)) queue = list() if(part) queue[++queue.len] = part return queue.len /obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index) if(!isnum(index) || !istype(queue) || (index<1 || index>queue.len)) return 0 queue.Cut(index,++index) return 1 /obj/machinery/mecha_part_fabricator/proc/process_queue() var/obj/item/part = listgetindex(src.queue, 1) if(!part) remove_from_queue(1) if(src.queue.len) return process_queue() else return if(!(part.vars.Find("construction_time")) || !(part.vars.Find("construction_cost")))//If it shouldn't be printed remove_from_queue(1)//Take it out of the quene return process_queue()//Then reprocess it temp = null while(part) if(stat&(NOPOWER|BROKEN)) return 0 if(!check_resources(part)) src.visible_message("\icon[src] [src] beeps, \"Not enough resources. Queue processing stopped\".") temp = {"Not enough resources to build next part.
Try again | Return"} return 0 remove_from_queue(1) build_part(part) part = listgetindex(src.queue, 1) src.visible_message("\icon[src] [src] beeps, \"Queue processing finished successfully\".") return 1 /obj/machinery/mecha_part_fabricator/proc/list_queue() var/output = "Queue contains:" if(!istype(queue) || !queue.len) output += "
Nothing" else output += "
    " for(var/i=1;i<=queue.len;i++) var/obj/item/part = listgetindex(src.queue, i) if(istype(part)) if(part.vars.Find("construction_time") && part.vars.Find("construction_cost")) output += "[part.name] - [i>1?"":null] [i↓":null] Remove" else//Prevents junk items from even appearing in the list, and they will be silently removed when the fab processes remove_from_queue(i)//Trash it return list_queue()//Rebuild it output += "
" output += "\[Process queue | Clear queue\]" return output /obj/machinery/mecha_part_fabricator/proc/convert_designs() if(!files) return var/i = 0 for(var/datum/design/D in files.known_designs) if(D.build_type&16) if(D.category in part_sets)//Checks if it's a valid category if(add_part_to_set(D.category, text2path(D.build_path)))//Adds it to said category i++ else if(add_part_to_set("Misc", text2path(D.build_path)))//If in doubt, chunk it into the Misc i++ return i /obj/machinery/mecha_part_fabricator/proc/update_tech() if(!files) return var/output for(var/datum/tech/T in files.known_tech) if(T && T.level > 1) var/diff switch(T.id) //bad, bad formulas if("materials") var/pmat = 0//Calculations to make up for the fact that these parts and tech modify the same thing for(var/obj/item/weapon/stock_parts/micro_laser/Ml in component_parts) pmat += Ml.rating if(pmat >= 1) pmat -= 1//So the equations don't have to be reworked, upgrading a single part from T1 to T2 is == to 1 tech level diff = round(initial(resource_coeff) - (initial(resource_coeff)*(T.level+pmat))/25,0.01) if(resource_coeff!=diff) resource_coeff = diff output+="Production efficiency increased.
" if("programming") var/ptime = 0 for(var/obj/item/weapon/stock_parts/manipulator/Ma in component_parts) ptime += Ma.rating if(ptime >= 2) ptime -= 2 diff = round(initial(time_coeff) - (initial(time_coeff)*(T.level+ptime))/25,0.1) if(time_coeff!=diff) time_coeff = diff output+="Production routines updated.
" return output /obj/machinery/mecha_part_fabricator/proc/sync(silent=null) /* if(queue.len) if(!silent) temp = "Error. Please clear processing queue before updating!" src.updateUsrDialog() return */ if(!silent) temp = "Updating local R&D database..." src.updateUsrDialog() sleep(30) //only sleep if called by user var/found = 0 for(var/obj/machinery/computer/rdconsole/RDC in get_area(src)) if(!RDC.sync) continue found++ for(var/datum/tech/T in RDC.files.known_tech) files.AddTech2Known(T) for(var/datum/design/D in RDC.files.known_designs) files.AddDesign2Known(D) files.RefreshResearch() var/i = src.convert_designs() var/tech_output = update_tech() if(!silent) temp = "Processed [i] equipment designs.
" temp += tech_output temp += "Return" src.updateUsrDialog() if(i || tech_output) src.visible_message("\icon[src] [src] beeps, \"Successfully synchronized with R&D server. New data processed.\"") if(found == 0) temp = "Couldn't contact R&D server.
" temp += "Return" src.updateUsrDialog() src.visible_message("\icon[src] [src] beeps, \"Error! Couldn't connect to R&D server.\"") return /obj/machinery/mecha_part_fabricator/proc/get_resource_cost_w_coeff(var/obj/item/part as obj,var/resource as text, var/roundto=1) //Be SURE to add any new equipment to this switch, but don't be suprised if it spits out children objects if(part.vars.Find("construction_time") && part.vars.Find("construction_cost")) return round(part:construction_cost[resource]*resource_coeff, roundto) else return 0 /obj/machinery/mecha_part_fabricator/proc/get_construction_time_w_coeff(var/obj/item/part as obj, var/roundto=1) //Be SURE to add any new equipment to this switch, but don't be suprised if it spits out children objects if(part.vars.Find("construction_time") && part.vars.Find("construction_cost")) return round(part:construction_time*time_coeff, roundto) else return 0 /obj/machinery/mecha_part_fabricator/attack_hand(mob/user as mob) var/dat, left_part if (..()) return if(!operation_allowed(user)) return user.set_machine(src) var/turf/exit = get_step(src,SOUTH) if(exit.density) src.visible_message("\icon[src] [src] beeps, \"Error! Part outlet is obstructed\".") return if(temp) left_part = temp else if(src.being_built) left_part = {"Building [src.being_built.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 = {" [src.name]
[left_part] [list_queue()]
"} user << browse(dat, "window=mecha_fabricator;size=1000x400") onclose(user, "mecha_fabricator") return /obj/machinery/mecha_part_fabricator/proc/exploit_prevention(var/obj/Part, mob/user as mob, var/desc_exploit) // critical exploit prevention, feel free to improve or replace this, but do not remove it -walter0o if(!Part || !user || !istype(Part) || !istype(user)) // sanity return 1 if( !(locate(Part, src.contents)) || !(Part.vars.Find("construction_time")) || !(Part.vars.Find("construction_cost")) ) // these 3 are the current requirements for an object being buildable by the mech_fabricator var/turf/LOC = get_turf(user) message_admins("[key_name_admin(user)] tried to exploit an Exosuit Fabricator to [desc_exploit ? "get the desc of" : "duplicate"] [Part] ! ([LOC ? "JMP" : "null"])", 0) log_admin("EXPLOIT : [key_name(user)] tried to exploit an Exosuit Fabricator to [desc_exploit ? "get the desc of" : "duplicate"] [Part] !") return 1 return null /obj/machinery/mecha_part_fabricator/Topic(href, href_list) if(..()) // critical exploit prevention, do not remove unless you replace it -walter0o return var/datum/topic_input/filter = new /datum/topic_input(href,href_list) if(href_list["part_set"]) var/tpart_set = filter.getStr("part_set") if(tpart_set) if(tpart_set=="clear") src.part_set = null else src.part_set = tpart_set screen = "parts" if(href_list["part"]) var/obj/part = filter.getObj("part") // critical exploit prevention, do not remove unless you replace it -walter0o if(src.exploit_prevention(part, usr)) return if(!processing_queue) build_part(part) else add_to_queue(part) if(href_list["add_to_queue"]) var/obj/part = filter.getObj("add_to_queue") // critical exploit prevention, do not remove unless you replace it -walter0o if(src.exploit_prevention(part, usr)) return add_to_queue(part) return update_queue_on_page() if(href_list["remove_from_queue"]) remove_from_queue(filter.getNum("remove_from_queue")) return update_queue_on_page() if(href_list["partset_to_queue"]) add_part_set_to_queue(filter.get("partset_to_queue")) return update_queue_on_page() if(href_list["process_queue"]) spawn(-1) if(processing_queue || being_built) return 0 processing_queue = 1 process_queue() processing_queue = 0 /* if(href_list["list_queue"]) list_queue() */ if(href_list["clear_temp"]) temp = null if(href_list["screen"]) src.screen = href_list["screen"] if(href_list["queue_move"] && href_list["index"]) var/index = filter.getNum("index") var/new_index = index + filter.getNum("queue_move") if(isnum(index) && isnum(new_index)) if(InRange(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"]) queue = list() src.sync() return update_queue_on_page() if(href_list["part_desc"]) var/obj/part = filter.getObj("part_desc") // critical exploit prevention, do not remove unless you replace it -walter0o if(src.exploit_prevention(part, usr, 1)) return if(part) temp = {"

[part] description:

[part.desc]
Return "} if(href_list["remove_mat"] && href_list["material"]) temp = "Ejected [remove_material(href_list["material"],text2num(href_list["remove_mat"]))] of [href_list["material"]]
Return" src.updateUsrDialog() return /obj/machinery/mecha_part_fabricator/proc/remove_material(var/mat_string, var/amount) var/type switch(mat_string) if("metal") type = /obj/item/stack/sheet/metal if("glass") type = /obj/item/stack/sheet/glass if("gold") type = /obj/item/stack/sheet/mineral/gold if("silver") type = /obj/item/stack/sheet/mineral/silver if("diamond") type = /obj/item/stack/sheet/mineral/diamond if("phoron") type = /obj/item/stack/sheet/mineral/phoron if("uranium") type = /obj/item/stack/sheet/mineral/uranium else return 0 var/result = 0 var/obj/item/stack/sheet/res = new type(src) // amount available to take out var/total_amount = round(resources[mat_string]/res.perunit) // number of stacks we're going to take out res.amount = round(min(total_amount,amount)) if(res.amount>0) resources[mat_string] -= res.amount*res.perunit res.Move(src.loc) result = res.amount else del res return result /obj/machinery/mecha_part_fabricator/attackby(obj/W as obj, mob/user as mob) if(istype(W,/obj/item/weapon/screwdriver)) if (!opened) opened = 1 icon_state = "fab-o" user << "You open the maintenance hatch of [src]." else opened = 0 icon_state = "fab-idle" user << "You close the maintenance hatch of [src]." return if (opened) if(istype(W, /obj/item/weapon/crowbar)) playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) var/obj/machinery/constructable_frame/machine_frame/M = new /obj/machinery/constructable_frame/machine_frame(src.loc) M.state = 2 M.icon_state = "box_1" for(var/obj/I in component_parts) if(I.reliability != 100 && crit_fail) I.crit_fail = 1 I.loc = src.loc if(src.resources["metal"] >= 3750) var/obj/item/stack/sheet/metal/G = new /obj/item/stack/sheet/metal(src.loc) G.amount = round(src.resources["metal"] / G.perunit) if(src.resources["glass"] >= 3750) var/obj/item/stack/sheet/glass/G = new /obj/item/stack/sheet/glass(src.loc) G.amount = round(src.resources["glass"] / G.perunit) if(src.resources["phoron"] >= 2000) var/obj/item/stack/sheet/mineral/phoron/G = new /obj/item/stack/sheet/mineral/phoron(src.loc) G.amount = round(src.resources["phoron"] / G.perunit) if(src.resources["silver"] >= 2000) var/obj/item/stack/sheet/mineral/silver/G = new /obj/item/stack/sheet/mineral/silver(src.loc) G.amount = round(src.resources["silver"] / G.perunit) if(src.resources["gold"] >= 2000) var/obj/item/stack/sheet/mineral/gold/G = new /obj/item/stack/sheet/mineral/gold(src.loc) G.amount = round(src.resources["gold"] / G.perunit) if(src.resources["uranium"] >= 2000) var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium(src.loc) G.amount = round(src.resources["uranium"] / G.perunit) if(src.resources["diamond"] >= 2000) var/obj/item/stack/sheet/mineral/diamond/G = new /obj/item/stack/sheet/mineral/diamond(src.loc) G.amount = round(src.resources["diamond"] / G.perunit) del(src) return 1 else user << "\red You can't load the [src.name] while it's opened." return 1 if(istype(W, /obj/item/weapon/card/emag)) emag() return var/material switch(W.type) if(/obj/item/stack/sheet/mineral/gold) material = "gold" if(/obj/item/stack/sheet/mineral/silver) material = "silver" if(/obj/item/stack/sheet/mineral/diamond) material = "diamond" if(/obj/item/stack/sheet/mineral/phoron) material = "phoron" if(/obj/item/stack/sheet/metal) material = "metal" if(/obj/item/stack/sheet/glass) material = "glass" if(/obj/item/stack/sheet/mineral/uranium) material = "uranium" else return ..() if(src.being_built) user << "The fabricator is currently processing. Please wait until completion." return var/obj/item/stack/sheet/stack = W var/sname = "[stack.name]" var/amnt = stack.perunit if(src.resources[material] < res_max_amount) if(stack && stack.amount >= 1) var/count = 0 src.overlays += "fab-load-[material]"//loading animation is now an overlay based on material type. No more spontaneous conversion of all ores to metal. -vey sleep(10) while(src.resources[material] < res_max_amount && stack) src.resources[material] += amnt stack.use(1) count++ src.overlays -= "fab-load-[material]" user << "You insert [count] [sname] into the fabricator." src.updateUsrDialog() else user << "The fabricator can only accept full sheets of [sname]." return else user << "The fabricator cannot hold more [sname]." return