mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-23 04:51:32 +01:00
Also generalizes autolathe recycling so that other containers can alt click it to be recycled. Currently its still only circuits and the part exchanger. changes: - qol: "Integrated circuit assemblies can now be recycled in autolathes. They can't be recycled in the printer, because clicking the printer with the circuit is required to scan it for cloning." - qol: "Integrated circuits can now be charged in rechargers." https://github.com/user-attachments/assets/1b8325a8-aca0-4df0-a2a3-763eb8cec989
329 lines
11 KiB
Plaintext
329 lines
11 KiB
Plaintext
ABSTRACT_TYPE(/obj/structure/machinery/fabricator)
|
|
density = TRUE
|
|
anchored = TRUE
|
|
use_power = POWER_USE_IDLE
|
|
idle_power_usage = 10
|
|
active_power_usage = 2000
|
|
clicksound = SFX_KEYBOARD
|
|
clickvol = 30
|
|
manufacturer = "hephaestus"
|
|
|
|
/// What location to print to. Only used for mounted autolathes
|
|
var/atom/print_loc
|
|
|
|
/// Class of fabricator. Determines recipes loaded. See entries in [__fabricator_defines.dm]
|
|
var/fabricator_class = FABRICATOR_CLASS_GENERAL
|
|
/// List of stored materials.
|
|
var/list/stored_material = list()
|
|
/// List of material capacities. Should not be modified directly, use [var/list/base_storage_capacity] instead.
|
|
var/list/storage_capacity = list()
|
|
/// Base storage capacity, which is modified by default by the amount and tier of matter bins.
|
|
var/list/base_storage_capacity = list(
|
|
MATERIAL_STEEL = 25000,
|
|
MATERIAL_ALUMINIUM = 25000,
|
|
MATERIAL_GLASS = 12500,
|
|
MATERIAL_PLASTIC = 12500,
|
|
MATERIAL_PHORON = 12500
|
|
)
|
|
/// Current category to show for this fabricator
|
|
var/show_category = "All"
|
|
|
|
/// Status bitflags for the fabricator
|
|
var/fab_status_flags = 0
|
|
|
|
/// Current queue for this fabricator
|
|
var/list/print_queue = list()
|
|
/// What is currently printing in this fabricator
|
|
var/datum/fabricator_build_order/currently_printing
|
|
|
|
/// Global list of the substances currently stored in the fabricator
|
|
var/static/list/stored_substances_to_names = list()
|
|
|
|
/// How efficiently this fabricator uses materials. Modified by default by the amount and tier of micro lasers
|
|
var/mat_efficiency = 1
|
|
/// What to multiply build times by. Modified by default by the amount and tier of manipulators
|
|
var/build_time_multiplier = 1
|
|
|
|
/// Snowflake for mounted autolathes
|
|
var/does_flick = TRUE
|
|
|
|
/// The fabricator's wires
|
|
var/datum/wires/fabricator/wires
|
|
|
|
component_types = list(
|
|
/obj/item/circuitboard/autolathe,
|
|
/obj/item/stock_parts/matter_bin = 3,
|
|
/obj/item/stock_parts/micro_laser,
|
|
/obj/item/stock_parts/manipulator,
|
|
/obj/item/stock_parts/console_screen
|
|
)
|
|
|
|
///The sound this fabricator will emit while running
|
|
var/fabricating_sound_loop = /datum/looping_sound/fabricator
|
|
|
|
///The looping sound used while the fabricator is running
|
|
VAR_PRIVATE/datum/looping_sound/fabricator_looping_sound
|
|
|
|
/obj/structure/machinery/fabricator/upgrade_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "- Upgraded <b>matter bins</b> will increase material storage capacity."
|
|
. += SPAN_NOTICE(" - The current storage limit per material type is <b>[SSmaterials.get_material_amount(storage_capacity, MATERIAL_STEEL) / 2000]</b> sheets")
|
|
. += "- Upgraded <b>micro lasers</b> will improve material use efficiency."
|
|
. += SPAN_NOTICE(" - The current material cost reduction is <b>[round((1 - mat_efficiency) * 100)]%</b>")
|
|
. += "- Upgraded <b>manipulators</b> will increase the fabrication speed."
|
|
. += SPAN_NOTICE(" - The current build speed increase is <b>[round(build_time_multiplier * 100)]%</b>")
|
|
|
|
/obj/structure/machinery/fabricator/Initialize(mapload)
|
|
wires = new(src)
|
|
print_loc = src
|
|
base_storage_capacity = base_storage_capacity.Copy()
|
|
SSmaterials.normalize_material_amounts(base_storage_capacity)
|
|
stored_material = list()
|
|
for(var/mat in base_storage_capacity)
|
|
stored_material[mat] = 0
|
|
|
|
// Update global type to string cache.
|
|
if(!stored_substances_to_names[mat])
|
|
if(ispath(mat, /singleton/material))
|
|
var/singleton/material/mat_instance = mat
|
|
mat_instance = GET_SINGLETON(mat_instance)
|
|
if(istype(mat_instance))
|
|
stored_substances_to_names[mat] = mat_instance.display_name
|
|
else if(ispath(mat, /singleton/reagent))
|
|
var/singleton/reagent/reg = mat
|
|
stored_substances_to_names[mat] = initial(reg.name)
|
|
update_icon()
|
|
. = ..()
|
|
|
|
/obj/structure/machinery/fabricator/proc/normalize_material_storage()
|
|
SSmaterials.normalize_material_amounts(stored_material)
|
|
SSmaterials.normalize_material_amounts(storage_capacity)
|
|
|
|
/obj/structure/machinery/fabricator/Destroy()
|
|
print_loc = null
|
|
QDEL_NULL(currently_printing)
|
|
QDEL_NULL(wires)
|
|
|
|
QDEL_LIST(print_queue)
|
|
QDEL_NULL(fabricator_looping_sound)
|
|
|
|
return ..()
|
|
|
|
/obj/structure/machinery/fabricator/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "Autolathe", capitalize_first_letters(name))
|
|
ui.open()
|
|
|
|
/obj/structure/machinery/fabricator/ui_data(mob/user)
|
|
. = ..()
|
|
normalize_material_storage()
|
|
var/list/data = list()
|
|
data["manufacturer"] = manufacturer
|
|
data["disabled"] = (fab_status_flags & FAB_DISABLED)
|
|
data["material_efficiency"] = mat_efficiency
|
|
data["materials"] = list()
|
|
data["categories"] = SSfabrication.get_categories(fabricator_class)|"All"
|
|
data["build_time"] = currently_printing?.remaining_time
|
|
data["show_category"] = show_category
|
|
for(var/material in stored_material)
|
|
data["materials"] += list(list("material" = SSmaterials.material_display_name(material), "stored" = stored_material[material], "max_capacity" = storage_capacity[material]))
|
|
data["recipes"] = list()
|
|
for(var/recipe in SSfabrication.get_recipes(fabricator_class))
|
|
var/singleton/fabricator_recipe/R = recipe
|
|
if(R.hack_only && !(fab_status_flags & FAB_HACKED))
|
|
continue
|
|
var/list/recipe_data = list()
|
|
recipe_data["name"] = R.name
|
|
recipe_data["recipe"] = R.type
|
|
recipe_data["security_level"] = R.security_level ? capitalize(num2seclevel(R.security_level)) : "None"
|
|
recipe_data["hack_only"] = R.hack_only
|
|
recipe_data["enabled"] = can_print_item(R)
|
|
var/list/resources = list()
|
|
recipe_data["sheets"] = null
|
|
recipe_data["can_make"] = FALSE
|
|
for(var/resource in R.resources)
|
|
var/resource_cost = round(R.resources[resource] * mat_efficiency)
|
|
var/material = SSmaterials.material_to_path(resource, FALSE)
|
|
resources += "[resource_cost] [SSmaterials.material_display_name(resource)]"
|
|
if(!material || isnull(stored_material[material]) || stored_material[material] < resource_cost)
|
|
recipe_data["can_make"] = TRUE
|
|
if(resource_cost > 0 && material && !isnull(stored_material[material]))
|
|
var/craftable = stored_material[material] / resource_cost
|
|
recipe_data["sheets"] = isnull(recipe_data["sheets"]) ? craftable : min(recipe_data["sheets"], craftable)
|
|
recipe_data["category"] = R.category
|
|
recipe_data["resources"] = english_list(resources)
|
|
recipe_data["build_time"] = (R.build_time / 10)
|
|
recipe_data["max_sheets"] = null
|
|
if(R.is_stack)
|
|
var/obj/item/stack/R_stack = R.path
|
|
recipe_data["max_sheets"] = initial(R_stack.max_amount)
|
|
data["recipes"] += list(recipe_data)
|
|
|
|
data["currently_printing"] = null
|
|
if(currently_printing)
|
|
data["currently_printing"] = REF("[currently_printing]")
|
|
data["queue"] = list()
|
|
for(var/datum/fabricator_build_order/AR in print_queue)
|
|
data["queue"] += list(
|
|
list(
|
|
"ref" = REF(AR),
|
|
"order" = AR.target_recipe.name,
|
|
"path" = AR.target_recipe.type,
|
|
"multiplier" = AR.multiplier,
|
|
"build_time" = AR.target_recipe.build_time,
|
|
"progress" = AR.target_recipe.build_time - AR.remaining_time,
|
|
"remaining_time" = AR.remaining_time
|
|
)
|
|
)
|
|
return data
|
|
|
|
/obj/structure/machinery/fabricator/attackby(obj/item/attacking_item, mob/user)
|
|
if(fab_status_flags & FAB_BUSY)
|
|
to_chat(user, SPAN_NOTICE("\The [src] is busy. Please wait for the completion of previous operation."))
|
|
return TRUE
|
|
|
|
if(default_deconstruction_screwdriver(user, attacking_item))
|
|
SStgui.update_uis(src)
|
|
return TRUE
|
|
if(default_deconstruction_crowbar(user, attacking_item))
|
|
return TRUE
|
|
|
|
if(default_part_replacement(user, attacking_item))
|
|
return TRUE
|
|
|
|
if(stat)
|
|
return TRUE
|
|
|
|
if(panel_open)
|
|
//Don't eat multitools or wirecutters used on an open lathe.
|
|
if(attacking_item.tool_behaviour == TOOL_MULTITOOL || attacking_item.tool_behaviour == TOOL_WIRECUTTER )
|
|
if(panel_open)
|
|
wires.interact(user)
|
|
else
|
|
to_chat(user, SPAN_WARNING("\The [src]'s wires aren't exposed."))
|
|
return TRUE
|
|
|
|
if(attacking_item.loc != user && !istype(attacking_item, /obj/item/stack))
|
|
return FALSE
|
|
|
|
if(is_robot_module(attacking_item))
|
|
return FALSE
|
|
|
|
load_lathe(attacking_item, user)
|
|
return TRUE
|
|
|
|
/obj/structure/machinery/fabricator/autolathe/proc/recycle_item_contents(obj/item/R, mob/user)
|
|
var/recycled = 0
|
|
var/recyclable = 0
|
|
var/rejected = 0
|
|
|
|
for(var/obj/item/item in R.contents.Copy())
|
|
if(!item.matter || !item.recyclable)
|
|
continue
|
|
recyclable++
|
|
if(load_lathe(item, user, FALSE))
|
|
recycled++
|
|
else
|
|
rejected++
|
|
|
|
if(recycled)
|
|
to_chat(user, SPAN_NOTICE("You recycle [recycled] item\s from \the [R] into \the [src]."))
|
|
else if(!recyclable)
|
|
to_chat(user, SPAN_WARNING("\The [R] contains no recyclable materials for \the [src]."))
|
|
else
|
|
to_chat(user, SPAN_WARNING("\The [src] could not accept any recyclable contents from \the [R]."))
|
|
|
|
if(rejected)
|
|
to_chat(user, SPAN_WARNING("Some contents could not be accepted and remain in \the [R]."))
|
|
|
|
/obj/structure/machinery/fabricator/attack_hand(mob/user)
|
|
user.set_machine(src)
|
|
ui_interact(user)
|
|
|
|
/obj/structure/machinery/fabricator/proc/is_functioning()
|
|
. = use_power != POWER_USE_OFF && !(fab_status_flags & FAB_DISABLED)
|
|
|
|
/obj/structure/machinery/fabricator/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
|
|
usr.set_machine(src)
|
|
add_fingerprint(usr)
|
|
|
|
playsound(src, SFX_KEYBOARD, 50)
|
|
|
|
if(action == "make")
|
|
START_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF)
|
|
var/multiplier = text2num(params["multiplier"])
|
|
var/singleton/fabricator_recipe/R = GET_SINGLETON(text2path(params["recipe"]))
|
|
if(!istype(R))
|
|
CRASH("Unknown recipe given! [R], param is [params["recipe"]].")
|
|
|
|
intent_message(MACHINE_SOUND)
|
|
|
|
try_queue_build(R, multiplier)
|
|
|
|
. = TRUE
|
|
|
|
if(action == "remove")
|
|
var/datum/fabricator_build_order/order = locate(params["ref"])
|
|
try_cancel_build(order)
|
|
. = TRUE
|
|
|
|
/obj/structure/machinery/fabricator/process(seconds_per_tick)
|
|
..()
|
|
if(use_power == POWER_USE_ACTIVE && (fab_status_flags & FAB_BUSY))
|
|
update_current_build(seconds_per_tick)
|
|
|
|
/obj/structure/machinery/fabricator/update_icon()
|
|
if(!does_flick)
|
|
return
|
|
ClearOverlays()
|
|
if(panel_open)
|
|
AddOverlays("[icon_state]_panel")
|
|
if(currently_printing)
|
|
AddOverlays(emissive_appearance(icon, "[icon_state]_lights_working"))
|
|
AddOverlays("[icon_state]_lights_working")
|
|
AddOverlays("[icon_state]_process")
|
|
else if(powered())
|
|
AddOverlays(emissive_appearance(icon, "[icon_state]_lights"))
|
|
AddOverlays("[icon_state]_lights")
|
|
|
|
/obj/structure/machinery/fabricator/proc/remove_mat_overlay(mat_overlay)
|
|
CutOverlays(mat_overlay)
|
|
update_icon()
|
|
|
|
/obj/structure/machinery/fabricator/RefreshParts()
|
|
..()
|
|
var/mb_rating = 0
|
|
var/man_rating = 0
|
|
var/las_rating = 0
|
|
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
|
|
mb_rating += MB.rating
|
|
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
|
man_rating += M.rating
|
|
for(var/obj/item/stock_parts/micro_laser/L in component_parts)
|
|
las_rating += L.rating
|
|
SSmaterials.normalize_material_amounts(base_storage_capacity)
|
|
storage_capacity = list()
|
|
for(var/mat in base_storage_capacity)
|
|
storage_capacity[mat] = mb_rating * base_storage_capacity[mat]
|
|
mat_efficiency = 1.1 - (las_rating * 0.1) // Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.8. Maximum rating of parts is 3
|
|
build_time_multiplier = initial(build_time_multiplier) * man_rating
|
|
|
|
/obj/structure/machinery/fabricator/dismantle()
|
|
normalize_material_storage()
|
|
for(var/mat in stored_material)
|
|
var/stack_type = SSmaterials.material_stack_type(mat)
|
|
if(!stack_type)
|
|
continue
|
|
var/obj/item/stack/material/S = new stack_type(get_turf(src))
|
|
if(stored_material[mat] > S.perunit)
|
|
S.amount = round(stored_material[mat] / S.perunit)
|
|
else
|
|
qdel(S)
|
|
..()
|
|
return TRUE
|