Ported the Microlathe from Bay, and began autolathe refactor: Take II (#21668)

Continued from #19839

> Part 1 of a refactor to try and make our various fabricators use the
same system and basic code. This adds the microlathe as a proof of
concept to the whole refactor, ported from Baystation. Currently not
mapped anywhere.

> This also ports over Nebula's autolathe working sound, however it is
adapted to fit our code. As such, I went to the original sound and
re-cut it, now including start and stop sounds.

Plan is overall to make it much easier to add new types of fabricators. 

### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:

| Path | Original Author | License |
| --- | --- | --- |
| icons/obj/machinery/fabricators/microlathe.dmi |
[BloodyMan](https://github.com/BloodyMan) (Baystation 12) | CC-BY-SA |
| sound/machines/fabricators/autolathe/ |
[pencilina](https://freesound.org/people/pencilina/) | CC-0 |

---------

Co-authored-by: Cody Brittain <cbrittain10@live.com>
This commit is contained in:
Cody Brittain
2026-01-14 19:29:32 +00:00
committed by GitHub
co-authored by Cody Brittain
parent 5e69ccbd6a
commit ccbfbdc50a
146 changed files with 1406 additions and 955 deletions
-453
View File
@@ -1,453 +0,0 @@
#define AUTOLATHE_BUSY 1
#define AUTOLATHE_STARTED 2
/obj/machinery/autolathe
name = "autolathe"
desc = "A large device loaded with various item schematics. It uses a combination of steel and glass to fabricate items."
icon = 'icons/obj/machinery/autolathe.dmi'
icon_state = "autolathe"
density = TRUE
anchored = TRUE
use_power = POWER_USE_IDLE
idle_power_usage = 10
active_power_usage = 2000
clicksound = /singleton/sound_category/keyboard_sound
clickvol = 30
var/atom/print_loc
var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MATERIAL_GLASS = 0, MATERIAL_ALUMINIUM = 0, MATERIAL_PLASTIC = 0, MATERIAL_LEAD = 0, MATERIAL_PHORON = 0)
var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MATERIAL_GLASS = 0, MATERIAL_ALUMINIUM = 0, MATERIAL_PLASTIC = 0, MATERIAL_LEAD = 0, MATERIAL_PHORON = 0)
var/show_category = "All"
var/hacked = FALSE
var/disabled = FALSE
var/shocked = FALSE
var/autolathe_flags = 0
var/datum/autolathe_queue_item/currently_printing
var/mat_efficiency = 1
var/last_process_time
var/build_time = 50
var/does_flick = TRUE
var/datum/wires/autolathe/wires
var/list/print_queue = list()
component_types = list(
/obj/item/circuitboard/autolathe,
/obj/item/stock_parts/matter_bin = 3,
/obj/item/stock_parts/manipulator,
/obj/item/stock_parts/console_screen
)
/obj/machinery/autolathe/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>[storage_capacity[DEFAULT_WALL_MATERIAL] / 2000]</b> sheets")
. += "- Upgraded <b>manipulators</b> will improve material use efficiency and increase fabrication speed."
. += SPAN_NOTICE(" - The current material cost reduction is <b>[round((1 - mat_efficiency) * 100)]%</b>")
. += SPAN_NOTICE(" - The current build speed increase is <b>[round((1 - mat_efficiency) * 100)]%</b>")
/obj/machinery/autolathe/Initialize()
..()
wires = new(src)
print_loc = src
update_icon()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/autolathe/LateInitialize()
. = ..()
populate_lathe_recipes()
/obj/machinery/autolathe/Destroy()
print_loc = null
QDEL_NULL(currently_printing)
QDEL_NULL(wires)
QDEL_LIST(print_queue)
return ..()
/obj/machinery/autolathe/proc/populate_lathe_recipes()
if(SSmaterials.autolathe_categories)
return
SSmaterials.autolathe_categories = list()
for(var/singleton/autolathe_recipe/recipe in GET_SINGLETON_SUBTYPE_LIST(/singleton/autolathe_recipe))
SSmaterials.autolathe_categories |= recipe.category
var/obj/item/I = new recipe.path
if(I.matter && !recipe.resources) //This can be overidden in the datums.
recipe.resources = list()
for(var/material in I.matter)
recipe.resources[material] = I.matter[material]*1.25 // More expensive to produce than they are to recycle.
qdel(I)
SSmaterials.autolathe_categories |= "All"
SSmaterials.autolathe_categories = sort_list(SSmaterials.autolathe_categories, GLOBAL_PROC_REF(cmp_text_asc))
/obj/machinery/autolathe/proc/can_print_item(var/singleton/autolathe_recipe/recipe)
var/ship_security_level = seclevel2num(get_security_level())
var/is_on_ship = is_station_level(z) // since ship security levels are global FOR NOW, we'll ignore the alert check for offship autolathes
if(!hacked)
if(recipe.hack_only)
return FALSE
else if(is_on_ship && ship_security_level < recipe.security_level)
return FALSE
return TRUE
/obj/machinery/autolathe/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/machinery/autolathe/ui_data(mob/user)
. = ..()
var/list/data = list()
data["disabled"] = disabled
data["material_efficiency"] = mat_efficiency
data["materials"] = list()
data["categories"] = SSmaterials.autolathe_categories
data["build_time"] = build_time
for(var/material in stored_material)
data["materials"] += list(list("material" = material, "stored" = stored_material[material], "max_capacity" = storage_capacity[material]))
data["recipes"] = list()
for(var/recipe in GET_SINGLETON_SUBTYPE_LIST(/singleton/autolathe_recipe))
var/singleton/autolathe_recipe/R = recipe
if(is_abstract(R))
continue
if(R.hack_only && !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()
for(var/resource in R.resources)
resources += "[R.resources[resource] * mat_efficiency] [resource]"
recipe_data["sheets"] = stored_material[resource]/round(R.resources[resource]*mat_efficiency)
recipe_data["can_make"] = !isnull(stored_material[resource]) && stored_material[resource] < round(R.resources[resource]*mat_efficiency)
recipe_data["category"] = R.category
recipe_data["resources"] = english_list(resources)
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/autolathe_queue_item/AR in print_queue)
data["queue"] += list(
list(
"ref" = "[REF(AR)]",
"order" = AR.recipe.name,
"path" = AR.recipe.type,
"multiplier" = AR.multiplier,
"build_time" = AR.build_time,
"progress" = AR.progress
)
)
return data
/obj/machinery/autolathe/attackby(obj/item/attacking_item, mob/user)
if((autolathe_flags & AUTOLATHE_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(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/machinery/autolathe/attack_hand(mob/user)
if(panel_open)
wires.interact(user)
user.set_machine(src)
ui_interact(user)
/obj/machinery/autolathe/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
usr.set_machine(src)
add_fingerprint(usr)
playsound(src, /singleton/sound_category/keyboard_sound, 50)
if(action == "make")
var/multiplier = text2num(params["multiplier"])
var/singleton/autolathe_recipe/R = GET_SINGLETON(text2path(params["recipe"]))
if(!istype(R))
CRASH("([usr.ckey]) tried to print an unknown recipe! [R], param is [params["recipe"]].")
if(!can_print_item(R))
CRASH("([usr.ckey]) tried to print an un-enabled recipe! [R], param is [params["recipe"]].")
intent_message(MACHINE_SOUND)
//Check if we still have the materials.
for(var/material in R.resources)
if(!isnull(stored_material[material]))
if(stored_material[material] < round(R.resources[material] * mat_efficiency) * multiplier)
return
var/datum/autolathe_queue_item/order = new()
order.recipe = R
order.multiplier = multiplier
order.build_time = build_time
//We know we have the materials, store them in the order.
for(var/material in R.resources)
if(!isnull(stored_material[material]))
var/material_usage = round(R.resources[material] * mat_efficiency) * multiplier
order.materials_used[material] = material_usage
stored_material[material] = max(0, stored_material[material] - material_usage)
print_queue += order
. = TRUE
if(action == "remove")
var/datum/autolathe_queue_item/order = locate(params["ref"])
if(!order)
return
if(currently_printing == order)
to_chat(usr, SPAN_WARNING("This item is already being printed!"))
return
for(var/material in order.materials_used)
if((stored_material[material] + order.materials_used[material]) > storage_capacity[material])
to_chat(usr, SPAN_WARNING("The autolathe display indicates that there isn't enough space to refund the materials!"))
return
stored_material[material] += order.materials_used[material]
print_queue -= order
qdel(order)
. = TRUE
/obj/machinery/autolathe/process()
if(length(print_queue))
if(!currently_printing)
last_process_time = world.time
currently_printing = print_queue[1]
autolathe_flags |= AUTOLATHE_BUSY
update_use_power(POWER_USE_ACTIVE)
else if(!currently_printing && (autolathe_flags & AUTOLATHE_BUSY))
autolathe_flags &= ~(AUTOLATHE_BUSY|AUTOLATHE_STARTED)
update_use_power(POWER_USE_IDLE)
if(currently_printing && use_power == POWER_USE_ACTIVE)
if(!(autolathe_flags & AUTOLATHE_STARTED))
start_processing_queue_item()
else if((autolathe_flags & AUTOLATHE_BUSY))
process_queue_item()
/// Used so that we don't try to AddOverlays every tick the autolathe processes.
/obj/machinery/autolathe/proc/start_processing_queue_item()
if(does_flick)
//Fancy autolathe animation.
AddOverlays(emissive_appearance(icon, "[icon_state]_lights_working"))
AddOverlays("[icon_state]_lights_working")
autolathe_flags |= AUTOLATHE_STARTED|AUTOLATHE_BUSY
/obj/machinery/autolathe/proc/process_queue_item()
if(!currently_printing)
return
var/time_difference = world.time - last_process_time
currently_printing.progress = min(currently_printing.progress + time_difference, currently_printing.build_time)
last_process_time = world.time
if(currently_printing.progress >= currently_printing.build_time)
complete_queue_item()
/obj/machinery/autolathe/proc/complete_queue_item()
//Create the desired item.
var/obj/item/I = new currently_printing.recipe.path(get_turf(print_loc))
I.Created()
if(currently_printing.multiplier > 1 && istype(I, /obj/item/stack))
var/obj/item/stack/S = I
S.amount = currently_printing.multiplier
print_queue -= currently_printing
QDEL_NULL(currently_printing)
CutOverlays(emissive_appearance(icon, "[icon_state]_lights_working"))
CutOverlays("[icon_state]_lights_working")
I.update_icon()
flick_overlay_view(mutable_appearance(icon, "[icon_state]_print"), 1 SECONDS)
update_use_power(POWER_USE_IDLE)
return TRUE
/obj/machinery/autolathe/update_icon()
CutOverlays("[icon_state]_panel")
CutOverlays(emissive_appearance(icon, "[icon_state]_lights"))
CutOverlays("[icon_state]_lights")
if(panel_open)
AddOverlays("[icon_state]_panel")
if(!(stat & (NOPOWER|BROKEN)))
AddOverlays(emissive_appearance(icon, "[icon_state]_lights"))
AddOverlays("[icon_state]_lights")
//Updates overall lathe storage size.
/obj/machinery/autolathe/RefreshParts()
..()
var/mb_rating = 0
var/man_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
storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000
storage_capacity[MATERIAL_GLASS] = mb_rating * 12500
storage_capacity[MATERIAL_ALUMINIUM] = mb_rating * 25000
storage_capacity[MATERIAL_PLASTIC] = mb_rating * 12500
storage_capacity[MATERIAL_LEAD] = mb_rating * 12500
storage_capacity[MATERIAL_PHORON] = mb_rating * 12500
build_time = 50 / man_rating
mat_efficiency = 1.1 - man_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
/obj/machinery/autolathe/dismantle()
for(var/mat in stored_material)
var/material/M = SSmaterials.get_material_by_name(mat)
if(!istype(M))
continue
var/obj/item/stack/material/S = new M.stack_type(get_turf(src))
if(stored_material[mat] > S.perunit)
S.amount = round(stored_material[mat] / S.perunit)
else
qdel(S)
..()
return TRUE
#define NO_SPACE "No Space"
#define FILL_COMPLETELY "Fill Completely"
#define FILL_INCOMPLETELY "Fill Incompletely"
/obj/machinery/autolathe/proc/load_lathe(obj/item/O, mob/user)
//Resources are being loaded.
var/obj/item/eating = O
if(!eating.matter || !eating.recyclable)
to_chat(user, SPAN_WARNING("\The [eating] cannot be recycled by \the [src]."))
return
var/list/fill_status = list() // Used to determine message in cases of multiple materials.
var/total_used = 0 // Amount of material used.
var/mass_per_sheet = 0 // Amount of material constituting one sheet.
var/is_stack = FALSE //Affects the fill message
for(var/material in eating.matter)
if(isnull(stored_material[material]) || isnull(storage_capacity[material]))
continue
if(stored_material[material] >= storage_capacity[material])
LAZYADD(fill_status[NO_SPACE], material)
continue
var/total_material = eating.matter[material]
//If it's a stack, we eat multiple sheets.
if(istype(eating, /obj/item/stack))
var/obj/item/stack/stack = eating
is_stack = TRUE
total_material *= stack.get_amount()
if(stored_material[material] + total_material > storage_capacity[material])
total_material = storage_capacity[material] - stored_material[material]
LAZYADD(fill_status[FILL_COMPLETELY], material)
else
LAZYADD(fill_status[FILL_INCOMPLETELY], material)
stored_material[material] += total_material
total_used += total_material
mass_per_sheet += eating.matter[material]
if(fill_status[NO_SPACE])
to_chat(user, SPAN_WARNING("\The [src] is full of [english_list(fill_status[NO_SPACE])]. Please remove some material in order to insert more."))
return
else if(fill_status[FILL_COMPLETELY])
to_chat(user, SPAN_NOTICE("You fill \the [src] to capacity with [english_list(fill_status[FILL_COMPLETELY])][is_stack ? "." : " from \the [eating]."]"))
else if(fill_status[FILL_INCOMPLETELY])
to_chat(user, SPAN_NOTICE("You fill \the [src] with [english_list(fill_status[FILL_INCOMPLETELY])][is_stack ? "." : " from \the [eating]."]"))
// Plays metal insertion animation.
if(istype(eating, /obj/item/stack/material))
var/obj/item/stack/material/stack = eating
var/mutable_appearance/M = mutable_appearance(icon, "material_insertion")
M.color = stack.material.icon_colour
//first play the insertion animation
flick_overlay_view(M, 1 SECONDS)
//now play the progress bar animation
flick_overlay_view(mutable_appearance(icon, "autolathe_progress"), 1 SECONDS)
if(istype(eating, /obj/item/stack))
var/obj/item/stack/stack = eating
var/amount_needed
if(total_used && mass_per_sheet)
amount_needed = total_used / mass_per_sheet
stack.use(min(stack.get_amount(), (round(amount_needed) == amount_needed)? amount_needed : round(amount_needed) + 1)) // Prevent maths imprecision from leading to infinite resources
else
user.remove_from_mob(O)
qdel(O)
/obj/machinery/autolathe/mounted
name = "\improper mounted autolathe"
density = FALSE
anchored = FALSE
idle_power_usage = FALSE
active_power_usage = FALSE
interact_offline = TRUE
does_flick = FALSE
/obj/machinery/autolathe/mounted/ui_state(mob/user)
return GLOB.heavy_vehicle_state
/// Queue items are needed so that the queue knows exactly what it's doing.
/datum/autolathe_queue_item
/// The recipe singleton. We need to know exactly what we're making.
var/singleton/autolathe_recipe/recipe
/// Multiplier, used to know how many sheets we are printing. Note that this is specifically for sheets.
var/multiplier = 1
/// The materials used for this order.
var/list/materials_used = list()
/// How much time it takes to build this order. 50 for an un-upgraded autolathe.
var/build_time = 0
/// Current progress on this queue item.
var/progress = 0
/datum/autolathe_queue_item/Destroy()
recipe = null
return ..()
#undef NO_SPACE
#undef FILL_COMPLETELY
#undef FILL_INCOMPLETELY
#undef AUTOLATHE_BUSY
#undef AUTOLATHE_STARTED
@@ -1,14 +0,0 @@
/singleton/autolathe_recipe
var/name = "object"
var/path
var/list/resources
var/hidden
var/category
var/power_use = 0
var/is_stack
/// If true, the autolathe needs to be hacked before it can print this design
var/hack_only
/// If set, the ship needs to be at this alert level before autolathes on it can print this design. ignored if hacked
var/security_level
@@ -1,165 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/ammunition)
name = "Abstract Ammunition"
category = "Ammunition"
/singleton/autolathe_recipe/ammunition/New()
..()
if(ispath(path, /obj/item/ammo_pile))
var/obj/item/ammo_pile/pile = path
var/ammo_type = initial(pile.ammo_type)
var/obj/item/ammo_casing/ammo = new ammo_type
var/list/ammo_matter = ammo.matter.Copy()
resources = ammo_matter
for(var/material in resources)
resources[material] = resources[material] * ammo.max_stack
qdel(ammo)
/singleton/autolathe_recipe/ammunition/syringegun_ammo
name = "syringe gun cartridge"
path = /obj/item/syringe_cartridge
/singleton/autolathe_recipe/ammunition/shotgun
name = "shells (blank, shotgun)"
path = /obj/item/ammo_pile/shotgun_blanks
/singleton/autolathe_recipe/ammunition/shotgun/beanbag
name = "shells (beanbag, shotgun)"
path = /obj/item/ammo_pile/shotgun_beanbag
/singleton/autolathe_recipe/ammunition/shotgun/flash
name = "shells (flash, shotgun)"
path = /obj/item/ammo_pile/shotgun_flash
/singleton/autolathe_recipe/ammunition/shotgun/stun
name = "shells (stun cartridge, shotgun)"
path = /obj/item/ammo_pile/shotgun_stunshell
/singleton/autolathe_recipe/ammunition/shotgun/slug
name = "shells (slug, shotgun)"
path = /obj/item/ammo_pile/slug
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/shotgun/pellet
name = "shells (buckshot, shotgun)"
path = /obj/item/ammo_pile/shotgun_pellet
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_revolver_1
name = "speed loader (.357)"
path = /obj/item/ammo_magazine/a357
hack_only = TRUE
/singleton/autolathe_recipe/ammunition/detective_revolver_lethal
name = "speed loader (.38)"
path = /obj/item/ammo_magazine/c38
hack_only = TRUE
/singleton/autolathe_recipe/ammunition/detective_revolver_rubber
name = "speed loader (.38, rubber)"
path = /obj/item/ammo_magazine/c38/rubber
hack_only = TRUE
/singleton/autolathe_recipe/ammunition/magazine_fourty_five
name = "magazine (.45, pistol)"
path = /obj/item/ammo_magazine/c45m
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_rubber
name = "magazine (.45, rubber, pistol)"
path = /obj/item/ammo_magazine/c45m/rubber
/singleton/autolathe_recipe/ammunition/magazine_flash
name = "magazine (.45, flash, pistol)"
path = /obj/item/ammo_magazine/c45m/flash
/singleton/autolathe_recipe/ammunition/magazine_fourty_five/extended
name = "magazine (.45, extended, pistol)"
path = /obj/item/ammo_magazine/c45m/stendo
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_fourty_five/extended/rubber
name = "magazine (.45, extended rubber, pistol)"
path = /obj/item/ammo_magazine/c45m/stendo/rubber
security_level = SEC_LEVEL_GREEN
/singleton/autolathe_recipe/ammunition/submachine_mag
name = "magazine (.45, submachine gun)"
path = /obj/item/ammo_magazine/submachinemag
hack_only = TRUE
/singleton/autolathe_recipe/ammunition/uzi_mag
name = "magazine (.45, machine pistol)"
path = /obj/item/ammo_magazine/c45uzi
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_xanu_pistol
name = "magazine (4.6mm)"
path = /obj/item/ammo_magazine/c46m
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_xanu_smg
name = "magazine (4.6mm, extended)"
path = /obj/item/ammo_magazine/c46m/extended
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_stetchkin
name = "magazine (9mm)"
path = /obj/item/ammo_magazine/mc9mm
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_stetchkin_flash
name = "magazine (9mm, flash)"
path = /obj/item/ammo_magazine/mc9mm/flash
/singleton/autolathe_recipe/ammunition/magazine_smg
name = "magazine (9mm, top mounted, machine pistol)"
path = /obj/item/ammo_magazine/mc9mmt
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_smg_rubber
name = "magazine (9mm rubber, top mounted, machine pistol)"
path = /obj/item/ammo_magazine/mc9mmt/rubber
/singleton/autolathe_recipe/ammunition/magazine_c20r
name = "magazine (10mm)"
path = /obj/item/ammo_magazine/a10mm
hack_only = TRUE
/singleton/autolathe_recipe/ammunition/magazine_carbine
name = "magazine (5.56mm, rifle)"
path = /obj/item/ammo_magazine/a556
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_carbinepolymer
name = "magazine (5.56mm polymer, rifle)"
path = /obj/item/ammo_magazine/a556/polymer
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_smallcarbine
name = "magazine (5.56mm, carbine)"
path = /obj/item/ammo_magazine/a556/carbine
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_smallcarbinepolymer
name = "magazine (5.56mm polymer, carbine)"
path = /obj/item/ammo_magazine/a556/carbine/polymer
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_xanu_rifle
name = "magazine (6.5mm, rifle)"
path = /obj/item/ammo_magazine/a65
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/ammunition/magazine_arifle
name = "magazine (7.62mm)"
path = /obj/item/ammo_magazine/c762
hack_only = TRUE
/singleton/autolathe_recipe/ammunition/clip_boltaction
name = "clip (7.62mm)"
path = /obj/item/ammo_magazine/boltaction
hack_only = TRUE
@@ -1,40 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/armaments)
name = "Abstract Armaments"
category = "Armaments"
/singleton/autolathe_recipe/armaments/grenade
name = "grenade casing"
path = /obj/item/grenade/chem_grenade
/singleton/autolathe_recipe/armaments/grenade/large
name = "large grenade casing"
path = /obj/item/grenade/chem_grenade/large
/singleton/autolathe_recipe/armaments/handcuffs
name = "handcuffs"
path = /obj/item/handcuffs
/singleton/autolathe_recipe/armaments/flamethrower
name = "flamethrower"
path = /obj/item/flamethrower/full
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/armaments/tacknife
name = "tactical knife"
path = /obj/item/material/knife/tacknife
security_level = SEC_LEVEL_RED
/singleton/autolathe_recipe/armaments/brassknuckles
name = "brass knuckles"
path = /obj/item/clothing/gloves/brassknuckles
hack_only = TRUE
/singleton/autolathe_recipe/armaments/electropack
name = "electropack"
path = /obj/item/device/radio/electropack
hack_only = TRUE
/singleton/autolathe_recipe/armaments/trap
name = "mechanical trap"
path = /obj/item/trap
hack_only = TRUE
@@ -1,53 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/components)
name = "Abstract Components"
category = "Devices and Components"
/singleton/autolathe_recipe/components/consolescreen
name = "console screen"
path = /obj/item/stock_parts/console_screen
/singleton/autolathe_recipe/components/igniter
name = "igniter"
path = /obj/item/device/assembly/igniter
/singleton/autolathe_recipe/components/signaler
name = "signaler"
path = /obj/item/device/assembly/signaler
/singleton/autolathe_recipe/components/sensor_infra
name = "infrared sensor"
path = /obj/item/device/assembly/infra
/singleton/autolathe_recipe/components/timer
name = "timer"
path = /obj/item/device/assembly/timer
/singleton/autolathe_recipe/components/sensor_prox
name = "proximity sensor"
path = /obj/item/device/assembly/prox_sensor
/singleton/autolathe_recipe/components/cable_coil
name = "cable coil"
path = /obj/item/stack/cable_coil
is_stack = TRUE
// Basic Stock Parts for Engineering
/singleton/autolathe_recipe/components/micromanip
name = "micro-manipulator"
path = /obj/item/stock_parts/manipulator
/singleton/autolathe_recipe/components/matterbin
name = "matter bin"
path = /obj/item/stock_parts/matter_bin
/singleton/autolathe_recipe/components/capacitor
name = "capacitor"
path = /obj/item/stock_parts/capacitor
/singleton/autolathe_recipe/components/scanningmod
name = "scanning module"
path = /obj/item/stock_parts/scanning_module
/singleton/autolathe_recipe/components/microlaser
name = "micro-laser"
path = /obj/item/stock_parts/micro_laser
@@ -1,67 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/dinnerware)
name = "Abstract Dinnerware"
category = "Dinnerware"
/singleton/autolathe_recipe/dinnerware/knife
name = "kitchen knife"
path = /obj/item/material/knife
/singleton/autolathe_recipe/dinnerware/drinking_glass
name = "drinking glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass
/singleton/autolathe_recipe/dinnerware/half_pint_glass
name = "half pint glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/square
/singleton/autolathe_recipe/dinnerware/rocks_glass
name = "rocks glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/rocks
/singleton/autolathe_recipe/dinnerware/sherry_glass
name = "sherry glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/shake
/singleton/autolathe_recipe/dinnerware/cocktail_glass
name = "cocktail glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/cocktail
/singleton/autolathe_recipe/dinnerware/shot_glass
name = "shot glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/shot
/singleton/autolathe_recipe/dinnerware/pint_glass
name = "pint glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/pint
/singleton/autolathe_recipe/dinnerware/mug_glass
name = "mug glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/mug
/singleton/autolathe_recipe/dinnerware/flute_glass
name = "flute glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/flute
/singleton/autolathe_recipe/dinnerware/cognac_glass
name = "cognac glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/cognac
/singleton/autolathe_recipe/dinnerware/goblet_glass
name = "goblet glass"
path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/goblet
/singleton/autolathe_recipe/dinnerware/jar
name = "jar"
path = /obj/item/glass_jar
/singleton/autolathe_recipe/dinnerware/bowl
name = "bowl"
path = /obj/item/reagent_containers/cooking_container/board/bowl
/singleton/autolathe_recipe/dinnerware/bottle
name = "bottle"
path = /obj/item/reagent_containers/food/drinks/bottle
/singleton/autolathe_recipe/dinnerware/ashtray_glass
name = "glass ashtray"
path = /obj/item/material/ashtray/glass
@@ -1,53 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/engineering)
name = "Abstract Engineering"
category = "Engineering"
/singleton/autolathe_recipe/engineering/airlockmodule
name = "airlock electronics"
path = /obj/item/airlock_electronics
/singleton/autolathe_recipe/engineering/airalarm
name = "air alarm electronics"
path = /obj/item/airalarm_electronics
/singleton/autolathe_recipe/engineering/firealarm
name = "fire alarm electronics"
path = /obj/item/firealarm_electronics
/singleton/autolathe_recipe/engineering/powermodule
name = "power control module"
path = /obj/item/module/power_control
/singleton/autolathe_recipe/engineering/stockparts_box
name = "stock parts box"
path = /obj/item/storage/bag/stockparts_box
/singleton/autolathe_recipe/engineering/camera_assembly
name = "camera assembly"
path = /obj/item/camera_assembly
/singleton/autolathe_recipe/engineering/suit_cooling
name = "portable suit cooling unit"
path = /obj/item/device/suit_cooling_unit/no_cell
/singleton/autolathe_recipe/engineering/emergency_cell
name = "miniature cell"
path = /obj/item/cell/device/emergency_light/empty
/singleton/autolathe_recipe/engineering/debugger
name = "debugger"
path = /obj/item/device/debugger
/singleton/autolathe_recipe/engineering/floor_light
name = "floor light"
path = /obj/machinery/floor_light
/singleton/autolathe_recipe/engineering/tile_circuit_blue
name = "circuit tile, blue"
path = /obj/item/stack/tile/circuit_blue
is_stack = TRUE
/singleton/autolathe_recipe/engineering/tile_circuit_green
name = "circuit tile, green"
path = /obj/item/stack/tile/circuit_green
is_stack = TRUE
@@ -1,51 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/general)
name = "Abstract General"
category = "General"
/singleton/autolathe_recipe/general/bucket
name = "bucket"
path = /obj/item/reagent_containers/glass/bucket
/singleton/autolathe_recipe/general/flashlight
name = "flashlight"
path = /obj/item/device/flashlight/empty
/singleton/autolathe_recipe/general/extinguisher
name = "extinguisher"
path = /obj/item/extinguisher
/singleton/autolathe_recipe/general/radio_headset
name = "radio headset"
path = /obj/item/device/radio/headset
/singleton/autolathe_recipe/general/radio_bounced
name = "shortwave radio"
path = /obj/item/device/radio/off
/singleton/autolathe_recipe/general/weldermask
name = "welding mask"
path = /obj/item/clothing/head/welding
/singleton/autolathe_recipe/general/taperecorder
name = "tape recorder"
path = /obj/item/device/taperecorder
/singleton/autolathe_recipe/general/tube
name = "light tube"
path = /obj/item/light/tube
/singleton/autolathe_recipe/general/bulb
name = "light bulb"
path = /obj/item/light/bulb
/singleton/autolathe_recipe/general/labeler
name = "hand labeler"
path = /obj/item/device/hand_labeler
/singleton/autolathe_recipe/general/destTagger
name = "destination tagger"
path = /obj/item/device/destTagger
/singleton/autolathe_recipe/general/cratescanner
name = "crate contents scanner"
path = /obj/item/device/cratescanner
@@ -1,29 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/materials)
name = "Abstract Materials"
category = "Materials"
is_stack = TRUE
/singleton/autolathe_recipe/materials/metal
name = "steel sheets"
path = /obj/item/stack/material/steel
/singleton/autolathe_recipe/materials/aluminium
name = "aluminium sheets"
path = /obj/item/stack/material/aluminium
/singleton/autolathe_recipe/materials/glass
name = "glass sheets"
path = /obj/item/stack/material/glass
/singleton/autolathe_recipe/materials/rglass
name = "reinforced glass sheets"
path = /obj/item/stack/material/glass/reinforced
/singleton/autolathe_recipe/materials/rods
name = "metal rods"
path = /obj/item/stack/rods
/singleton/autolathe_recipe/materials/barbed_wire
name = "barbed wire"
path = /obj/item/stack/barbed_wire
@@ -1,55 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/medical)
name = "Abstract Medical"
category = "Medical"
/singleton/autolathe_recipe/medical/scalpel
name = "scalpel"
path = /obj/item/surgery/scalpel
/singleton/autolathe_recipe/medical/circularsaw
name = "circular saw"
path = /obj/item/surgery/circular_saw
/singleton/autolathe_recipe/medical/surgicaldrill
name = "surgical drill"
path = /obj/item/surgery/surgicaldrill
/singleton/autolathe_recipe/medical/retractor
name = "retractor"
path = /obj/item/surgery/retractor
/singleton/autolathe_recipe/medical/cautery
name = "cautery"
path = /obj/item/surgery/cautery
/singleton/autolathe_recipe/medical/hemostat
name = "hemostat"
path = /obj/item/surgery/hemostat
/singleton/autolathe_recipe/medical/beaker
name = "glass beaker"
path = /obj/item/reagent_containers/glass/beaker
/singleton/autolathe_recipe/medical/beaker_large
name = "large glass beaker"
path = /obj/item/reagent_containers/glass/beaker/large
/singleton/autolathe_recipe/medical/vial
name = "glass vial"
path = /obj/item/reagent_containers/glass/beaker/vial
/singleton/autolathe_recipe/medical/autoinjector
name = "autoinjector"
path = /obj/item/reagent_containers/hypospray/autoinjector
/singleton/autolathe_recipe/medical/autoinhaler
name = "autoinhaler"
path = /obj/item/reagent_containers/inhaler
/singleton/autolathe_recipe/medical/syringe
name = "syringe"
path = /obj/item/reagent_containers/syringe
/singleton/autolathe_recipe/medical/syringe/large
name = "large syringe"
path = /obj/item/reagent_containers/syringe/large
@@ -1,47 +0,0 @@
ABSTRACT_TYPE(/singleton/autolathe_recipe/tools)
name = "Abstract Tools"
category = "Tools"
/singleton/autolathe_recipe/tools/crowbar
name = "crowbar"
path = /obj/item/crowbar
/singleton/autolathe_recipe/tools/multitool
name = "multitool"
path = /obj/item/device/multitool
/singleton/autolathe_recipe/tools/geiger
name = "geiger counter"
path = /obj/item/device/geiger
/singleton/autolathe_recipe/tools/t_scanner
name = "T-ray scanner"
path = /obj/item/device/t_scanner
/singleton/autolathe_recipe/tools/weldertool
name = "welding tool"
path = /obj/item/weldingtool
/singleton/autolathe_recipe/tools/welder_industrial
name = "industrial welding tool"
path = /obj/item/weldingtool/largetank
/singleton/autolathe_recipe/tools/screwdriver
name = "screwdriver"
path = /obj/item/screwdriver
/singleton/autolathe_recipe/tools/wirecutters
name = "wirecutters"
path = /obj/item/wirecutters
/singleton/autolathe_recipe/tools/wrench
name = "wrench"
path = /obj/item/wrench
/singleton/autolathe_recipe/tools/hatchet
name = "hatchet"
path = /obj/item/material/hatchet
/singleton/autolathe_recipe/tools/minihoe
name = "mini hoe"
path = /obj/item/material/minihoe
@@ -29,12 +29,24 @@
/obj/item/circuitboard/autolathe
name = T_BOARD("autolathe")
build_path = /obj/machinery/autolathe
build_path = /obj/machinery/fabricator/autolathe
board_type = BOARD_MACHINE
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2)
req_components = list(
"/obj/item/stock_parts/matter_bin" = 3,
"/obj/item/stock_parts/manipulator" = 1,
"/obj/item/stock_parts/micro_laser" = 1,
"/obj/item/stock_parts/console_screen" = 1)
/obj/item/circuitboard/microlathe
name = T_BOARD("microlathe")
build_path = /obj/machinery/fabricator/microlathe
board_type = BOARD_MACHINE
origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2)
req_components = list(
"/obj/item/stock_parts/matter_bin" = 3,
"/obj/item/stock_parts/manipulator" = 1,
"/obj/item/stock_parts/micro_laser" = 1,
"/obj/item/stock_parts/console_screen" = 1)
/obj/item/circuitboard/protolathe
@@ -24,6 +24,7 @@
var/list/bite_sizes = list(1,2,3,4,5)
use_material_name = FALSE
applies_material_colour = FALSE
default_material = MATERIAL_ALUMINIUM
/obj/item/material/kitchen/utensil/Initialize(newloc, material_key)
. = ..()
@@ -93,6 +94,12 @@
sharp = TRUE
surgerysound = 'sound/items/surgery/hemostat.ogg'
/obj/item/material/kitchen/utensil/fork/bamboo
icon_state = "plastic_fork"
default_material = MATERIAL_BAMBOO
use_material_name = TRUE
applies_material_colour = TRUE
/obj/item/material/kitchen/utensil/fork/plastic
icon_state = "plastic_fork"
item_state = "fork"
@@ -106,6 +113,12 @@
icon_state = "spork"
item_state = "fork"
/obj/item/material/kitchen/utensil/spork/bamboo
icon_state = "plastic_spork"
default_material = MATERIAL_BAMBOO
use_material_name = TRUE
applies_material_colour = TRUE
/obj/item/material/kitchen/utensil/spork/plastic
icon_state = "plastic_spork"
item_state = "fork"
@@ -126,6 +139,12 @@
use_material_name = TRUE
applies_material_colour = TRUE
/obj/item/material/kitchen/utensil/fork/chopsticks/plastic
icon_state = "plastic_chopsticks"
default_material = MATERIAL_PLASTIC
use_material_name = TRUE
applies_material_colour = TRUE
/obj/item/material/kitchen/utensil/spoon
name = "spoon"
desc = "It's a spoon. You can see your own upside-down face in it."
@@ -134,6 +153,12 @@
attack_verb = list("attacked", "poked")
force_divisor = 0.1 //2 when wielded with weight 20 (steel)
/obj/item/material/kitchen/utensil/spoon/bamboo
icon_state = "plastic_spoon"
default_material = MATERIAL_BAMBOO
use_material_name = TRUE
applies_material_colour = TRUE
/obj/item/material/kitchen/utensil/spoon/plastic
icon_state = "plastic_spoon"
item_state = "spoon"
@@ -172,6 +197,12 @@
return
return ..()
/obj/item/material/kitchen/utensil/knife/bamboo
icon_state = "plastic_knife"
default_material = MATERIAL_BAMBOO
use_material_name = TRUE
applies_material_colour = TRUE
/obj/item/material/kitchen/utensil/knife/plastic
icon_state = "plastic_knife"
item_state = "knife"