From ccbfbdc50ad8df8a6b3eb5f98b7690a0adbff05a Mon Sep 17 00:00:00 2001 From: Cody Brittain <1779662+Generalcamo@users.noreply.github.com> Date: Wed, 14 Jan 2026 14:29:32 -0500 Subject: [PATCH] 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 --- aurorastation.dme | 34 +- code/__DEFINES/fabricators.dm | 2 + code/__DEFINES/machinery.dm | 6 + .../subsystems/initialization/fabrication.dm | 85 ++++ .../datums/looping_sounds/machinery_sounds.dm | 46 ++ code/datums/wires/autolathe.dm | 60 --- code/datums/wires/fabricator.dm | 76 +++ code/game/machinery/autolathe/autolathe.dm | 453 ------------------ .../machinery/autolathe/autolathe_datums.dm | 14 - .../machinery/autolathe/designs/dinnerware.dm | 67 --- .../circuitboards/machinery/research.dm | 14 +- .../objects/items/weapons/material/kitchen.dm | 31 ++ code/modules/fabrication/_fabricator.dm | 287 +++++++++++ .../fabrication/_fabricator_build_order.dm | 19 + code/modules/fabrication/designs/_design.dm | 21 + .../designs/general/designs_ammo.dm} | 88 ++-- .../designs/general/designs_arms.dm} | 18 +- .../designs/general/designs_devices.dm} | 26 +- .../designs/general/designs_engineering.dm} | 26 +- .../designs/general/designs_general.dm} | 26 +- .../designs/general/designs_materials.dm} | 15 +- .../designs/general/designs_medical.dm} | 28 +- .../designs/general/designs_tools.dm} | 24 +- .../designs/micro/designs_cutlery.dm | 76 +++ .../designs/micro/designs_dinnerware.dm | 20 + .../designs/micro/designs_glasses.dm | 49 ++ code/modules/fabrication/fabricator_build.dm | 108 +++++ code/modules/fabrication/fabricator_intake.dm | 74 +++ .../fabricators/fabricator_autolathe.dm | 17 + .../fabricators/fabricator_hacked.dm | 5 + .../fabricators/fabricator_microlathe.dm | 42 ++ .../heavy_vehicle/equipment/utility.dm | 6 +- code/modules/item_worth/worths_list.dm | 2 +- .../GeneralCamo - Autolathe Refactor.yml | 63 +++ icons/obj/machinery/autolathe.dmi | Bin 1592 -> 0 bytes icons/obj/machinery/fabricators/autolathe.dmi | Bin 0 -> 1171 bytes .../obj/machinery/fabricators/microlathe.dmi | Bin 0 -> 992 bytes .../abandoned_diner/abandoned_diner.dmm | 2 +- .../away_site/big_derelict/bigderelict.dmm | 2 +- .../away_site/first_aurora/first_aurora.dmm | 4 +- .../away_site/hivebot_hub/hivebot_hub.dmm | 4 +- .../konyang/point_verdant/point_verdant.dmm | 25 +- .../overgrown_mining_station.dmm | 2 +- .../quarantined_outpost.dmm | 2 +- .../hegemony_waypoint_submaps.dmm | 2 +- .../solarian_prewar/sensor_relay.dmm | 2 +- maps/away/away_site/shady/shady.dmm | 2 +- .../away_site/tajara/scrapper/scrapper.dmm | 4 +- .../uueoaesa/omgolo/omgolo_tourist.dmm | 2 +- .../uueoaesa/reclamation/ihss_reclamation.dmm | 2 +- .../wrecked_nt_ship/wrecked_nt_ship.dmm | 2 +- ...nviro_testing_facility_submaps_layouts.dmm | 6 +- .../enviro_testing_facility_submaps_main.dmm | 4 +- .../biesel/tcaf_corvette/tcaf_corvette.dmm | 4 +- maps/away/ships/coc/coc_ranger/coc_ship.dmm | 2 +- maps/away/ships/coc/coc_scarab/coc_scarab.dmm | 2 +- .../ships/coc/coc_surveyor/coc_surveyor.dmm | 2 +- .../coc/gadpathur_patrol/gadpathur_patrol.dmm | 2 +- .../dominian_corvette/dominian_corvette.dmm | 7 +- .../ships/dpra/hailstorm/hailstorm_ship.dmm | 7 +- .../elyra/elyra_corvette/elyra_corvette.dmm | 2 +- .../freebooter_salvager.dmm | 2 +- .../freebooter_ship/freebooter_ship_.dmm | 2 +- maps/away/ships/golden_deep/golden_deep.dmm | 4 +- .../fishing_league_trawler.dmm | 2 +- maps/away/ships/heph/cyclops/cyclops.dmm | 2 +- .../heph/heph_security/heph_security.dmm | 2 +- maps/away/ships/himeo/himeo_patrol_ship.dmm | 4 +- maps/away/ships/iac/iac_rescue_ship.dmm | 2 +- maps/away/ships/idris/idris_cruiser.dmm | 2 +- .../ships/kataphracts/kataphract_ship.dmm | 2 +- .../ships/konyang/kasf_ship/kasf_ship.dmm | 2 +- .../konyang/konyang_wreck/konyang_wreck.dmm | 2 +- .../orion_express_ship/orion_express_ship.dmm | 2 +- .../ships/orion/orion_miner/orion_miner.dmm | 2 +- .../ships/pra/headmaster/headmaster_ship.dmm | 7 +- maps/away/ships/sadar_scout/sadar_scout.dmm | 2 +- .../ships/sol/sol_frigate/sol_frigate.dmm | 2 +- .../ships/sol/sol_merc/fsf_patrol_ship.dmm | 4 +- .../ships/sol/sol_pirate/sfa_patrol_ship.dmm | 4 +- maps/away/ships/sol/sol_splf/splf_raider.dmm | 2 +- maps/away/ships/sol/sol_ssrm/ssrm_ship.dmm | 4 +- .../tirakqi_smuggler/tirakqi_smuggler.dmm | 2 +- .../ships/tramp_freighter/tramp_freighter.dmm | 2 +- .../hiskyn/unathi_pirate_hiskyn.dmm | 2 +- .../izharshan/unathi_pirate_izharshan.dmm | 5 +- .../tarwa/unathi_pirate_tarwa.dmm | 2 +- maps/away/ships/xanu/xanu_frigate.dmm | 2 +- maps/dungeon_spawns/coc_ship_unique.dmm | 7 +- maps/dungeon_spawns/skrell_crash_unique.dmm | 2 +- maps/dungeon_spawns/sol_ship_unique.dmm | 2 +- maps/event/generic_dock/generic_dock-1.dmm | 7 +- maps/event/idris_cruise/idris_cruise-1.dmm | 7 +- .../helpers/event_shuttles/sccv_apollo_v1.dmm | 4 +- .../helpers/event_shuttles/sccv_apollo_v2.dmm | 4 +- .../helpers/event_shuttles/sccv_apollo_v3.dmm | 4 +- maps/helpers/event_shuttles/sccv_artemis.dmm | 4 +- maps/helpers/event_shuttles/sccv_packrat.dmm | 2 +- .../asteroid/coc_ship/coc_ship_unique.dmm | 7 +- .../skrell_ship/skrell_crash_unique.dmm | 2 +- .../asteroid/sol_ship/sol_ship_unique.dmm | 2 +- .../exoplanets/crashed_pod/crashed_pod.dmm | 2 +- .../konyang/abandoned/factory_arms.dmm | 8 +- .../exoplanets/konyang/abandoned/garage.dmm | 7 +- .../konyang/abandoned/landing_zone.dmm | 2 +- .../exoplanets/konyang/landing_zone.dmm | 2 +- .../konyang/ocean/naval_landing_zone.dmm | 2 +- .../exoplanets/konyang/pirate_outpost.dmm | 6 +- .../moghes/moghes_wasteland_ozeuoi.dmm | 2 +- .../exoplanets/ouerea/ouerea_autakh.dmm | 2 +- .../exoplanets/ouerea/ouerea_freewater.dmm | 2 +- .../uueoaesa/heph_mining_station.dmm | 2 +- .../exoplanets/uueoaesa/heph_survey_post.dmm | 2 +- .../uueoaesa/miners_guild_outpost.dmm | 2 +- .../exoplanets/uueoaesa/pid_kois_farm.dmm | 2 +- maps/runtime/runtime.dmm | 2 +- maps/sccv_horizon/sccv_horizon.dmm | 31 +- .../fabricators/autolathe/autolathe_end.ogg | Bin 0 -> 193268 bytes .../fabricators/autolathe/autolathe_mid01.ogg | Bin 0 -> 66531 bytes .../fabricators/autolathe/autolathe_mid02.ogg | Bin 0 -> 60962 bytes .../fabricators/autolathe/autolathe_mid03.ogg | Bin 0 -> 65171 bytes .../fabricators/autolathe/autolathe_mid04.ogg | Bin 0 -> 68795 bytes .../fabricators/autolathe/autolathe_mid05.ogg | Bin 0 -> 66819 bytes .../fabricators/autolathe/autolathe_mid06.ogg | Bin 0 -> 65802 bytes .../fabricators/autolathe/autolathe_mid07.ogg | Bin 0 -> 66402 bytes .../fabricators/autolathe/autolathe_mid08.ogg | Bin 0 -> 66990 bytes .../fabricators/autolathe/autolathe_mid09.ogg | Bin 0 -> 61434 bytes .../fabricators/autolathe/autolathe_mid10.ogg | Bin 0 -> 64781 bytes .../fabricators/autolathe/autolathe_mid11.ogg | Bin 0 -> 62150 bytes .../fabricators/autolathe/autolathe_mid12.ogg | Bin 0 -> 59696 bytes .../fabricators/autolathe/autolathe_mid13.ogg | Bin 0 -> 57849 bytes .../fabricators/autolathe/autolathe_mid14.ogg | Bin 0 -> 62684 bytes .../fabricators/autolathe/autolathe_mid15.ogg | Bin 0 -> 67605 bytes .../fabricators/autolathe/autolathe_mid16.ogg | Bin 0 -> 67946 bytes .../fabricators/autolathe/autolathe_mid17.ogg | Bin 0 -> 67132 bytes .../fabricators/autolathe/autolathe_mid18.ogg | Bin 0 -> 69766 bytes .../fabricators/autolathe/autolathe_mid19.ogg | Bin 0 -> 62722 bytes .../fabricators/autolathe/autolathe_mid20.ogg | Bin 0 -> 65592 bytes .../fabricators/autolathe/autolathe_mid21.ogg | Bin 0 -> 66001 bytes .../fabricators/autolathe/autolathe_mid22.ogg | Bin 0 -> 60669 bytes .../fabricators/autolathe/autolathe_start.ogg | Bin 0 -> 162725 bytes tgui/packages/tgui/assets/bg-hammertail.svg | 18 + tgui/packages/tgui/index.tsx | 1 + tgui/packages/tgui/interfaces/Autolathe.tsx | 40 +- .../tgui/styles/themes/hammertail.scss | 67 +++ .../tgui/styles/themes/hephaestus.scss | 10 + 146 files changed, 1406 insertions(+), 955 deletions(-) create mode 100644 code/__DEFINES/fabricators.dm create mode 100644 code/controllers/subsystems/initialization/fabrication.dm delete mode 100644 code/datums/wires/autolathe.dm create mode 100644 code/datums/wires/fabricator.dm delete mode 100644 code/game/machinery/autolathe/autolathe.dm delete mode 100644 code/game/machinery/autolathe/autolathe_datums.dm delete mode 100644 code/game/machinery/autolathe/designs/dinnerware.dm create mode 100644 code/modules/fabrication/_fabricator.dm create mode 100644 code/modules/fabrication/_fabricator_build_order.dm create mode 100644 code/modules/fabrication/designs/_design.dm rename code/{game/machinery/autolathe/designs/ammunition.dm => modules/fabrication/designs/general/designs_ammo.dm} (55%) rename code/{game/machinery/autolathe/designs/armaments.dm => modules/fabrication/designs/general/designs_arms.dm} (60%) rename code/{game/machinery/autolathe/designs/components.dm => modules/fabrication/designs/general/designs_devices.dm} (57%) rename code/{game/machinery/autolathe/designs/engineering.dm => modules/fabrication/designs/general/designs_engineering.dm} (56%) rename code/{game/machinery/autolathe/designs/general.dm => modules/fabrication/designs/general/designs_general.dm} (56%) rename code/{game/machinery/autolathe/designs/materials.dm => modules/fabrication/designs/general/designs_materials.dm} (58%) rename code/{game/machinery/autolathe/designs/medical.dm => modules/fabrication/designs/general/designs_medical.dm} (58%) rename code/{game/machinery/autolathe/designs/tools.dm => modules/fabrication/designs/general/designs_tools.dm} (54%) create mode 100644 code/modules/fabrication/designs/micro/designs_cutlery.dm create mode 100644 code/modules/fabrication/designs/micro/designs_dinnerware.dm create mode 100644 code/modules/fabrication/designs/micro/designs_glasses.dm create mode 100644 code/modules/fabrication/fabricator_build.dm create mode 100644 code/modules/fabrication/fabricator_intake.dm create mode 100644 code/modules/fabrication/fabricators/fabricator_autolathe.dm create mode 100644 code/modules/fabrication/fabricators/fabricator_hacked.dm create mode 100644 code/modules/fabrication/fabricators/fabricator_microlathe.dm create mode 100644 html/changelogs/GeneralCamo - Autolathe Refactor.yml delete mode 100644 icons/obj/machinery/autolathe.dmi create mode 100644 icons/obj/machinery/fabricators/autolathe.dmi create mode 100644 icons/obj/machinery/fabricators/microlathe.dmi create mode 100644 sound/machines/fabricators/autolathe/autolathe_end.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid01.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid02.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid03.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid04.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid05.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid06.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid07.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid08.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid09.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid10.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid11.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid12.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid13.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid14.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid15.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid16.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid17.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid18.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid19.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid20.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid21.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_mid22.ogg create mode 100644 sound/machines/fabricators/autolathe/autolathe_start.ogg create mode 100644 tgui/packages/tgui/assets/bg-hammertail.svg create mode 100644 tgui/packages/tgui/styles/themes/hammertail.scss diff --git a/aurorastation.dme b/aurorastation.dme index 757922b5823..a8a32e327eb 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -60,6 +60,7 @@ #include "code\__DEFINES\emitter.dm" #include "code\__DEFINES\empulse.dm" #include "code\__DEFINES\evacuation.dm" +#include "code\__DEFINES\fabricators.dm" #include "code\__DEFINES\feedback.dm" #include "code\__DEFINES\flags.dm" #include "code\__DEFINES\fonts.dm" @@ -411,6 +412,7 @@ #include "code\controllers\subsystems\initialization\atlas.dm" #include "code\controllers\subsystems\initialization\atoms.dm" #include "code\controllers\subsystems\initialization\codex.dm" +#include "code\controllers\subsystems\initialization\fabrication.dm" #include "code\controllers\subsystems\initialization\holomap.dm" #include "code\controllers\subsystems\initialization\map_finalization.dm" #include "code\controllers\subsystems\initialization\misc_early.dm" @@ -627,10 +629,10 @@ #include "code\datums\wires\airlock.dm" #include "code\datums\wires\alarm.dm" #include "code\datums\wires\apc.dm" -#include "code\datums\wires\autolathe.dm" #include "code\datums\wires\camera.dm" #include "code\datums\wires\disposals.dm" #include "code\datums\wires\explosive.dm" +#include "code\datums\wires\fabricator.dm" #include "code\datums\wires\iff.dm" #include "code\datums\wires\ipc_tag_scanner.dm" #include "code\datums\wires\landmine.dm" @@ -1012,17 +1014,6 @@ #include "code\game\machinery\atmoalter\portable_atmospherics.dm" #include "code\game\machinery\atmoalter\pump.dm" #include "code\game\machinery\atmoalter\scrubber.dm" -#include "code\game\machinery\autolathe\autolathe.dm" -#include "code\game\machinery\autolathe\autolathe_datums.dm" -#include "code\game\machinery\autolathe\designs\ammunition.dm" -#include "code\game\machinery\autolathe\designs\armaments.dm" -#include "code\game\machinery\autolathe\designs\components.dm" -#include "code\game\machinery\autolathe\designs\dinnerware.dm" -#include "code\game\machinery\autolathe\designs\engineering.dm" -#include "code\game\machinery\autolathe\designs\general.dm" -#include "code\game\machinery\autolathe\designs\materials.dm" -#include "code\game\machinery\autolathe\designs\medical.dm" -#include "code\game\machinery\autolathe\designs\tools.dm" #include "code\game\machinery\bots\bots.dm" #include "code\game\machinery\camera\camera.dm" #include "code\game\machinery\camera\camera_assembly.dm" @@ -2304,6 +2295,25 @@ #include "code\modules\events\visitor.dm" #include "code\modules\events\wallrot.dm" #include "code\modules\ext_scripts\python.dm" +#include "code\modules\fabrication\_fabricator.dm" +#include "code\modules\fabrication\_fabricator_build_order.dm" +#include "code\modules\fabrication\fabricator_build.dm" +#include "code\modules\fabrication\fabricator_intake.dm" +#include "code\modules\fabrication\designs\_design.dm" +#include "code\modules\fabrication\designs\general\designs_ammo.dm" +#include "code\modules\fabrication\designs\general\designs_arms.dm" +#include "code\modules\fabrication\designs\general\designs_devices.dm" +#include "code\modules\fabrication\designs\general\designs_engineering.dm" +#include "code\modules\fabrication\designs\general\designs_general.dm" +#include "code\modules\fabrication\designs\general\designs_materials.dm" +#include "code\modules\fabrication\designs\general\designs_medical.dm" +#include "code\modules\fabrication\designs\general\designs_tools.dm" +#include "code\modules\fabrication\designs\micro\designs_cutlery.dm" +#include "code\modules\fabrication\designs\micro\designs_dinnerware.dm" +#include "code\modules\fabrication\designs\micro\designs_glasses.dm" +#include "code\modules\fabrication\fabricators\fabricator_autolathe.dm" +#include "code\modules\fabrication\fabricators\fabricator_hacked.dm" +#include "code\modules\fabrication\fabricators\fabricator_microlathe.dm" #include "code\modules\flufftext\Dreaming.dm" #include "code\modules\flufftext\TextFilters.dm" #include "code\modules\games\cardemon.dm" diff --git a/code/__DEFINES/fabricators.dm b/code/__DEFINES/fabricators.dm new file mode 100644 index 00000000000..8f36f3f58ef --- /dev/null +++ b/code/__DEFINES/fabricators.dm @@ -0,0 +1,2 @@ +#define FABRICATOR_CLASS_GENERAL "general" +#define FABRICATOR_CLASS_MICRO "microlathe" diff --git a/code/__DEFINES/machinery.dm b/code/__DEFINES/machinery.dm index dae9b61f55c..d02bf710481 100644 --- a/code/__DEFINES/machinery.dm +++ b/code/__DEFINES/machinery.dm @@ -32,6 +32,12 @@ #define MAINT 0x8 // Under maintenance. #define EMPED 0x10 // Temporary broken by EMP pulse. +#define FABRICATOR_EXTRA_COST_FACTOR 1.25 +#define FAB_HACKED BITFLAG(1) +#define FAB_DISABLED BITFLAG(2) +#define FAB_SHOCKED BITFLAG(3) +#define FAB_BUSY BITFLAG(4) + #define INOPERABLE(machine) (machine.stat & (BROKEN|NOPOWER|MAINT|EMPED)) #define OPERABLE(machine) !INOPERABLE(machine) diff --git a/code/controllers/subsystems/initialization/fabrication.dm b/code/controllers/subsystems/initialization/fabrication.dm new file mode 100644 index 00000000000..5802778f684 --- /dev/null +++ b/code/controllers/subsystems/initialization/fabrication.dm @@ -0,0 +1,85 @@ +SUBSYSTEM_DEF(fabrication) + name = "Fabrication" + flags = SS_NO_FIRE + init_order = INIT_ORDER_MISC + + /** + * List of lists(Strings => Paths - Subtypes of `/singsingleton/fabricator_recipe`). Global list of fabricator recipes. Set during `Initialize()`. + * + * Example formatting: + * ```dm + * list( + * "general" = list( + * /singleton/fabricator_recipe/A, + * /singleton/fabricator_recipe/B + * ), + * "microlathe" = list( + * /singleton/fabricator_recipe/C, + * /singleton/fabricator_recipe/D + * ) + * ) + * ``` + */ + var/list/recipes = list() + + /** + * List of lists (Strings => Strings). Global list of recipe categories. These are pulled from the recipes provided in `recipes`. Set during `Initialize()`. + * + * Example formatting: + * ```dm + * list( + * "general" = list( + * "Arms and Ammunition", + * "Devices and Components" + * ), + * "microlathe" = list( + * "Cutlery", + * "Drinking Glasses" + * ) + * ) + * ``` + */ + var/list/categories = list() + +/datum/controller/subsystem/fabrication/Initialize() + for(var/singleton/fabricator_recipe/recipe as anything in GET_SINGLETON_SUBTYPE_LIST(/singleton/fabricator_recipe)) + if(is_abstract(recipe)) + continue + if(!recipe.name) + continue + for(var/type in recipe.fabricator_types) + if(!recipes[type]) + recipes[type] = list() + recipes[type] += recipe + if (!categories[type]) + categories[type] = list() + categories[type] |= 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] * FABRICATOR_EXTRA_COST_FACTOR + qdel(I) + return SS_INIT_SUCCESS + +/** + * Retrieves a list of categories for the given root type. + * + * **Parameters**: + * - `type` - The root type to fetch from the `categories` list. + * + * Returns list of strings. The categories associated with the given root type. + */ +/datum/controller/subsystem/fabrication/proc/get_categories(type) + return categories[type] + +/** + * Retrieves a list of recipes for the given root type. + * + * **Parameters**: + * - `type` - The root type to fetch from the `recipes` list. + * + * Returns list of paths (`/singleton/fabricator_recipe`). The recipes associated with the given root type. + */ +/datum/controller/subsystem/fabrication/proc/get_recipes(type) + return recipes[type] diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index aef907d9d42..2f46c4d2b55 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -114,6 +114,51 @@ mid_length = 5 SECONDS volume = 75 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// FABRICATORS AND SUBTYPES +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/fabricator + start_sound = 'sound/machines/fabricators/autolathe/autolathe_start.ogg' + start_length = 2.67 SECONDS + mid_sounds = list( + 'sound/machines/fabricators/autolathe/autolathe_mid01.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid02.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid03.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid04.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid05.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid06.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid07.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid08.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid09.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid10.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid11.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid12.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid13.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid14.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid15.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid16.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid17.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid18.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid19.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid20.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid21.ogg' = 1, + 'sound/machines/fabricators/autolathe/autolathe_mid22.ogg' = 1, + ) + mid_length = 1 SECOND + end_sound = 'sound/machines/fabricators/autolathe/autolathe_end.ogg' + each_once = TRUE + in_order = TRUE + volume = 30 + extra_range = MEDIUM_RANGE_SOUND_EXTRARANGE + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/datum/looping_sound/fabricator/minilathe + volume = 20 + extra_range = SHORT_RANGE_SOUND_EXTRARANGE + ignore_walls = FALSE + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /datum/looping_sound/synth_fab @@ -124,3 +169,4 @@ mid_length = 3 SECONDS end_sound = 'sound/machines/synthfab/synthfab_end.ogg' volume = 75 + diff --git a/code/datums/wires/autolathe.dm b/code/datums/wires/autolathe.dm deleted file mode 100644 index d549767e571..00000000000 --- a/code/datums/wires/autolathe.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/wires/autolathe - proper_name = "Autolathe" - holder_type = /obj/machinery/autolathe - -/datum/wires/autolathe/New(atom/holder) - wires = list( - WIRE_HACK, WIRE_DISABLE, - WIRE_SHOCK - ) - add_duds(2) - ..() - -/datum/wires/autolathe/get_status() - var/obj/machinery/autolathe/A = holder - . = ..() - . += "\The [A] [A.disabled ? "is dead quiet" : "has a soft electric whirr"]." - . += "\The [A] [A.shocked ? "is making sparking noises" : "is cycling normally"]." - . += "\The [A] [A.hacked ? "rarely" : "occasionally"] makes a beep boop noise." - -/datum/wires/autolathe/interactable(mob/user) - if(!..()) - return FALSE - var/obj/machinery/autolathe/A = holder - if(A.panel_open) - return TRUE - return FALSE - -/datum/wires/autolathe/on_cut(wire, mend, source) - var/obj/machinery/autolathe/A = holder - switch(wire) - if(WIRE_HACK) - A.hacked = !mend - if(WIRE_SHOCK) - A.shocked = !mend - if(WIRE_DISABLE) - A.disabled = !mend - -/datum/wires/autolathe/on_pulse(wire) - if(is_cut(wire)) - return - var/obj/machinery/autolathe/A = holder - switch(wire) - if(WIRE_HACK) - A.hacked = !A.hacked - spawn(50) - if(A && !is_cut(wire)) - A.hacked = 0 - interact(usr) - if(WIRE_SHOCK) - A.shocked = !A.shocked - spawn(50) - if(A && !is_cut(wire)) - A.shocked = 0 - interact(usr) - if(WIRE_DISABLE) - A.disabled = !A.disabled - spawn(50) - if(A && !is_cut(wire)) - A.disabled = 0 - interact(usr) diff --git a/code/datums/wires/fabricator.dm b/code/datums/wires/fabricator.dm new file mode 100644 index 00000000000..de75673632d --- /dev/null +++ b/code/datums/wires/fabricator.dm @@ -0,0 +1,76 @@ +/datum/wires/fabricator + proper_name = "Fabricator" + holder_type = /obj/machinery/fabricator + +/datum/wires/fabricator/New(atom/holder) + wires = list( + WIRE_HACK, WIRE_DISABLE, + WIRE_SHOCK + ) + add_duds(2) + ..() + +/datum/wires/fabricator/get_status() + var/obj/machinery/fabricator/A = holder + . = ..() + . += "\The [A] [(A.fab_status_flags & FAB_DISABLED) ? "is dead quiet" : "has a soft electric whirr"]." + . += "\The [A] [(A.fab_status_flags & FAB_SHOCKED) ? "is making sparking noises" : "is cycling normally"]." + . += "\The [A] [(A.fab_status_flags & FAB_HACKED) ? "rarely" : "occasionally"] makes a beep boop noise." + +/datum/wires/fabricator/interactable(mob/user) + if(!..()) + return FALSE + var/obj/machinery/fabricator/A = holder + if(A.panel_open) + return TRUE + return FALSE + +/datum/wires/fabricator/on_cut(wire, mend, source) + var/obj/machinery/fabricator/A = holder + switch(wire) + if(WIRE_HACK) + if(mend) + A.fab_status_flags &= ~FAB_HACKED + else + A.fab_status_flags |= FAB_HACKED + if(WIRE_SHOCK) + if(mend) + A.fab_status_flags &= ~FAB_SHOCKED + else + A.fab_status_flags |= FAB_SHOCKED + if(WIRE_DISABLE) + if(mend) + A.fab_status_flags &= ~FAB_DISABLED + else + A.fab_status_flags |= FAB_DISABLED + +/datum/wires/fabricator/proc/reset_flag(wire, user, flag) + var/obj/machinery/fabricator/A = holder + if(A && !is_cut(wire) && flag) + A.fab_status_flags &= ~flag + interact(user) + +/datum/wires/fabricator/on_pulse(wire, user) + if(is_cut(wire)) + return + var/obj/machinery/fabricator/A = holder + switch(wire) + if(WIRE_HACK) + if(A.fab_status_flags & FAB_HACKED) + A.fab_status_flags &= ~FAB_HACKED + else + A.fab_status_flags |= FAB_HACKED + addtimer(CALLBACK(src, PROC_REF(reset_flag), wire, user, FAB_HACKED)) + if(WIRE_SHOCK) + if(A.fab_status_flags & FAB_SHOCKED) + A.fab_status_flags &= ~FAB_SHOCKED + else + A.fab_status_flags |= FAB_SHOCKED + addtimer(CALLBACK(src, PROC_REF(reset_flag), wire, user, FAB_SHOCKED)) + if(WIRE_DISABLE) + if(A.fab_status_flags & FAB_DISABLED) + A.fab_status_flags &= ~FAB_DISABLED + else + A.fab_status_flags |= FAB_DISABLED + addtimer(CALLBACK(src, PROC_REF(reset_flag), wire, user, FAB_DISABLED)) + diff --git a/code/game/machinery/autolathe/autolathe.dm b/code/game/machinery/autolathe/autolathe.dm deleted file mode 100644 index 478943b05f1..00000000000 --- a/code/game/machinery/autolathe/autolathe.dm +++ /dev/null @@ -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 matter bins will increase material storage capacity." - . += SPAN_NOTICE(" - The current storage limit per material type is [storage_capacity[DEFAULT_WALL_MATERIAL] / 2000] sheets") - . += "- Upgraded manipulators will improve material use efficiency and increase fabrication speed." - . += SPAN_NOTICE(" - The current material cost reduction is [round((1 - mat_efficiency) * 100)]%") - . += SPAN_NOTICE(" - The current build speed increase is [round((1 - mat_efficiency) * 100)]%") - -/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 diff --git a/code/game/machinery/autolathe/autolathe_datums.dm b/code/game/machinery/autolathe/autolathe_datums.dm deleted file mode 100644 index 5b35393e00c..00000000000 --- a/code/game/machinery/autolathe/autolathe_datums.dm +++ /dev/null @@ -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 diff --git a/code/game/machinery/autolathe/designs/dinnerware.dm b/code/game/machinery/autolathe/designs/dinnerware.dm deleted file mode 100644 index 021242acb2e..00000000000 --- a/code/game/machinery/autolathe/designs/dinnerware.dm +++ /dev/null @@ -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 diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/weapons/circuitboards/machinery/research.dm index 8611f82d897..614c81482d0 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/research.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/research.dm @@ -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 diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index 63dae3ac5b9..cf336d20fe8 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -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" diff --git a/code/modules/fabrication/_fabricator.dm b/code/modules/fabrication/_fabricator.dm new file mode 100644 index 00000000000..fb4649b23be --- /dev/null +++ b/code/modules/fabrication/_fabricator.dm @@ -0,0 +1,287 @@ +ABSTRACT_TYPE(/obj/machinery/fabricator) + 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 + 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( + DEFAULT_WALL_MATERIAL = 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/machinery/fabricator/upgrade_hints(mob/user, distance, is_adjacent) + . += ..() + . += "- Upgraded matter bins will increase material storage capacity." + . += SPAN_NOTICE(" - The current storage limit per material type is [storage_capacity[DEFAULT_WALL_MATERIAL] / 2000] sheets") + . += "- Upgraded micro lasers will improve material use efficiency." + . += SPAN_NOTICE(" - The current material cost reduction is [round((1 - mat_efficiency) * 100)]%") + . += "- Upgraded manipulators will increase the fabrication speed." + . += SPAN_NOTICE(" - The current build speed increase is [round(build_time_multiplier * 100)]%") + +/obj/machinery/fabricator/Initialize(mapload) + wires = new(src) + print_loc = src + 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, /material)) + var/material/mat_instance = mat + mat_instance = SSmaterials.get_material_by_name(initial(mat_instance.name)) + 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/machinery/fabricator/Destroy() + print_loc = null + QDEL_NULL(currently_printing) + QDEL_NULL(wires) + + QDEL_LIST(print_queue) + QDEL_NULL(fabricator_looping_sound) + + return ..() + +/obj/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/machinery/fabricator/ui_data(mob/user) + . = ..() + 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" = 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() + 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["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/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.ismultitool() || attacking_item.iswirecutter()) + 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/machinery/fabricator/attack_hand(mob/user) + user.set_machine(src) + ui_interact(user) + +/// +/obj/machinery/fabricator/proc/is_functioning() + . = use_power != POWER_USE_OFF && !(fab_status_flags & FAB_DISABLED) + +/obj/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, /singleton/sound_category/keyboard_sound, 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/machinery/fabricator/process(seconds_per_tick) + ..() + if(use_power == POWER_USE_ACTIVE && (fab_status_flags & FAB_BUSY)) + update_current_build(seconds_per_tick) + +/obj/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/machinery/fabricator/proc/remove_mat_overlay(mat_overlay) + CutOverlays(mat_overlay) + update_icon() + +/obj/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 + 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/machinery/fabricator/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 diff --git a/code/modules/fabrication/_fabricator_build_order.dm b/code/modules/fabrication/_fabricator_build_order.dm new file mode 100644 index 00000000000..4436d1c3845 --- /dev/null +++ b/code/modules/fabrication/_fabricator_build_order.dm @@ -0,0 +1,19 @@ +/// Queue items are needed so that the queue knows exactly what it's doing. +/datum/fabricator_build_order + /// The recipe singleton. We need to know exactly what we're making. + var/singleton/fabricator_recipe/target_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/earmarked_materials = list() + /// Remaining time for this order. + var/remaining_time = 0 + +/datum/fabricator_build_order/New(singleton/fabricator_recipe/_target_recipe, _multiplier = 1) + ..() + target_recipe = _target_recipe + multiplier = _multiplier + +/datum/fabricator_build_order/Destroy() + target_recipe = null + . = ..() diff --git a/code/modules/fabrication/designs/_design.dm b/code/modules/fabrication/designs/_design.dm new file mode 100644 index 00000000000..0e054bdecef --- /dev/null +++ b/code/modules/fabrication/designs/_design.dm @@ -0,0 +1,21 @@ +/singleton/fabricator_recipe + /// Name to show in the fabricator for this recipe + var/name = "object" + /// Path of the object to print + var/path + /// If true, the fabricator 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 fabricators on it can print this design. Ignored if hacked + var/security_level + /// What category will the recipe appear in? + var/category + /// What resources the recipe needs. Defaults to the amount of materials inside the object, multiplied by 1.25 + var/list/resources + /// Whether to treat the object as a stack or not. Will show multipliers for building + var/is_stack + /// What types of fabricators will this recipe appear in? + var/list/fabricator_types = list( + FABRICATOR_CLASS_GENERAL + ) + /// Build time for the recipe. Defaults to 5 SECONDS + var/build_time = 5 SECONDS diff --git a/code/game/machinery/autolathe/designs/ammunition.dm b/code/modules/fabrication/designs/general/designs_ammo.dm similarity index 55% rename from code/game/machinery/autolathe/designs/ammunition.dm rename to code/modules/fabrication/designs/general/designs_ammo.dm index 2c4b487639f..1ed9713cd49 100644 --- a/code/game/machinery/autolathe/designs/ammunition.dm +++ b/code/modules/fabrication/designs/general/designs_ammo.dm @@ -1,8 +1,8 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/ammunition) +ABSTRACT_TYPE(/singleton/fabricator_recipe/ammunition) name = "Abstract Ammunition" category = "Ammunition" -/singleton/autolathe_recipe/ammunition/New() +/singleton/fabricator_recipe/ammunition/New() ..() if(ispath(path, /obj/item/ammo_pile)) @@ -18,148 +18,128 @@ ABSTRACT_TYPE(/singleton/autolathe_recipe/ammunition) qdel(ammo) -/singleton/autolathe_recipe/ammunition/syringegun_ammo +/singleton/fabricator_recipe/ammunition/syringegun_ammo name = "syringe gun cartridge" path = /obj/item/syringe_cartridge -/singleton/autolathe_recipe/ammunition/shotgun +/singleton/fabricator_recipe/ammunition/shotgun name = "shells (blank, shotgun)" path = /obj/item/ammo_pile/shotgun_blanks -/singleton/autolathe_recipe/ammunition/shotgun/beanbag +/singleton/fabricator_recipe/ammunition/shotgun/beanbag name = "shells (beanbag, shotgun)" path = /obj/item/ammo_pile/shotgun_beanbag -/singleton/autolathe_recipe/ammunition/shotgun/flash +/singleton/fabricator_recipe/ammunition/shotgun/flash name = "shells (flash, shotgun)" path = /obj/item/ammo_pile/shotgun_flash -/singleton/autolathe_recipe/ammunition/shotgun/stun +/singleton/fabricator_recipe/ammunition/shotgun/stun name = "shells (stun cartridge, shotgun)" - path = /obj/item/ammo_pile/shotgun_stunshell + path = /obj/item/ammo_casing/shotgun/stunshell -/singleton/autolathe_recipe/ammunition/shotgun/slug +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_recipe/ammunition/detective_revolver_lethal + name = "speed loader (.38)" + path = /obj/item/ammo_magazine/c38 + hack_only = TRUE + +/singleton/fabricator_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 +/singleton/fabricator_recipe/ammunition/magazine_rubber name = "magazine (.45, rubber, pistol)" path = /obj/item/ammo_magazine/c45m/rubber -/singleton/autolathe_recipe/ammunition/magazine_flash +/singleton/fabricator_recipe/ammunition/magazine_flash name = "magazine (.45, flash, pistol)" path = /obj/item/ammo_magazine/c45m/flash -/singleton/autolathe_recipe/ammunition/magazine_fourty_five/extended +/singleton/fabricator_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 +/singleton/fabricator_recipe/ammunition/submachine_mag name = "magazine (.45, submachine gun)" path = /obj/item/ammo_magazine/submachinemag hack_only = TRUE -/singleton/autolathe_recipe/ammunition/uzi_mag +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_recipe/ammunition/magazine_stetchkin_flash name = "magazine (9mm, flash)" path = /obj/item/ammo_magazine/mc9mm/flash -/singleton/autolathe_recipe/ammunition/magazine_smg +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_recipe/ammunition/magazine_c20r name = "magazine (10mm)" path = /obj/item/ammo_magazine/a10mm hack_only = TRUE -/singleton/autolathe_recipe/ammunition/magazine_carbine +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_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 +/singleton/fabricator_recipe/ammunition/magazine_arifle name = "magazine (7.62mm)" path = /obj/item/ammo_magazine/c762 hack_only = TRUE -/singleton/autolathe_recipe/ammunition/clip_boltaction +/singleton/fabricator_recipe/ammunition/clip_boltaction name = "clip (7.62mm)" path = /obj/item/ammo_magazine/boltaction hack_only = TRUE diff --git a/code/game/machinery/autolathe/designs/armaments.dm b/code/modules/fabrication/designs/general/designs_arms.dm similarity index 60% rename from code/game/machinery/autolathe/designs/armaments.dm rename to code/modules/fabrication/designs/general/designs_arms.dm index 501cae48709..8870a0ac67d 100644 --- a/code/game/machinery/autolathe/designs/armaments.dm +++ b/code/modules/fabrication/designs/general/designs_arms.dm @@ -1,40 +1,40 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/armaments) +ABSTRACT_TYPE(/singleton/fabricator_recipe/armaments) name = "Abstract Armaments" category = "Armaments" -/singleton/autolathe_recipe/armaments/grenade +/singleton/fabricator_recipe/armaments/grenade name = "grenade casing" path = /obj/item/grenade/chem_grenade -/singleton/autolathe_recipe/armaments/grenade/large +/singleton/fabricator_recipe/armaments/grenade/large name = "large grenade casing" path = /obj/item/grenade/chem_grenade/large -/singleton/autolathe_recipe/armaments/handcuffs +/singleton/fabricator_recipe/armaments/handcuffs name = "handcuffs" path = /obj/item/handcuffs -/singleton/autolathe_recipe/armaments/flamethrower +/singleton/fabricator_recipe/armaments/flamethrower name = "flamethrower" path = /obj/item/flamethrower/full security_level = SEC_LEVEL_RED -/singleton/autolathe_recipe/armaments/tacknife +/singleton/fabricator_recipe/armaments/tacknife name = "tactical knife" path = /obj/item/material/knife/tacknife security_level = SEC_LEVEL_RED -/singleton/autolathe_recipe/armaments/brassknuckles +/singleton/fabricator_recipe/armaments/brassknuckles name = "brass knuckles" path = /obj/item/clothing/gloves/brassknuckles hack_only = TRUE -/singleton/autolathe_recipe/armaments/electropack +/singleton/fabricator_recipe/armaments/electropack name = "electropack" path = /obj/item/device/radio/electropack hack_only = TRUE -/singleton/autolathe_recipe/armaments/trap +/singleton/fabricator_recipe/armaments/trap name = "mechanical trap" path = /obj/item/trap hack_only = TRUE diff --git a/code/game/machinery/autolathe/designs/components.dm b/code/modules/fabrication/designs/general/designs_devices.dm similarity index 57% rename from code/game/machinery/autolathe/designs/components.dm rename to code/modules/fabrication/designs/general/designs_devices.dm index a269a7e98ba..76c35e79c0c 100644 --- a/code/game/machinery/autolathe/designs/components.dm +++ b/code/modules/fabrication/designs/general/designs_devices.dm @@ -1,53 +1,53 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/components) +ABSTRACT_TYPE(/singleton/fabricator_recipe/components) name = "Abstract Components" category = "Devices and Components" -/singleton/autolathe_recipe/components/consolescreen +/singleton/fabricator_recipe/components/consolescreen name = "console screen" path = /obj/item/stock_parts/console_screen -/singleton/autolathe_recipe/components/igniter +/singleton/fabricator_recipe/components/igniter name = "igniter" path = /obj/item/device/assembly/igniter -/singleton/autolathe_recipe/components/signaler +/singleton/fabricator_recipe/components/signaler name = "signaler" path = /obj/item/device/assembly/signaler -/singleton/autolathe_recipe/components/sensor_infra +/singleton/fabricator_recipe/components/sensor_infra name = "infrared sensor" path = /obj/item/device/assembly/infra -/singleton/autolathe_recipe/components/timer +/singleton/fabricator_recipe/components/timer name = "timer" path = /obj/item/device/assembly/timer -/singleton/autolathe_recipe/components/sensor_prox +/singleton/fabricator_recipe/components/sensor_prox name = "proximity sensor" path = /obj/item/device/assembly/prox_sensor -/singleton/autolathe_recipe/components/cable_coil +/singleton/fabricator_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 +/singleton/fabricator_recipe/components/micromanip name = "micro-manipulator" path = /obj/item/stock_parts/manipulator -/singleton/autolathe_recipe/components/matterbin +/singleton/fabricator_recipe/components/matterbin name = "matter bin" path = /obj/item/stock_parts/matter_bin -/singleton/autolathe_recipe/components/capacitor +/singleton/fabricator_recipe/components/capacitor name = "capacitor" path = /obj/item/stock_parts/capacitor -/singleton/autolathe_recipe/components/scanningmod +/singleton/fabricator_recipe/components/scanningmod name = "scanning module" path = /obj/item/stock_parts/scanning_module -/singleton/autolathe_recipe/components/microlaser +/singleton/fabricator_recipe/components/microlaser name = "micro-laser" path = /obj/item/stock_parts/micro_laser diff --git a/code/game/machinery/autolathe/designs/engineering.dm b/code/modules/fabrication/designs/general/designs_engineering.dm similarity index 56% rename from code/game/machinery/autolathe/designs/engineering.dm rename to code/modules/fabrication/designs/general/designs_engineering.dm index acc11207e48..0cacbb3b75c 100644 --- a/code/game/machinery/autolathe/designs/engineering.dm +++ b/code/modules/fabrication/designs/general/designs_engineering.dm @@ -1,53 +1,53 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/engineering) +ABSTRACT_TYPE(/singleton/fabricator_recipe/engineering) name = "Abstract Engineering" category = "Engineering" -/singleton/autolathe_recipe/engineering/airlockmodule +/singleton/fabricator_recipe/engineering/airlockmodule name = "airlock electronics" path = /obj/item/airlock_electronics -/singleton/autolathe_recipe/engineering/airalarm +/singleton/fabricator_recipe/engineering/airalarm name = "air alarm electronics" path = /obj/item/airalarm_electronics -/singleton/autolathe_recipe/engineering/firealarm +/singleton/fabricator_recipe/engineering/firealarm name = "fire alarm electronics" path = /obj/item/firealarm_electronics -/singleton/autolathe_recipe/engineering/powermodule +/singleton/fabricator_recipe/engineering/powermodule name = "power control module" path = /obj/item/module/power_control -/singleton/autolathe_recipe/engineering/stockparts_box +/singleton/fabricator_recipe/engineering/stockparts_box name = "stock parts box" path = /obj/item/storage/bag/stockparts_box -/singleton/autolathe_recipe/engineering/camera_assembly +/singleton/fabricator_recipe/engineering/camera_assembly name = "camera assembly" path = /obj/item/camera_assembly -/singleton/autolathe_recipe/engineering/suit_cooling +/singleton/fabricator_recipe/engineering/suit_cooling name = "portable suit cooling unit" path = /obj/item/device/suit_cooling_unit/no_cell -/singleton/autolathe_recipe/engineering/emergency_cell +/singleton/fabricator_recipe/engineering/emergency_cell name = "miniature cell" path = /obj/item/cell/device/emergency_light/empty -/singleton/autolathe_recipe/engineering/debugger +/singleton/fabricator_recipe/engineering/debugger name = "debugger" path = /obj/item/device/debugger -/singleton/autolathe_recipe/engineering/floor_light +/singleton/fabricator_recipe/engineering/floor_light name = "floor light" path = /obj/machinery/floor_light -/singleton/autolathe_recipe/engineering/tile_circuit_blue +/singleton/fabricator_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 +/singleton/fabricator_recipe/engineering/tile_circuit_green name = "circuit tile, green" path = /obj/item/stack/tile/circuit_green is_stack = TRUE diff --git a/code/game/machinery/autolathe/designs/general.dm b/code/modules/fabrication/designs/general/designs_general.dm similarity index 56% rename from code/game/machinery/autolathe/designs/general.dm rename to code/modules/fabrication/designs/general/designs_general.dm index 757bba07267..13093e38ce9 100644 --- a/code/game/machinery/autolathe/designs/general.dm +++ b/code/modules/fabrication/designs/general/designs_general.dm @@ -1,51 +1,51 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/general) +ABSTRACT_TYPE(/singleton/fabricator_recipe/general) name = "Abstract General" category = "General" -/singleton/autolathe_recipe/general/bucket +/singleton/fabricator_recipe/general/bucket name = "bucket" path = /obj/item/reagent_containers/glass/bucket -/singleton/autolathe_recipe/general/flashlight +/singleton/fabricator_recipe/general/flashlight name = "flashlight" path = /obj/item/device/flashlight/empty -/singleton/autolathe_recipe/general/extinguisher +/singleton/fabricator_recipe/general/extinguisher name = "extinguisher" path = /obj/item/extinguisher -/singleton/autolathe_recipe/general/radio_headset +/singleton/fabricator_recipe/general/radio_headset name = "radio headset" path = /obj/item/device/radio/headset -/singleton/autolathe_recipe/general/radio_bounced +/singleton/fabricator_recipe/general/radio_bounced name = "shortwave radio" path = /obj/item/device/radio/off -/singleton/autolathe_recipe/general/weldermask +/singleton/fabricator_recipe/general/weldermask name = "welding mask" path = /obj/item/clothing/head/welding -/singleton/autolathe_recipe/general/taperecorder +/singleton/fabricator_recipe/general/taperecorder name = "tape recorder" path = /obj/item/device/taperecorder -/singleton/autolathe_recipe/general/tube +/singleton/fabricator_recipe/general/tube name = "light tube" path = /obj/item/light/tube -/singleton/autolathe_recipe/general/bulb +/singleton/fabricator_recipe/general/bulb name = "light bulb" path = /obj/item/light/bulb -/singleton/autolathe_recipe/general/labeler +/singleton/fabricator_recipe/general/labeler name = "hand labeler" path = /obj/item/device/hand_labeler -/singleton/autolathe_recipe/general/destTagger +/singleton/fabricator_recipe/general/destTagger name = "destination tagger" path = /obj/item/device/destTagger -/singleton/autolathe_recipe/general/cratescanner +/singleton/fabricator_recipe/general/cratescanner name = "crate contents scanner" path = /obj/item/device/cratescanner diff --git a/code/game/machinery/autolathe/designs/materials.dm b/code/modules/fabrication/designs/general/designs_materials.dm similarity index 58% rename from code/game/machinery/autolathe/designs/materials.dm rename to code/modules/fabrication/designs/general/designs_materials.dm index 9ad412fcf9c..efe910c33a5 100644 --- a/code/game/machinery/autolathe/designs/materials.dm +++ b/code/modules/fabrication/designs/general/designs_materials.dm @@ -1,29 +1,28 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/materials) +ABSTRACT_TYPE(/singleton/fabricator_recipe/materials) name = "Abstract Materials" category = "Materials" - is_stack = TRUE -/singleton/autolathe_recipe/materials/metal +/singleton/fabricator_recipe/materials/metal name = "steel sheets" path = /obj/item/stack/material/steel -/singleton/autolathe_recipe/materials/aluminium +/singleton/fabricator_recipe/materials/aluminium name = "aluminium sheets" path = /obj/item/stack/material/aluminium -/singleton/autolathe_recipe/materials/glass +/singleton/fabricator_recipe/materials/glass name = "glass sheets" path = /obj/item/stack/material/glass -/singleton/autolathe_recipe/materials/rglass +/singleton/fabricator_recipe/materials/rglass name = "reinforced glass sheets" path = /obj/item/stack/material/glass/reinforced -/singleton/autolathe_recipe/materials/rods +/singleton/fabricator_recipe/materials/rods name = "metal rods" path = /obj/item/stack/rods -/singleton/autolathe_recipe/materials/barbed_wire +/singleton/fabricator_recipe/materials/barbed_wire name = "barbed wire" path = /obj/item/stack/barbed_wire diff --git a/code/game/machinery/autolathe/designs/medical.dm b/code/modules/fabrication/designs/general/designs_medical.dm similarity index 58% rename from code/game/machinery/autolathe/designs/medical.dm rename to code/modules/fabrication/designs/general/designs_medical.dm index 6c119c0367e..a05f9c44198 100644 --- a/code/game/machinery/autolathe/designs/medical.dm +++ b/code/modules/fabrication/designs/general/designs_medical.dm @@ -1,55 +1,55 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/medical) +ABSTRACT_TYPE(/singleton/fabricator_recipe/medical) name = "Abstract Medical" category = "Medical" -/singleton/autolathe_recipe/medical/scalpel +/singleton/fabricator_recipe/medical/scalpel name = "scalpel" path = /obj/item/surgery/scalpel -/singleton/autolathe_recipe/medical/circularsaw +/singleton/fabricator_recipe/medical/circularsaw name = "circular saw" path = /obj/item/surgery/circular_saw -/singleton/autolathe_recipe/medical/surgicaldrill +/singleton/fabricator_recipe/medical/surgicaldrill name = "surgical drill" path = /obj/item/surgery/surgicaldrill -/singleton/autolathe_recipe/medical/retractor +/singleton/fabricator_recipe/medical/retractor name = "retractor" path = /obj/item/surgery/retractor -/singleton/autolathe_recipe/medical/cautery +/singleton/fabricator_recipe/medical/cautery name = "cautery" path = /obj/item/surgery/cautery -/singleton/autolathe_recipe/medical/hemostat +/singleton/fabricator_recipe/medical/hemostat name = "hemostat" path = /obj/item/surgery/hemostat -/singleton/autolathe_recipe/medical/beaker +/singleton/fabricator_recipe/medical/beaker name = "glass beaker" path = /obj/item/reagent_containers/glass/beaker -/singleton/autolathe_recipe/medical/beaker_large +/singleton/fabricator_recipe/medical/beaker_large name = "large glass beaker" path = /obj/item/reagent_containers/glass/beaker/large -/singleton/autolathe_recipe/medical/vial +/singleton/fabricator_recipe/medical/vial name = "glass vial" path = /obj/item/reagent_containers/glass/beaker/vial -/singleton/autolathe_recipe/medical/autoinjector +/singleton/fabricator_recipe/medical/autoinjector name = "autoinjector" path = /obj/item/reagent_containers/hypospray/autoinjector -/singleton/autolathe_recipe/medical/autoinhaler +/singleton/fabricator_recipe/medical/autoinhaler name = "autoinhaler" path = /obj/item/reagent_containers/inhaler -/singleton/autolathe_recipe/medical/syringe +/singleton/fabricator_recipe/medical/syringe name = "syringe" path = /obj/item/reagent_containers/syringe -/singleton/autolathe_recipe/medical/syringe/large +/singleton/fabricator_recipe/medical/syringe/large name = "large syringe" path = /obj/item/reagent_containers/syringe/large diff --git a/code/game/machinery/autolathe/designs/tools.dm b/code/modules/fabrication/designs/general/designs_tools.dm similarity index 54% rename from code/game/machinery/autolathe/designs/tools.dm rename to code/modules/fabrication/designs/general/designs_tools.dm index 2b5d6a1226e..9cf4c4cb49e 100644 --- a/code/game/machinery/autolathe/designs/tools.dm +++ b/code/modules/fabrication/designs/general/designs_tools.dm @@ -1,47 +1,47 @@ -ABSTRACT_TYPE(/singleton/autolathe_recipe/tools) +ABSTRACT_TYPE(/singleton/fabricator_recipe/tools) name = "Abstract Tools" category = "Tools" -/singleton/autolathe_recipe/tools/crowbar +/singleton/fabricator_recipe/tools/crowbar name = "crowbar" path = /obj/item/crowbar -/singleton/autolathe_recipe/tools/multitool +/singleton/fabricator_recipe/tools/multitool name = "multitool" path = /obj/item/device/multitool -/singleton/autolathe_recipe/tools/geiger +/singleton/fabricator_recipe/tools/geiger name = "geiger counter" path = /obj/item/device/geiger -/singleton/autolathe_recipe/tools/t_scanner +/singleton/fabricator_recipe/tools/t_scanner name = "T-ray scanner" path = /obj/item/device/t_scanner -/singleton/autolathe_recipe/tools/weldertool +/singleton/fabricator_recipe/tools/weldertool name = "welding tool" path = /obj/item/weldingtool -/singleton/autolathe_recipe/tools/welder_industrial +/singleton/fabricator_recipe/tools/welder_industrial name = "industrial welding tool" path = /obj/item/weldingtool/largetank -/singleton/autolathe_recipe/tools/screwdriver +/singleton/fabricator_recipe/tools/screwdriver name = "screwdriver" path = /obj/item/screwdriver -/singleton/autolathe_recipe/tools/wirecutters +/singleton/fabricator_recipe/tools/wirecutters name = "wirecutters" path = /obj/item/wirecutters -/singleton/autolathe_recipe/tools/wrench +/singleton/fabricator_recipe/tools/wrench name = "wrench" path = /obj/item/wrench -/singleton/autolathe_recipe/tools/hatchet +/singleton/fabricator_recipe/tools/hatchet name = "hatchet" path = /obj/item/material/hatchet -/singleton/autolathe_recipe/tools/minihoe +/singleton/fabricator_recipe/tools/minihoe name = "mini hoe" path = /obj/item/material/minihoe diff --git a/code/modules/fabrication/designs/micro/designs_cutlery.dm b/code/modules/fabrication/designs/micro/designs_cutlery.dm new file mode 100644 index 00000000000..552dabf4a24 --- /dev/null +++ b/code/modules/fabrication/designs/micro/designs_cutlery.dm @@ -0,0 +1,76 @@ +ABSTRACT_TYPE(/singleton/fabricator_recipe/cutlery) + name = "Abstract Cutlery" + category = "Cutlery" + fabricator_types = list(FABRICATOR_CLASS_MICRO) + +/singleton/fabricator_recipe/cutlery/fork_aluminum + name = "fork, aluminium" + path = /obj/item/material/kitchen/utensil/fork + category = "Cutlery" + fabricator_types = list(FABRICATOR_CLASS_MICRO) + +/singleton/fabricator_recipe/cutlery/spoon_aluminum + name = "spoon, aluminium" + path = /obj/item/material/kitchen/utensil/spoon + +/singleton/fabricator_recipe/cutlery/spork_aluminum + name = "spork, aluminium" + path = /obj/item/material/kitchen/utensil/spork + +/singleton/fabricator_recipe/cutlery/knife_aluminum + name = "table knife, aluminium" + path = /obj/item/material/kitchen/utensil/knife + +/singleton/fabricator_recipe/cutlery/chopsticks_aluminum + name = "chopsticks, aluminium" + path = /obj/item/material/kitchen/utensil/fork/chopsticks + +/singleton/fabricator_recipe/cutlery/fork_plastic + name = "fork, plastic" + path = /obj/item/material/kitchen/utensil/fork/plastic + build_time = 2 SECONDS + +/singleton/fabricator_recipe/cutlery/spoon_plastic + name = "spoon, plastic" + path = /obj/item/material/kitchen/utensil/spoon/plastic + build_time = 2 SECONDS + +/singleton/fabricator_recipe/cutlery/spork_plastic + name = "spork, plastic" + path = /obj/item/material/kitchen/utensil/spork/plastic + build_time = 2 SECONDS + +/singleton/fabricator_recipe/cutlery/knife_plastic + name = "table knife, plastic" + path = /obj/item/material/kitchen/utensil/knife/plastic + build_time = 2 SECONDS + +/singleton/fabricator_recipe/cutlery/chopsticks_plastic + name = "chopsticks, plastic" + path = /obj/item/material/kitchen/utensil/fork/chopsticks/plastic + build_time = 2 SECONDS + +/singleton/fabricator_recipe/cutlery/fork_bamboo + name = "fork, bamboo" + path = /obj/item/material/kitchen/utensil/fork/bamboo + build_time = 4 SECONDS + +/singleton/fabricator_recipe/cutlery/spoon_bamboo + name = "spoon, bamboo" + path = /obj/item/material/kitchen/utensil/spoon/bamboo + build_time = 4 SECONDS + +/singleton/fabricator_recipe/cutlery/spork_bamboo + name = "spork, bamboo" + path = /obj/item/material/kitchen/utensil/spork/bamboo + build_time = 4 SECONDS + +/singleton/fabricator_recipe/cutlery/knife_bamboo + name = "table knife, bamboo" + path = /obj/item/material/kitchen/utensil/knife/bamboo + build_time = 4 SECONDS + +/singleton/fabricator_recipe/cutlery/chopsticks_bamboo + name = "chopsticks, bamboo" + path = /obj/item/material/kitchen/utensil/fork/chopsticks/bamboo + build_time = 4 SECONDS diff --git a/code/modules/fabrication/designs/micro/designs_dinnerware.dm b/code/modules/fabrication/designs/micro/designs_dinnerware.dm new file mode 100644 index 00000000000..11d7d16d82f --- /dev/null +++ b/code/modules/fabrication/designs/micro/designs_dinnerware.dm @@ -0,0 +1,20 @@ +ABSTRACT_TYPE(/singleton/fabricator_recipe/dinnerware) + name = "Abstract Dinnerware" + category = "Dinnerware" + fabricator_types = list(FABRICATOR_CLASS_MICRO, FABRICATOR_CLASS_GENERAL) + +/singleton/fabricator_recipe/dinnerware/jar + name = "jar" + path = /obj/item/glass_jar + +/singleton/fabricator_recipe/dinnerware/bowl + name = "bowl" + path = /obj/item/reagent_containers/cooking_container/board/bowl + +/singleton/fabricator_recipe/dinnerware/bottle + name = "bottle" + path = /obj/item/reagent_containers/food/drinks/bottle + +/singleton/fabricator_recipe/dinnerware/ashtray_glass + name = "glass ashtray" + path = /obj/item/material/ashtray/glass diff --git a/code/modules/fabrication/designs/micro/designs_glasses.dm b/code/modules/fabrication/designs/micro/designs_glasses.dm new file mode 100644 index 00000000000..a73b029319d --- /dev/null +++ b/code/modules/fabrication/designs/micro/designs_glasses.dm @@ -0,0 +1,49 @@ +ABSTRACT_TYPE(/singleton/fabricator_recipe/drinking_glass) + name = "Abstract Drinking Glasses" + category = "Drinking Glasses" + fabricator_types = list(FABRICATOR_CLASS_MICRO, FABRICATOR_CLASS_GENERAL) + build_time = 3 SECONDS + +/singleton/fabricator_recipe/drinking_glass/regular_glass + name = "drinking glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass + +/singleton/fabricator_recipe/drinking_glass/half_pint_glass + name = "half pint glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/square + +/singleton/fabricator_recipe/drinking_glass/rocks_glass + name = "rocks glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/rocks + +/singleton/fabricator_recipe/drinking_glass/sherry_glass + name = "sherry glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/shake + +/singleton/fabricator_recipe/drinking_glass/cocktail_glass + name = "cocktail glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/cocktail + +/singleton/fabricator_recipe/drinking_glass/shot_glass + name = "shot glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/shot + +/singleton/fabricator_recipe/drinking_glass/pint_glass + name = "pint glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/pint + +/singleton/fabricator_recipe/drinking_glass/mug_glass + name = "mug glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/mug + +/singleton/fabricator_recipe/drinking_glass/flute_glass + name = "flute glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/flute + +/singleton/fabricator_recipe/drinking_glass/cognac_glass + name = "cognac glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/cognac + +/singleton/fabricator_recipe/drinking_glass/goblet_glass + name = "goblet glass" + path = /obj/item/reagent_containers/food/drinks/drinkingglass/newglass/goblet diff --git a/code/modules/fabrication/fabricator_build.dm b/code/modules/fabrication/fabricator_build.dm new file mode 100644 index 00000000000..b36c7d9cb76 --- /dev/null +++ b/code/modules/fabrication/fabricator_build.dm @@ -0,0 +1,108 @@ +///Processes the current build, incrementing its remaining time and handling removing it from the print queue +/obj/machinery/fabricator/proc/update_current_build(spend_time) + + if(!istype(currently_printing) || !is_functioning()) + return + + // Decrement our current build timer. + currently_printing.remaining_time -= max(1, max(1, spend_time SECONDS * build_time_multiplier)) + if(currently_printing.remaining_time > 0) + return + + // Print the item. + var/obj/item/I = new currently_printing.target_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) + get_next_build() + update_icon() + +/obj/machinery/fabricator/proc/start_building() + if(!(fab_status_flags & FAB_BUSY) && is_functioning()) + //Start the fabricator's looping sound + if (fabricator_looping_sound == null) + fabricator_looping_sound = new fabricating_sound_loop(src) + fabricator_looping_sound.start() + fab_status_flags |= FAB_BUSY + update_use_power(POWER_USE_ACTIVE) + update_icon() + +/obj/machinery/fabricator/proc/stop_building() + fabricator_looping_sound.stop() + QDEL_NULL(fabricator_looping_sound) + if(fab_status_flags & FAB_BUSY) + fab_status_flags &= ~FAB_BUSY + update_use_power(POWER_USE_IDLE) + update_icon() + STOP_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF) + +/obj/machinery/fabricator/proc/get_next_build() + currently_printing = null + if(length(print_queue)) + currently_printing = print_queue[1] + start_building() + else + stop_building() + updateUsrDialog() + +///Tries to build the next item in the fabricator's queue +/obj/machinery/fabricator/proc/try_queue_build(singleton/fabricator_recipe/recipe, multiplier) + + // Do some basic sanity checking. + if(!is_functioning() || !istype(recipe) || !(recipe in SSfabrication.get_recipes(fabricator_class)) || !can_print_item(recipe)) + return + + multiplier = sanitize_integer(multiplier, 1, 100, 1) + if(!ispath(recipe.path, /obj/item/stack) && multiplier > 1) + multiplier = 1 + + // Check if sufficient resources exist. + for(var/material in recipe.resources) + if(stored_material[material] < round(recipe.resources[material] * mat_efficiency) * multiplier) + return + + // Generate and track a new order. + var/datum/fabricator_build_order/order = new + order.remaining_time = recipe.build_time * multiplier + order.target_recipe = recipe + order.multiplier = multiplier + print_queue += order + + // Remove/earmark resources. + for(var/material in recipe.resources) + var/removed_mat = round(recipe.resources[material] * mat_efficiency) * multiplier + stored_material[material] = max(0, stored_material[material] - removed_mat) + order.earmarked_materials[material] = removed_mat + + if(!currently_printing) + get_next_build() + else + start_building() + +///Tries to cancel the build order +/obj/machinery/fabricator/proc/try_cancel_build(datum/fabricator_build_order/order) + if(istype(order) && currently_printing != order && is_functioning()) + if(order in print_queue) + // Refund some mats. + for(var/mat in order.earmarked_materials) + stored_material[mat] = min(stored_material[mat] + (order.earmarked_materials[mat] * 0.9), storage_capacity[mat]) + print_queue -= order + qdel(order) + return TRUE + return FALSE + +///Determines whether the recipe is valid to print in this fabricator. Checks for hacked status and ship security levels. +/obj/machinery/fabricator/proc/can_print_item(singleton/fabricator_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 fabricators + + if(!(fab_status_flags & FAB_HACKED)) + if(recipe.hack_only) + return FALSE + else if(is_on_ship && ship_security_level < recipe.security_level) + return FALSE + + return TRUE diff --git a/code/modules/fabrication/fabricator_intake.dm b/code/modules/fabrication/fabricator_intake.dm new file mode 100644 index 00000000000..1bc039bcfac --- /dev/null +++ b/code/modules/fabrication/fabricator_intake.dm @@ -0,0 +1,74 @@ +#define NO_SPACE "No Space" +#define FILL_COMPLETELY "Fill Completely" +#define FILL_INCOMPLETELY "Fill Incompletely" + +///Loads the lathe with materials +/obj/machinery/fabricator/proc/load_lathe(obj/item/loading_item, mob/user) + + //Resources are being loaded. + var/obj/item/eating = loading_item + 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) && does_flick) + var/obj/item/stack/material/sheet = eating + var/image/adding_mat_overlay = overlay_image(icon, "[icon_state]_mat") + adding_mat_overlay.color = sheet.material.icon_colour + AddOverlays(adding_mat_overlay) + CUT_OVERLAY_IN(adding_mat_overlay, 1 SECOND) + + // Play the lights animation (even if what we inserted wasn't a stack) + if(powered() && does_flick) + flick_overlay_view(mutable_appearance(icon, "[icon_state]_progress"), 1 SECONDS) + + if(istype(eating, /obj/item/stack)) + var/obj/item/stack/stack = eating + var/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(loading_item) + qdel(loading_item) + +#undef NO_SPACE +#undef FILL_COMPLETELY +#undef FILL_INCOMPLETELY diff --git a/code/modules/fabrication/fabricators/fabricator_autolathe.dm b/code/modules/fabrication/fabricators/fabricator_autolathe.dm new file mode 100644 index 00000000000..9a0645b15a3 --- /dev/null +++ b/code/modules/fabrication/fabricators/fabricator_autolathe.dm @@ -0,0 +1,17 @@ +/obj/machinery/fabricator/autolathe + name = "autolathe" + desc = "A large device loaded with various item schematics. It produces common day to day items from a variety of materials." + icon = 'icons/obj/machinery/fabricators/autolathe.dmi' + icon_state = "autolathe" + +/obj/machinery/fabricator/autolathe/mounted + name = "\improper mounted autolathe" + density = FALSE + anchored = FALSE + idle_power_usage = 0 + active_power_usage = 0 + interact_offline = TRUE + does_flick = FALSE + +/obj/machinery/fabricator/mounted/ui_state(mob/user) + return GLOB.heavy_vehicle_state diff --git a/code/modules/fabrication/fabricators/fabricator_hacked.dm b/code/modules/fabrication/fabricators/fabricator_hacked.dm new file mode 100644 index 00000000000..01b4fc576b0 --- /dev/null +++ b/code/modules/fabrication/fabricators/fabricator_hacked.dm @@ -0,0 +1,5 @@ +/obj/machinery/fabricator/autolathe/hacked + desc = "An atypical autolathe. It has an unusual icon in the interface, and appears to have far more options than a normal autolathe." + name = "jailbroken autolathe" + fab_status_flags = FAB_HACKED + manufacturer = "hammertail" diff --git a/code/modules/fabrication/fabricators/fabricator_microlathe.dm b/code/modules/fabrication/fabricators/fabricator_microlathe.dm new file mode 100644 index 00000000000..f3e1f4a8d42 --- /dev/null +++ b/code/modules/fabrication/fabricators/fabricator_microlathe.dm @@ -0,0 +1,42 @@ +/obj/machinery/fabricator/microlathe + name = "microlathe" + desc = "It produces small items from common resources." + icon = 'icons/obj/machinery/fabricators/microlathe.dmi' + icon_state = "minilathe" + idle_power_usage = 5 + active_power_usage = 1000 + fabricator_class = FABRICATOR_CLASS_MICRO + base_storage_capacity = list( + MATERIAL_ALUMINIUM = 5000, + MATERIAL_GLASS = 5000, + MATERIAL_PLASTIC = 5000, + MATERIAL_BAMBOO = 5000 + ) + manufacturer = "idris" + + component_types = list( + /obj/item/circuitboard/microlathe, + /obj/item/stock_parts/matter_bin = 3, + /obj/item/stock_parts/micro_laser, + /obj/item/stock_parts/manipulator, + /obj/item/stock_parts/console_screen + ) + + fabricating_sound_loop = /datum/looping_sound/fabricator/minilathe + +//Subtype for mapping, starts preloaded and set to print glasses +/obj/machinery/fabricator/microlathe/bartender + show_category = "Drinking Glasses" + +/obj/machinery/fabricator/microlathe/bartender/Initialize(mapload) + . = ..() + stored_material[MATERIAL_GLASS] = storage_capacity[MATERIAL_GLASS] + +//Subtype for mapping, starts preloaded and set to print cutlery +/obj/machinery/fabricator/microlathe/cafe + show_category = "Cutlery" + +/obj/machinery/fabricator/microlathe/cafe/Initialize(mapload) + . = ..() + stored_material[MATERIAL_PLASTIC] = storage_capacity[MATERIAL_PLASTIC] + stored_material[MATERIAL_BAMBOO] = storage_capacity[MATERIAL_BAMBOO] diff --git a/code/modules/heavy_vehicle/equipment/utility.dm b/code/modules/heavy_vehicle/equipment/utility.dm index 4fe6af8cecf..c5ce057229f 100644 --- a/code/modules/heavy_vehicle/equipment/utility.dm +++ b/code/modules/heavy_vehicle/equipment/utility.dm @@ -650,7 +650,7 @@ restricted_hardpoints = list(HARDPOINT_BACK) restricted_software = list(MECH_SOFTWARE_UTILITY) origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) - var/obj/machinery/autolathe/mounted/lathe + var/obj/machinery/fabricator/mounted/lathe module_hints = list( "Left Click (Target Materials): Load materials into the autolathe.", "Alt Click (Icon): Open the autolathe's UI.", @@ -658,12 +658,12 @@ /obj/item/mecha_equipment/autolathe/get_hardpoint_maptext() if(lathe?.currently_printing) - return lathe.currently_printing.recipe.name + return lathe.currently_printing.target_recipe.name . = ..() /obj/item/mecha_equipment/autolathe/Initialize() . = ..() - lathe = new /obj/machinery/autolathe/mounted(src) + lathe = new /obj/machinery/fabricator/mounted(src) /obj/item/mecha_equipment/autolathe/installed() ..() diff --git a/code/modules/item_worth/worths_list.dm b/code/modules/item_worth/worths_list.dm index a1a99f08924..21311c61439 100644 --- a/code/modules/item_worth/worths_list.dm +++ b/code/modules/item_worth/worths_list.dm @@ -791,7 +791,7 @@ var/list/worths = list( /obj/machinery/ai_slipper = -50, /obj/machinery/alarm = -80, /obj/machinery/air_sensor = -80, - /obj/machinery/autolathe = -330, + /obj/machinery/fabricator/autolathe = -330, /obj/machinery/bluespacerelay = -400, /obj/machinery/button = 10, /obj/machinery/cablelayer = -170, diff --git a/html/changelogs/GeneralCamo - Autolathe Refactor.yml b/html/changelogs/GeneralCamo - Autolathe Refactor.yml new file mode 100644 index 00000000000..4b76db2ccfb --- /dev/null +++ b/html/changelogs/GeneralCamo - Autolathe Refactor.yml @@ -0,0 +1,63 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: GeneralCamo + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Ported the microlathe from Bay. This is a small autolathe that can make cutlery and drinking glasses." + - rscadd: "Autolathes now make a sound when producing something." + - refactor: "Refactored the autolathe to have its recipes handled by a subsystem, in preparation for further refactors." + - qol: "Changed the autolathe interface to show time remaining to print an item, in seconds." + - balance: "Stacks of materials printed from an autolathe, now multiply the amount of time required to print the item." + - balance: "Autolathes now use microlasers to improve efficiency. Manipulators now solely increase build time." diff --git a/icons/obj/machinery/autolathe.dmi b/icons/obj/machinery/autolathe.dmi deleted file mode 100644 index 691d3bdd494b09e933f7df5b83fd88eb147754e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1592 zcmV-82FLk{P))z{#Zm#Y{VA8>Pr?eF(TN?SKNOCcjLTCoFn=>-)SBsp(67f%;@e*w+a z0QUa?eKs&TZgnkKU_oDLHA_}%H7{C^m^x)`Vtd`Sad{Xb7OL8aCB*JZU6vyoRyNz4#FS| z$ItK-WL}rW?~j8QGh=qpS6E0^MY)Xb8~$)Bb3Ik=X4I#YyDHf@U+oh$Ju(F{LgRCy_IkiR zj)d)uo`=&Pqzv8RAZOSu2hMQdx^AZpxX!?FyKUgjz#V!=I%^=CfgudMHnM?!R}C;+ z_OpM{Q3FR@w_6(;+sM*=pkMws+Npo1&PAWCo&H7HfFH0c?1%y1&2Um5oWA4vp6>)5 zF%aYn{%C~Zcg%nvvdamaFvkg4`eg$nc2St>W25%Wz=U1QKrrF3Us(FScQP<#S4zZ@ zyRfUXd{elA^!_Uh9H|?isXo@}W1T)$8ptTmK+Q8?YM>oGT|yyWLSgm@huI9248*gz zzE|sd`Vdd}LtG#(p;g)di83PZKBVoz1n0_ zbwud%tbb7t{EX1&`LiEv59a%s_@a)tAN6XdQ>)J#w4amuT+u$r33Dgx=7+}(t*)!H zBFJBah9$i0fe38p)`-BD3qu~?7CK^JqBOvl(8P9bjhOffvge^A1_*5D1^@s60001Z zaV~8qpyTbk_a7*Iq0z1L@zduol)ljD)_JZ0v-*4s?LU6{T24@EFB&+z`u|ncfTS;~ zdcl|%;8n^=AM5mSy{;{vAN#*jCs>>>ENcv$P5r;-8Hi2>s=D?1|6I_88IanGGth4R zzRCH5&|WYg^k?dRy1(9N`oFoQ16FtUWI*yj>$(Kjngp*mbb{A6w`2mBH+T0` zK=SZF>b>=ruD`E0TT*8RwxrGsPyvh701>cF4Nx7d$>F&HQip+O8j$Mqf&r;MFBp*9 zR}Dz*nL%>=#m#*=!EsM0d2b&ox?F!33`qKA)qt$8DhA~KR|z@(V)LyWQ0T|<`}RIb zR5Mh(e}B1?#a`+C`^%j&pg3Pxepdz*=L@N>2q?}MxGo1oQQrS( z{hKPFtS8j?OQtIV3VoL(6+e+q3VlcG)g`3V z$?>a8NIE~LSwg4!zq12TB;|JQ$CjbBd004l0k;lhJ+bJ}l_|{`t zdi+TnI1htf{*}RhW5Ceh%iI8Oz`t9r6$6HPGtSsRvl*fc{IYDI(G2B}@P02#Prsk& z0W2HL*hf)3iVjn6FO>jv28<0F-T=5><}rIkf{OV8_>kS!JEeMG>)d{Xh1VV z8D2Dtn1|UJ8qnz(#7_M5q#3}n4gdfE000000000$H+h{SpcXN%&)cs2!2k>xVtNE* q-GFg@-nIb%000000002s|Kkr$`=lECWt9*B0000P))z{#Zm#Y{VA8>PrYa=P`@Asx6C`U?LH#$opBQRRA0~Ht~Id3@^PZxLT z1$uu0&D8+*{{ZO)1%we1y$1(hUtj9#>i_@$O-)U}z`(%3z%i=Sx&QzG0d!JMQvg8b z*k%9#0Lyw*Sad{Xb7OL8aCB*JZU6vyoRv~R3c@fDJSVRR?X^g2MZI{D7U{u$p#-zG z!89pJwD@~d3(`X(%3fx}?Cea~m>kPfRg>ae;Rk5Ll_UqUS)~|_oY~Gb`5L1Rc-z^z zF_v0zFp4l@TpI^7jINsYFyjw_-mMbUcJMp15z`{$A8P6!)8xx|Gb(-Kvh~aC z7Bb1AFw!t`$wJl!ty&ExU~cPG#YiYM1Qn?S@yF-%)cV=`K%^uO1i1urWH=^eUA!;i z1wB5Sb?m<=xBvhH4M{{nRCt{2nu~IqFc3unL$P_7cZ^&2|9`VW0zv?3NfaWfbB{7( zk~MgbK^Aiz&ja@3Z!q1_=kSBeKp2IWkj3=BG5N9B? zTHwl9|IHx*(fnFrD-c*JaNTTh-US#Ddkk)N3h=g*WZswe>Q{H25BVl2Mhi$O-)A(JWWMiP>Y!5!w zYobo=FRPCR$+Ve#n8d8#0WL7S|2qN`$`|;Cy6g>@1ZGwOg5?>I%z?87)b;D`rnrQ1 zehKAb3g_YsECiaik-zE>)JG(@62l}e_#~cLUqWruDvzvN@0w0opV+^do9DpbF`SE> zFJtW2^-bNq9EK-t<~!8WJ)Zl|+Ukf*$V_Q2L)zMidb>iFy5J?ZJzu6OFXglr@q zP1u{CPYc>74`qgIya~-0#9~5Zrh7X?mTrTgm@f;C2o$>l{1Pfm_jZUP-9gL;M+6j@ z?hOC{000000Dx&~&3yjs{omM7qMOg3U4O7~h`J{7dHw`ty{76lRj(Cwc}ZY4->2(R zOy~Ot^M5&1{%*Q{lsnI_<@tLj@_T8W%I|fLPr~=_l=*$9li%we9{>OV0OpwgYtnQh zUnL&@<Tk(YVOsejQfKTg=O^d;luVgOF0C-QeHpYMtIo7$hu|0$^a{p|YN(fpr6mCcK~`U&cEf6V`> zI{764000000QkRnKA)yr(Bt`AEnvMMDPX&xwt#8D(*@2JeEu;kpey+L`%)jkazRqS zc0p|c(}Jf9oGoZvKv$4{ftTHN`UwC400000000000N9A}uZVOZ!&BRVfN9(ppz?Ry lLA(wC000000000u$3HNYNv=Bl@aX^m002ovPDHLkV1mz5EUW+k literal 0 HcmV?d00001 diff --git a/icons/obj/machinery/fabricators/microlathe.dmi b/icons/obj/machinery/fabricators/microlathe.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a05cd760267c5306791c28c184386fef6f218055 GIT binary patch literal 992 zcmV<610Vc}P))z{#Zm#Y{VA8>PrYa=P`@Asx6C`U?LH#$opBQO_F7kB9eW@Z3-e*w+a z0QUa?y$1(cu>*t=5jk%;UteG9>gxah|4mIzz`(#dTsp}B0004WQchCV=-0C=30lFy zgi*`2adM5(Rns13{WkPmazQPF-<^$^1{r^YTcia+AJcW3d}(h+rEgqze#~xxNfyV) z8?@>)n7~3?F9{=|)DQ|dPzmCX2kEKxyZ3<@Nfrol3FgQ@P&g)KUA(@<6Cxd(!2nZh zf&c&lVo5|nRCt{2-HmdhFcgMi{z6nR7)p_?z5nZMLJ)V+CKj4KN&7w1nKDhK=dD^9 zbZnA9_)>#)I5c9|S%PsLN6P#_r+f7$8ql1@QW)uZpAESX{J~t##L1*I(p|b$#;5 zp@f=O<29?zA5pdO%!RaL;*kIGuz)HUIzs000000Q^!-(~zz^pC7QU zKCuHK90Pa`{Q0QQ?>~3`-@_ki95%>O6ww~jZl2LJ$o@AUy*BQ9Xb-v|c) O0000