second batch - MAJOR: mech_fab, turrets
This commit is contained in:
@@ -81,10 +81,10 @@
|
||||
var/obj/machinery/mech_bay_recharge_port/recharge_port
|
||||
light_color = LIGHT_COLOR_PINK
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "MechBayPowerConsole", "Mech Bay Power Control Console", 400, 200, master_ui, state)
|
||||
ui = new(user, src, "MechBayPowerConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/ui_act(action, params)
|
||||
@@ -104,7 +104,6 @@
|
||||
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null, "name" = recharge_port.recharging_mech.name,)
|
||||
if(recharge_port.recharging_mech.cell && !QDELETED(recharge_port.recharging_mech.cell))
|
||||
data["recharge_port"]["mech"]["cell"] = list(
|
||||
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
|
||||
"charge" = recharge_port.recharging_mech.cell.charge,
|
||||
"maxcharge" = recharge_port.recharging_mech.cell.maxcharge
|
||||
)
|
||||
|
||||
+539
-335
@@ -9,17 +9,41 @@
|
||||
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
|
||||
processing_flags = START_PROCESSING_MANUALLY
|
||||
|
||||
subsystem_type = /datum/controller/subsystem/processing/fastprocess
|
||||
|
||||
/// Current items in the build queue.
|
||||
var/list/queue = list()
|
||||
var/processing_queue = 0
|
||||
var/screen = "main"
|
||||
var/temp
|
||||
var/offstation_security_levels = TRUE
|
||||
/// Whether or not the machine is building the entire queue automagically.
|
||||
var/process_queue = FALSE
|
||||
|
||||
/// The current design datum that the machine is building.
|
||||
var/datum/design/being_built
|
||||
/// World time when the build will finish.
|
||||
var/build_finish = 0
|
||||
/// World time when the build started.
|
||||
var/build_start = 0
|
||||
/// Reference to all materials used in the creation of the item being_built.
|
||||
var/list/build_materials
|
||||
/// Part currently stored in the Exofab.
|
||||
var/obj/item/stored_part
|
||||
|
||||
/// Coefficient for the speed of item building. Based on the installed parts.
|
||||
var/time_coeff = 1
|
||||
/// Coefficient for the efficiency of material usage in item building. Based on the installed parts.
|
||||
var/component_coeff = 1
|
||||
|
||||
/// Copy of the currently synced techweb.
|
||||
var/datum/techweb/specialized/autounlocking/exofab/stored_research
|
||||
|
||||
/// Whether the Exofab links to the ore silo on init. Special derelict or maintanance variants should set this to FALSE.
|
||||
var/link_on_init = TRUE
|
||||
|
||||
/// Reference to a remote material inventory, such as an ore silo.
|
||||
var/datum/component/remote_materials/rmat
|
||||
|
||||
/// A list of categories that valid MECHFAB design datums will broadly categorise themselves under.
|
||||
var/list/part_sets = list(
|
||||
"Cyborg",
|
||||
"Ripley",
|
||||
@@ -33,25 +57,17 @@
|
||||
"Exosuit Equipment",
|
||||
"Exosuit Ammunition",
|
||||
"Cyborg Upgrade Modules",
|
||||
"Cybernetics",
|
||||
"Implants",
|
||||
"Control Interfaces",
|
||||
"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
|
||||
/obj/machinery/mecha_part_fabricator/Initialize(mapload)
|
||||
stored_research = new
|
||||
rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init)
|
||||
|
||||
RefreshParts() //Recalculating local material sizes if the fab isn't linked
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/RefreshParts()
|
||||
@@ -60,8 +76,7 @@
|
||||
//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))
|
||||
rmat.set_local_size((200000 + (T*50000)))
|
||||
|
||||
//resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55)
|
||||
T = 1.15
|
||||
@@ -74,89 +89,153 @@
|
||||
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)
|
||||
var/obj/item/circuitboard/machine/mechfab/C = circuit
|
||||
offstation_security_levels = C.offstation_security_levels
|
||||
|
||||
// Adjust the build time of any item currently being built.
|
||||
if(being_built)
|
||||
var/last_const_time = build_finish - build_start
|
||||
var/new_const_time = get_construction_time_w_coeff(initial(being_built.construction_time))
|
||||
var/const_time_left = build_finish - world.time
|
||||
var/new_build_time = (new_const_time / last_const_time) * const_time_left
|
||||
build_finish = world.time + new_build_time
|
||||
|
||||
update_static_data(usr)
|
||||
|
||||
/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>"
|
||||
. += "<span class='notice'>The status display reads: Storing up to <b>[rmat.local_size]</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_clearance(D) && 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/check_clearance(datum/design/D)
|
||||
if(!(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z)) && !ISINRANGE(GLOB.security_level, D.min_security_level, D.max_security_level))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D)
|
||||
var/clearance = !(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z))
|
||||
var/sec_text = ""
|
||||
if(clearance && (D.min_security_level > SEC_LEVEL_GREEN || D.max_security_level < SEC_LEVEL_DELTA))
|
||||
sec_text = " (Allowed security levels: "
|
||||
for(var/n in D.min_security_level to D.max_security_level)
|
||||
sec_text += NUM2SECLEVEL(n)
|
||||
if(n + 1 <= D.max_security_level)
|
||||
sec_text += ", "
|
||||
sec_text += ") "
|
||||
var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [sec_text][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
|
||||
/**
|
||||
* Generates an info list for a given part.
|
||||
*
|
||||
* Returns a list of part information.
|
||||
* * D - Design datum to get information on.
|
||||
* * categories - Boolean, whether or not to parse snowflake categories into the part information list.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D, categories = FALSE)
|
||||
var/cost = list()
|
||||
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
|
||||
cost[M.name] = get_resource_cost_w_coeff(D, M)
|
||||
|
||||
var/obj/built_item = D.build_path
|
||||
|
||||
var/list/category_override = null
|
||||
var/list/sub_category = null
|
||||
|
||||
if(categories)
|
||||
// Handle some special cases to build up sub-categories for the fab interface.
|
||||
// Start with checking if this design builds a cyborg module.
|
||||
if(built_item in typesof(/obj/item/borg/upgrade))
|
||||
var/obj/item/borg/upgrade/U = built_item
|
||||
var/module_types = initial(U.module_flags)
|
||||
sub_category = list()
|
||||
if(module_types)
|
||||
if(module_types & BORG_MODULE_SECURITY)
|
||||
sub_category += "Security"
|
||||
if(module_types & BORG_MODULE_MINER)
|
||||
sub_category += "Mining"
|
||||
if(module_types & BORG_MODULE_JANITOR)
|
||||
sub_category += "Janitor"
|
||||
if(module_types & BORG_MODULE_MEDICAL)
|
||||
sub_category += "Medical"
|
||||
if(module_types & BORG_MODULE_ENGINEERING)
|
||||
sub_category += "Engineering"
|
||||
else
|
||||
sub_category += "All Cyborgs"
|
||||
// Else check if this design builds a piece of exosuit equipment.
|
||||
else if(built_item in typesof(/obj/item/mecha_parts/mecha_equipment))
|
||||
var/obj/item/mecha_parts/mecha_equipment/E = built_item
|
||||
var/mech_types = initial(E.mech_flags)
|
||||
sub_category = "Equipment"
|
||||
if(mech_types)
|
||||
category_override = list()
|
||||
if(mech_types & EXOSUIT_MODULE_RIPLEY)
|
||||
category_override += "Ripley"
|
||||
if(mech_types & EXOSUIT_MODULE_ODYSSEUS)
|
||||
category_override += "Odysseus"
|
||||
// if(mech_types & EXOSUIT_MODULE_CLARKE)
|
||||
// category_override += "Clarke"
|
||||
if(mech_types & EXOSUIT_MODULE_GYGAX)
|
||||
category_override += "Gygax"
|
||||
if(mech_types & EXOSUIT_MODULE_DURAND)
|
||||
category_override += "Durand"
|
||||
if(mech_types & EXOSUIT_MODULE_HONK)
|
||||
category_override += "H.O.N.K"
|
||||
if(mech_types & EXOSUIT_MODULE_PHAZON)
|
||||
category_override += "Phazon"
|
||||
|
||||
|
||||
var/list/part = list(
|
||||
"name" = D.name,
|
||||
"desc" = initial(built_item.desc),
|
||||
"printTime" = get_construction_time_w_coeff(initial(D.construction_time))/10,
|
||||
"cost" = cost,
|
||||
"id" = D.id,
|
||||
"subCategory" = sub_category,
|
||||
"categoryOverride" = category_override,
|
||||
"searchMeta" = D.search_metadata
|
||||
)
|
||||
|
||||
return part
|
||||
|
||||
/**
|
||||
* Generates a list of resources / materials available to this Exosuit Fab
|
||||
*
|
||||
* Returns null if there is no material container available.
|
||||
* List format is list(material_name = list(amount = ..., ref = ..., etc.))
|
||||
*/
|
||||
/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
|
||||
var/datum/component/material_container/materials = rmat.mat_container
|
||||
|
||||
var/list/material_data = list()
|
||||
|
||||
if(materials)
|
||||
for(var/mat_id in materials.materials)
|
||||
var/datum/material/M = mat_id
|
||||
var/list/material_info = list()
|
||||
var/amount = materials.materials[mat_id]
|
||||
|
||||
material_info = list(
|
||||
"name" = M.name,
|
||||
"ref" = REF(M),
|
||||
"amount" = amount,
|
||||
"sheets" = round(amount / MINERAL_MATERIAL_AMOUNT),
|
||||
"removable" = amount >= MINERAL_MATERIAL_AMOUNT
|
||||
)
|
||||
|
||||
material_data += list(material_info)
|
||||
|
||||
return material_data
|
||||
|
||||
return null
|
||||
|
||||
/**
|
||||
* Intended to be called when an item starts printing.
|
||||
*
|
||||
* Adds the overlay to show the fab working and sets active power usage settings.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/on_start_printing()
|
||||
add_overlay("fab-active")
|
||||
use_power = ACTIVE_POWER_USE
|
||||
|
||||
/**
|
||||
* Intended to be called when the exofab has stopped working and is no longer printing items.
|
||||
*
|
||||
* Removes the overlay to show the fab working and sets idle power usage settings. Additionally resets the description and turns off queue processing.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/on_finish_printing()
|
||||
cut_overlay("fab-active")
|
||||
use_power = IDLE_POWER_USE
|
||||
desc = initial(desc)
|
||||
process_queue = FALSE
|
||||
|
||||
/**
|
||||
* Calculates resource/material costs for printing an item based on the machine's resource coefficient.
|
||||
*
|
||||
* Returns a list of k,v resources with their amounts.
|
||||
* * D - Design datum to calculate the modified resource cost of.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D)
|
||||
var/list/resources = list()
|
||||
for(var/R in D.materials)
|
||||
@@ -164,294 +243,416 @@
|
||||
resources[M] = get_resource_cost_w_coeff(D, M)
|
||||
return resources
|
||||
|
||||
/**
|
||||
* Checks if the Exofab has enough resources to print a given item.
|
||||
*
|
||||
* Returns FALSE if the design has no reagents used in its construction (?) or if there are insufficient resources.
|
||||
* Returns TRUE if there are sufficient resources to print the item.
|
||||
* * D - Design datum to calculate the modified resource cost of.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
|
||||
if(D.reagents_list.len) // No reagents storage - no reagent designs.
|
||||
if(length(D.reagents_list)) // No reagents storage - no reagent designs.
|
||||
return FALSE
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/datum/component/material_container/materials = rmat.mat_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)
|
||||
/**
|
||||
* Attempts to build the next item in the build queue.
|
||||
*
|
||||
* Returns FALSE if either there are no more parts to build or the next part is not buildable.
|
||||
* Returns TRUE if the next part has started building.
|
||||
* * verbose - Whether the machine should use say() procs. Set to FALSE to disable the machine saying reasons for failure to build.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/build_next_in_queue(verbose = TRUE)
|
||||
if(!length(queue))
|
||||
return FALSE
|
||||
|
||||
var/datum/design/D = queue[1]
|
||||
if(build_part(D, verbose))
|
||||
remove_from_queue(1)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Starts the build process for a given design datum.
|
||||
*
|
||||
* Returns FALSE if the procedure fails. Returns TRUE when being_built is set.
|
||||
* Uses materials.
|
||||
* * D - Design datum to attempt to print.
|
||||
* * verbose - Whether the machine should use say() procs. Set to FALSE to disable the machine saying reasons for failure to build.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D, verbose = TRUE)
|
||||
if(!D)
|
||||
return FALSE
|
||||
|
||||
var/datum/component/material_container/materials = rmat.mat_container
|
||||
if (!materials)
|
||||
if(verbose)
|
||||
say("No access to material storage, please contact the quartermaster.")
|
||||
return FALSE
|
||||
if (rmat.on_hold())
|
||||
if(verbose)
|
||||
say("Mineral access is on hold, please contact the quartermaster.")
|
||||
return FALSE
|
||||
if(!check_resources(D))
|
||||
if(verbose)
|
||||
say("Not enough resources. Processing stopped.")
|
||||
return FALSE
|
||||
|
||||
build_materials = get_resources_w_coeff(D)
|
||||
|
||||
materials.use_materials(build_materials)
|
||||
being_built = D
|
||||
desc = "It's building \a [initial(D.name)]."
|
||||
var/list/res_coef = get_resources_w_coeff(D)
|
||||
build_finish = world.time + get_construction_time_w_coeff(initial(D.construction_time))
|
||||
build_start = world.time
|
||||
desc = "It's building \a [D.name]."
|
||||
|
||||
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)
|
||||
rmat.silo_log(src, "built", -1, "[D.name]", build_materials)
|
||||
|
||||
var/location = get_step(src,(dir))
|
||||
var/obj/item/I = new D.build_path(location)
|
||||
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/process()
|
||||
// If there's a stored part to dispense due to an obstruction, try to dispense it.
|
||||
if(stored_part)
|
||||
var/turf/exit = get_step(src,(dir))
|
||||
if(exit.density)
|
||||
return TRUE
|
||||
|
||||
/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)
|
||||
say("Obstruction cleared. \The [stored_part] is complete.")
|
||||
stored_part.forceMove(exit)
|
||||
stored_part = null
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(D)
|
||||
// If there's nothing being built, try to build something
|
||||
if(!being_built)
|
||||
// If we're not processing the queue anymore or there's nothing to build, end processing.
|
||||
if(!process_queue || !build_next_in_queue())
|
||||
on_finish_printing()
|
||||
end_processing()
|
||||
return TRUE
|
||||
on_start_printing()
|
||||
|
||||
// If there's an item being built, check if it is complete.
|
||||
if(being_built && (build_finish < world.time))
|
||||
// Then attempt to dispense it and if appropriate build the next item.
|
||||
dispense_built_part(being_built)
|
||||
if(process_queue)
|
||||
build_next_in_queue(FALSE)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Dispenses a part to the tile infront of the Exosuit Fab.
|
||||
*
|
||||
* Returns FALSE is the machine cannot dispense the part on the appropriate turf.
|
||||
* Return TRUE if the part was successfully dispensed.
|
||||
* * D - Design datum to attempt to dispense.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/dispense_built_part(datum/design/D)
|
||||
var/obj/item/I = new D.build_path(src)
|
||||
I.material_flags |= MATERIAL_NO_EFFECTS //Find a better way to do this.
|
||||
I.set_custom_materials(build_materials)
|
||||
|
||||
being_built = null
|
||||
|
||||
var/turf/exit = get_step(src,(dir))
|
||||
if(exit.density)
|
||||
say("Error! Part outlet is obstructed.")
|
||||
desc = "It's trying to dispense \a [D.name], but the part outlet is obstructed."
|
||||
stored_part = I
|
||||
return FALSE
|
||||
|
||||
say("\The [I] is complete.")
|
||||
I.forceMove(exit)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Adds a list of datum designs to the build queue.
|
||||
*
|
||||
* Will only add designs that are in this machine's stored techweb.
|
||||
* Does final checks for datum IDs and makes sure this machine can build the designs.
|
||||
* * part_list - List of datum design ids for designs to add to the queue.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(list/part_list)
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if((D.build_type & MECHFAB) && (D.id in part_list))
|
||||
add_to_queue(D)
|
||||
|
||||
/**
|
||||
* Adds a datum design to the build queue.
|
||||
*
|
||||
* Returns TRUE if successful and FALSE if the design was not added to the queue.
|
||||
* * D - Datum design to add to the queue.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(datum/design/D)
|
||||
if(!istype(queue))
|
||||
queue = list()
|
||||
if(D)
|
||||
queue[++queue.len] = D
|
||||
return queue.len
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Removes datum design from the build queue based on index.
|
||||
*
|
||||
* Returns TRUE if successful and FALSE if a design was not removed from the queue.
|
||||
* * index - Index in the build queue of the element to remove.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index)
|
||||
if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>queue.len))
|
||||
if(!isnum(index) || !ISINTEGER(index) || !istype(queue) || (index<1 || index>length(queue)))
|
||||
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_clearance(D))
|
||||
say("Security level not met. Queue processing stopped.")
|
||||
temp = {"<span class='alert'>Security level not met 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
|
||||
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.")
|
||||
|
||||
/**
|
||||
* Generates a list of parts formatted for tgui based on the current build queue.
|
||||
*
|
||||
* Returns a formatted list of lists containing formatted part information for every part in the build queue.
|
||||
*/
|
||||
/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_clearance(D) ||!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>"
|
||||
if(!istype(queue) || !length(queue))
|
||||
return null
|
||||
|
||||
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
|
||||
var/list/queued_parts = list()
|
||||
for(var/datum/design/D in queue)
|
||||
var/list/part = output_part_info(D)
|
||||
queued_parts += list(part)
|
||||
return queued_parts
|
||||
|
||||
/**
|
||||
* Syncs machine with R&D servers.
|
||||
*
|
||||
* Requires an R&D Console visible within 7 tiles. Copies techweb research. Updates tgui's state data.
|
||||
*/
|
||||
/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))
|
||||
for(var/obj/machinery/computer/rdconsole/RDC in orange(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()
|
||||
update_static_data(usr)
|
||||
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()
|
||||
say("Unable to connect to local R&D server.")
|
||||
return
|
||||
|
||||
/**
|
||||
* Calculates the coefficient-modified resource cost of a single material component of a design's recipe.
|
||||
*
|
||||
* Returns coefficient-modified resource cost for the given material component.
|
||||
* * D - Design datum to pull the resource cost from.
|
||||
* * resource - Material datum reference to the resource to calculate the cost of.
|
||||
* * roundto - Rounding value for round() proc
|
||||
*/
|
||||
/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)
|
||||
/**
|
||||
* Calculates the coefficient-modified build time of a design.
|
||||
*
|
||||
* Returns coefficient-modified build time of a given design.
|
||||
* * D - Design datum to calculate the modified build time of.
|
||||
* * roundto - Rounding value for round() proc
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_construction_time_w_coeff(construction_time, roundto = 1) //aran
|
||||
return round(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>"}
|
||||
/obj/machinery/mecha_part_fabricator/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/spritesheet/sheetmaterials)
|
||||
)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ExosuitFabricator")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/final_sets = list()
|
||||
var/list/buildable_parts = list()
|
||||
|
||||
for(var/part_set in part_sets)
|
||||
final_sets += part_set
|
||||
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if(D.build_type & MECHFAB)
|
||||
// This is for us.
|
||||
var/list/part = output_part_info(D, TRUE)
|
||||
|
||||
if(part["category_override"])
|
||||
for(var/cat in part["category_override"])
|
||||
buildable_parts[cat] += list(part)
|
||||
if(!(cat in part_sets))
|
||||
final_sets += cat
|
||||
continue
|
||||
|
||||
for(var/cat in part_sets)
|
||||
// Find all matching categories.
|
||||
if(!(cat in D.category))
|
||||
continue
|
||||
|
||||
buildable_parts[cat] += list(part)
|
||||
|
||||
data["partSets"] = final_sets
|
||||
data["buildableParts"] = buildable_parts
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["materials"] = output_available_resources()
|
||||
|
||||
if(being_built)
|
||||
var/list/part = list(
|
||||
"name" = being_built.name,
|
||||
"duration" = build_finish - world.time,
|
||||
"printTime" = get_construction_time_w_coeff(initial(being_built.construction_time))
|
||||
)
|
||||
data["buildingPart"] = part
|
||||
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
|
||||
data["buildingPart"] = null
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
|
||||
data["queue"] = list_queue()
|
||||
|
||||
if(stored_part)
|
||||
data["storedPart"] = stored_part.name
|
||||
else
|
||||
data["storedPart"] = null
|
||||
|
||||
data["isProcessingQueue"] = process_queue
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/ui_act(action, var/list/params)
|
||||
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)
|
||||
return TRUE
|
||||
|
||||
. = TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
|
||||
switch(action)
|
||||
if("sync_rnd")
|
||||
// Sync with R&D Servers
|
||||
sync()
|
||||
return
|
||||
if("add_queue_set")
|
||||
// Add all parts of a set to queue
|
||||
var/part_list = params["part_list"]
|
||||
add_part_set_to_queue(part_list)
|
||||
return
|
||||
if("add_queue_part")
|
||||
// Add a specific part to queue
|
||||
var/T = params["id"]
|
||||
for(var/v in stored_research.researched_designs)
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(v)
|
||||
if((D.build_type & MECHFAB) && (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
|
||||
return
|
||||
if("del_queue_part")
|
||||
// Delete a specific from from the queue
|
||||
var/index = text2num(params["index"])
|
||||
remove_from_queue(index)
|
||||
return
|
||||
if("clear_queue")
|
||||
// Delete everything from queue
|
||||
queue.Cut()
|
||||
return
|
||||
if("build_queue")
|
||||
// Build everything in queue
|
||||
if(process_queue)
|
||||
return
|
||||
process_queue = TRUE
|
||||
|
||||
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)
|
||||
if(!being_built)
|
||||
begin_processing()
|
||||
return
|
||||
if("stop_queue")
|
||||
// Pause queue building. Also known as stop.
|
||||
process_queue = FALSE
|
||||
return
|
||||
if("build_part")
|
||||
// Build a single part
|
||||
if(being_built || process_queue)
|
||||
return
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
var/id = params["id"]
|
||||
var/datum/design/D = SSresearch.techweb_design_by_id(id)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/on_deconstruction()
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
materials.retrieve_all()
|
||||
..()
|
||||
if(!(D.build_type & MECHFAB) || !(D.id == id))
|
||||
return
|
||||
|
||||
if(build_part(D))
|
||||
on_start_printing()
|
||||
begin_processing()
|
||||
|
||||
return
|
||||
if("move_queue_part")
|
||||
// Moves a part up or down in the queue.
|
||||
var/index = text2num(params["index"])
|
||||
var/new_index = index + text2num(params["newindex"])
|
||||
if(isnum(index) && isnum(new_index) && ISINTEGER(index) && ISINTEGER(new_index))
|
||||
if(ISINRANGE(new_index,1,length(queue)))
|
||||
queue.Swap(index,new_index)
|
||||
return
|
||||
if("remove_mat")
|
||||
// Remove a material from the fab
|
||||
var/mat_ref = params["ref"]
|
||||
var/amount = text2num(params["amount"])
|
||||
var/datum/material/mat = locate(mat_ref)
|
||||
eject_sheets(mat, amount)
|
||||
return
|
||||
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Eject material sheets.
|
||||
*
|
||||
* Returns the number of sheets successfully ejected.
|
||||
* eject_sheet - Byond REF of the material to eject.
|
||||
* eject_amt - Number of sheets to attempt to eject.
|
||||
*/
|
||||
/obj/machinery/mecha_part_fabricator/proc/eject_sheets(eject_sheet, eject_amt)
|
||||
var/datum/component/material_container/mat_container = rmat.mat_container
|
||||
if (!mat_container)
|
||||
say("No access to material storage, please contact the quartermaster.")
|
||||
return 0
|
||||
if (rmat.on_hold())
|
||||
say("Mineral access is on hold, please contact the quartermaster.")
|
||||
return 0
|
||||
var/count = mat_container.retrieve_sheets(text2num(eject_amt), eject_sheet, drop_location())
|
||||
var/list/matlist = list()
|
||||
matlist[eject_sheet] = text2num(eject_amt)
|
||||
rmat.silo_log(src, "ejected", -count, "sheets", matlist)
|
||||
return count
|
||||
|
||||
/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))
|
||||
/obj/machinery/mecha_part_fabricator/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(being_built)
|
||||
to_chat(user, "<span class='warning'>\The [src] is currently processing! Please wait until completion.</span>")
|
||||
return FALSE
|
||||
return default_deconstruction_screwdriver(user, "fab-o", "fab-idle", I)
|
||||
|
||||
if(default_deconstruction_crowbar(W))
|
||||
/obj/machinery/mecha_part_fabricator/crowbar_act(mob/living/user, obj/item/I)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
return ..()
|
||||
if(being_built)
|
||||
to_chat(user, "<span class='warning'>\The [src] is currently processing! Please wait until completion.</span>")
|
||||
return FALSE
|
||||
return default_deconstruction_crowbar(I)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/is_insertion_ready(mob/user)
|
||||
if(panel_open)
|
||||
@@ -463,6 +664,9 @@
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/maint
|
||||
link_on_init = FALSE
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/offstation
|
||||
offstation_security_levels = FALSE
|
||||
link_on_init = FALSE
|
||||
circuit = /obj/item/circuitboard/machine/mechfab/offstation
|
||||
|
||||
@@ -5,14 +5,11 @@
|
||||
icon_keyboard = "tech_key"
|
||||
req_access = list(ACCESS_ROBOTICS)
|
||||
circuit = /obj/item/circuitboard/computer/mecha_control
|
||||
ui_x = 500
|
||||
ui_y = 500
|
||||
|
||||
/obj/machinery/computer/mecha/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/mecha/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ExosuitControlConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "ExosuitControlConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/mecha/ui_data(mob/user)
|
||||
|
||||
Reference in New Issue
Block a user