From 5112fa6c5fcea0f6fa0e223e4d103ba05ee46383 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:05:29 +0300 Subject: [PATCH 01/11] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- maps/event/iccgn_ship/icgnv_hound_shuttle.dm | 2 +- maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm | 2 +- .../exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm | 2 +- .../random_ruins/exoplanet_ruins/transshipment/transshipment.dm | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/maps/event/iccgn_ship/icgnv_hound_shuttle.dm b/maps/event/iccgn_ship/icgnv_hound_shuttle.dm index 6bf967f8e7f8f..ec23d3f840a9c 100644 --- a/maps/event/iccgn_ship/icgnv_hound_shuttle.dm +++ b/maps/event/iccgn_ship/icgnv_hound_shuttle.dm @@ -8,7 +8,7 @@ fuel_consumption = 0 ceiling_type = /turf/simulated/floor/shuttle_ceiling flags = SHUTTLE_FLAGS_PROCESS - defer_initialisation = TRUE + defer_initialisation = FALSE knockdown = FALSE /turf/simulated/floor/shuttle_ceiling/iccgn diff --git a/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm b/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm index 4a284a1fe8c1a..6c9fa53d7d5a0 100644 --- a/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm +++ b/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm @@ -7,7 +7,7 @@ range = 1 ceiling_type = /turf/simulated/floor/shuttle_ceiling flags = SHUTTLE_FLAGS_PROCESS - defer_initialisation = TRUE + defer_initialisation = FALSE knockdown = FALSE /turf/simulated/floor/shuttle_ceiling/sfv_arbiter diff --git a/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm b/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm index cce52b82fb14b..027f75cb01dd9 100644 --- a/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm +++ b/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm @@ -27,7 +27,7 @@ range = 1 shuttle_area = /area/map_template/crashed_shuttle/graysontug fuel_consumption = 4 - defer_initialisation = TRUE + defer_initialisation = FALSE flags = SHUTTLE_FLAGS_PROCESS skill_needed = SKILL_MIN ceiling_type = /turf/simulated/floor/shuttle_ceiling diff --git a/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm b/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm index 7f5e76560eba7..0cd80ffb0192d 100644 --- a/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm +++ b/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm @@ -52,6 +52,7 @@ flags = SHUTTLE_FLAGS_PROCESS skill_needed = SKILL_MIN ceiling_type = /turf/simulated/floor/shuttle_ceiling + defer_initialisation = FALSE /obj/machinery/computer/shuttle_control/explore/old_snz name = "SNZ-210 Shuttle control console" From 50afd59647e1ab990c72be6f7e574feec9007865 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:05:58 +0300 Subject: [PATCH 02/11] =?UTF-8?q?Revert=20"=D0=A2=D0=B5=D1=81=D1=82=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=3F"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5112fa6c5fcea0f6fa0e223e4d103ba05ee46383. --- maps/event/iccgn_ship/icgnv_hound_shuttle.dm | 2 +- maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm | 2 +- .../exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm | 2 +- .../random_ruins/exoplanet_ruins/transshipment/transshipment.dm | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/maps/event/iccgn_ship/icgnv_hound_shuttle.dm b/maps/event/iccgn_ship/icgnv_hound_shuttle.dm index ec23d3f840a9c..6bf967f8e7f8f 100644 --- a/maps/event/iccgn_ship/icgnv_hound_shuttle.dm +++ b/maps/event/iccgn_ship/icgnv_hound_shuttle.dm @@ -8,7 +8,7 @@ fuel_consumption = 0 ceiling_type = /turf/simulated/floor/shuttle_ceiling flags = SHUTTLE_FLAGS_PROCESS - defer_initialisation = FALSE + defer_initialisation = TRUE knockdown = FALSE /turf/simulated/floor/shuttle_ceiling/iccgn diff --git a/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm b/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm index 6c9fa53d7d5a0..4a284a1fe8c1a 100644 --- a/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm +++ b/maps/event/sfv_arbiter/sfv_arbiter_shuttle.dm @@ -7,7 +7,7 @@ range = 1 ceiling_type = /turf/simulated/floor/shuttle_ceiling flags = SHUTTLE_FLAGS_PROCESS - defer_initialisation = FALSE + defer_initialisation = TRUE knockdown = FALSE /turf/simulated/floor/shuttle_ceiling/sfv_arbiter diff --git a/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm b/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm index 027f75cb01dd9..cce52b82fb14b 100644 --- a/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm +++ b/maps/random_ruins/exoplanet_ruins/crashed_shuttle/crashed_shuttle.dm @@ -27,7 +27,7 @@ range = 1 shuttle_area = /area/map_template/crashed_shuttle/graysontug fuel_consumption = 4 - defer_initialisation = FALSE + defer_initialisation = TRUE flags = SHUTTLE_FLAGS_PROCESS skill_needed = SKILL_MIN ceiling_type = /turf/simulated/floor/shuttle_ceiling diff --git a/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm b/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm index 0cd80ffb0192d..7f5e76560eba7 100644 --- a/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm +++ b/maps/random_ruins/exoplanet_ruins/transshipment/transshipment.dm @@ -52,7 +52,6 @@ flags = SHUTTLE_FLAGS_PROCESS skill_needed = SKILL_MIN ceiling_type = /turf/simulated/floor/shuttle_ceiling - defer_initialisation = FALSE /obj/machinery/computer/shuttle_control/explore/old_snz name = "SNZ-210 Shuttle control console" From 748a9cd10637c9b462ca898aea1b92e80b9cab30 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Sun, 19 Jan 2025 21:01:24 +0300 Subject: [PATCH 03/11] Nedodelanniy RND --- code/__defines/research.dm | 2 + code/_helpers/unsorted.dm | 5 +- code/datums/wires/fabricator.dm | 1 + .../circuitboards/machinery/research.dm | 3 +- code/modules/codex/entries/machinery.dm | 2 +- code/modules/fabrication/_fabricator.dm | 2 + code/modules/fabrication/designs/_design.dm | 1 - code/modules/fabrication/fabricator_build.dm | 2 + code/modules/fabrication/fabricator_food.dm | 3 +- code/modules/fabrication/fabricator_hacked.dm | 3 +- code/modules/fabrication/fabricator_intake.dm | 3 +- .../fabrication/fabricator_microlathe.dm | 4 +- code/modules/fabrication/fabricator_topic.dm | 2 + code/modules/fabrication/fabricator_ui.dm | 3 +- .../programs/generic/file_browser.dm | 25 +- code/modules/projectiles/gun.dm | 4 +- code/modules/research/designs/_designs.dm | 29 +- .../research/designs/designs_circuits.dm | 18 +- code/modules/research/rdconsole.dm | 204 ++-- code/modules/research/research.dm | 240 ++++- code/modules/research/server.dm | 18 +- code/unit_tests/machine_tests.dm | 3 +- .../lost_supply_base/lost_supply_base.dmm | 2 +- maps/sierra/z1-z5_sierra.dmm | 13 +- maps/sierra/z6_admin.dmm | 3 +- maps/using.dm | 2 +- mods/RnD/_RnD.dme | 49 + mods/RnD/code/SSresearch.dm | 114 +++ mods/RnD/code/_designs.dm | 156 +++ mods/RnD/code/asset.dm | 27 + mods/RnD/code/autolathe.dm | 968 ++++++++++++++++++ mods/RnD/code/design.dm | 6 + mods/RnD/code/designownloader.dm | 214 ++++ .../designs_autolathe/designs_arms_ammo.dm | 148 +++ .../code/designs_autolathe/designs_cutlery.dm | 40 + .../designs_devices_components.dm | 76 ++ .../designs_autolathe/designs_engineering.dm | 27 + .../code/designs_autolathe/designs_general.dm | 121 +++ .../code/designs_autolathe/designs_glasses.dm | 42 + .../code/designs_autolathe/designs_medical.dm | 51 + .../code/designs_autolathe/designs_tools.dm | 49 + mods/RnD/code/research.dm | 248 +++-- mods/RnD/code/tech_biotech.dm | 34 +- mods/RnD/code/tech_combat.dm | 22 +- mods/RnD/code/tech_data.dm | 40 +- mods/RnD/code/tech_engineering.dm | 40 +- mods/RnD/code/tech_illegal.dm | 16 +- mods/RnD/code/tech_power.dm | 18 +- mods/RnD/code/tech_robotics.dm | 30 +- mods/RnD/code/tech_telecom.dm | 26 +- mods/RnD/icons/autolathe.dmi | Bin 0 -> 38474 bytes mods/dev_mode/maps/dev_map.dmm | 305 ++++-- mods/utility_items/code/wires.dm | 4 +- nano/templates/mods/autolathe.tmpl | 79 ++ nano/templates/mods/autolathe_designs.tmpl | 76 ++ .../templates/mods/autolathe_disk_cloner.tmpl | 109 ++ nano/templates/mods/autolathe_materials.tmpl | 22 + nano/templates/mods/autolathe_oddity.tmpl | 34 + nano/templates/mods/autolathe_queue.tmpl | 94 ++ nano/templates/mods/autolathe_reagents.tmpl | 30 + nano/templates/mods/ntnetdsgn_downloader.tmpl | 107 ++ 61 files changed, 3505 insertions(+), 514 deletions(-) create mode 100644 mods/RnD/code/SSresearch.dm create mode 100644 mods/RnD/code/_designs.dm create mode 100644 mods/RnD/code/asset.dm create mode 100644 mods/RnD/code/autolathe.dm create mode 100644 mods/RnD/code/designownloader.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_arms_ammo.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_cutlery.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_devices_components.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_engineering.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_general.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_glasses.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_medical.dm create mode 100644 mods/RnD/code/designs_autolathe/designs_tools.dm create mode 100644 mods/RnD/icons/autolathe.dmi create mode 100644 nano/templates/mods/autolathe.tmpl create mode 100644 nano/templates/mods/autolathe_designs.tmpl create mode 100644 nano/templates/mods/autolathe_disk_cloner.tmpl create mode 100644 nano/templates/mods/autolathe_materials.tmpl create mode 100644 nano/templates/mods/autolathe_oddity.tmpl create mode 100644 nano/templates/mods/autolathe_queue.tmpl create mode 100644 nano/templates/mods/autolathe_reagents.tmpl create mode 100644 nano/templates/mods/ntnetdsgn_downloader.tmpl diff --git a/code/__defines/research.dm b/code/__defines/research.dm index 560872ef16c6a..2aad735937043 100644 --- a/code/__defines/research.dm +++ b/code/__defines/research.dm @@ -15,3 +15,5 @@ #define PROTOLATHE FLAG(1) //New stuff. Uses glass/metal/chemicals #define MECHFAB FLAG(2) //Mechfab #define CHASSIS FLAG(3) //For protolathe, but differently +#define BIOPRINTER FLAG(4) +#define ORGAN_GROWER FLAG(5) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index b055c35593d56..b2ea5557c971d 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -537,10 +537,13 @@ Turf and target are seperate in case you want to teleport some distance from a t * * Returns a list of atoms. */ -/atom/proc/GetAllContents(searchDepth = 5) +/atom/proc/GetAllContents(searchDepth = 5, includeSelf = FALSE) RETURN_TYPE(/list) var/list/toReturn = list() + if(includeSelf) + toReturn += src + for(var/atom/part in contents) toReturn += part if(length(part.contents) && searchDepth) diff --git a/code/datums/wires/fabricator.dm b/code/datums/wires/fabricator.dm index e5ae5e6e5ed53..d01b75caa0bf8 100644 --- a/code/datums/wires/fabricator.dm +++ b/code/datums/wires/fabricator.dm @@ -1,3 +1,4 @@ + #define AUTOLATHE_HACK_WIRE 1 #define AUTOLATHE_SHOCK_WIRE 2 #define AUTOLATHE_DISABLE_WIRE 4 diff --git a/code/game/objects/items/weapons/circuitboards/machinery/research.dm b/code/game/objects/items/weapons/circuitboards/machinery/research.dm index e02025896fd03..88ca5316798c2 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/research.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/research.dm @@ -45,6 +45,7 @@ /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1 ) +/* /obj/item/stock_parts/circuitboard/replicator name = "circuit board (replicator)" build_path = /obj/machinery/fabricator/replicator @@ -58,7 +59,7 @@ /obj/item/stock_parts/keyboard = 1, /obj/item/stock_parts/power/apc/buildable = 1 ) - +*/ /obj/item/stock_parts/circuitboard/protolathe name = "circuit board (protolathe)" build_path = /obj/machinery/r_n_d/protolathe diff --git a/code/modules/codex/entries/machinery.dm b/code/modules/codex/entries/machinery.dm index 513f6a1a92fdb..563ac3013f89a 100644 --- a/code/modules/codex/entries/machinery.dm +++ b/code/modules/codex/entries/machinery.dm @@ -1,5 +1,5 @@ /datum/codex_entry/replicator - associated_paths = list(/obj/machinery/fabricator/replicator) + associated_paths = list(/obj/machinery/fabricator) mechanics_text = "The food replicator is operated through voice commands. To inquire available dishes on the menu, say 'menu'. To dispense a dish, say the name of the dish listed in its menu. \ Dishes can only be produced as long as the replicator has biomass. To check on the biomass level of the replicator, say 'status'. Various food items or plants may be inserted to refill biomass." diff --git a/code/modules/fabrication/_fabricator.dm b/code/modules/fabrication/_fabricator.dm index 08aac2664f833..8e345875cc9a1 100644 --- a/code/modules/fabrication/_fabricator.dm +++ b/code/modules/fabrication/_fabricator.dm @@ -1,4 +1,5 @@ /obj/machinery/fabricator + /* name = "autolathe" desc = "It produces common day to day items from a variety of materials." icon = 'icons/obj/machines/fabricators/autolathe.dmi' @@ -132,3 +133,4 @@ M.place_sheet(get_turf(src), round(stored_material[mat] / M.units_per_sheet), M.name) ..() return TRUE +*/ diff --git a/code/modules/fabrication/designs/_design.dm b/code/modules/fabrication/designs/_design.dm index ba05bff1a5a69..423fa85278c91 100644 --- a/code/modules/fabrication/designs/_design.dm +++ b/code/modules/fabrication/designs/_design.dm @@ -32,4 +32,3 @@ for(var/datum/reagent/R in I.reagents.reagent_list) resources[R.type] = R.volume * FABRICATOR_EXTRA_COST_FACTOR qdel(I) - diff --git a/code/modules/fabrication/fabricator_build.dm b/code/modules/fabrication/fabricator_build.dm index 29f0826bd52d8..c5f093c7cc350 100644 --- a/code/modules/fabrication/fabricator_build.dm +++ b/code/modules/fabrication/fabricator_build.dm @@ -1,3 +1,4 @@ +/* /obj/machinery/fabricator/proc/update_current_build(spend_time) if(!istype(currently_building) || !is_functioning()) @@ -70,3 +71,4 @@ get_next_build() else start_building() +*/ diff --git a/code/modules/fabrication/fabricator_food.dm b/code/modules/fabrication/fabricator_food.dm index a8759071d4183..f01b84d3cfe7b 100644 --- a/code/modules/fabrication/fabricator_food.dm +++ b/code/modules/fabrication/fabricator_food.dm @@ -1,4 +1,4 @@ -/obj/machinery/fabricator/replicator +/*/obj/machinery/fabricator/replicator name = "food replicator" desc = "A versatile machine that dispenses nourishing but bland food. Responds to voice commands like 'menu' and 'status'." fabricator_class = FABRICATOR_CLASS_FOOD @@ -44,3 +44,4 @@ audible_message("\The [src] states, \"Greetings! I serve the following dishes: [english_list(menu)]\"") else audible_message("\The [src] states, \"Apologies! I cannot serve any dishes at the moment.\"") +*/ diff --git a/code/modules/fabrication/fabricator_hacked.dm b/code/modules/fabrication/fabricator_hacked.dm index 7f841e56aaf3f..b4484b8b2523a 100644 --- a/code/modules/fabrication/fabricator_hacked.dm +++ b/code/modules/fabrication/fabricator_hacked.dm @@ -1,4 +1,5 @@ -/obj/machinery/fabricator/hacked +/*/obj/machinery/fabricator/hacked desc = "A typical autolathe. It has an unusual 'CRaCKZ BY C0wCUb3C0NQ3r0R' glyph bouncing around the interface."; name = "jailbroken autolathe" fab_status_flags = FAB_HACKED +*/ diff --git a/code/modules/fabrication/fabricator_intake.dm b/code/modules/fabrication/fabricator_intake.dm index 42fca0b43f37f..801d14d330452 100644 --- a/code/modules/fabrication/fabricator_intake.dm +++ b/code/modules/fabrication/fabricator_intake.dm @@ -1,4 +1,4 @@ -#define SUBSTANCE_TAKEN_NONE -1 +/*#define SUBSTANCE_TAKEN_NONE -1 #define SUBSTANCE_TAKEN_SOME 0 #define SUBSTANCE_TAKEN_FULL 1 #define SUBSTANCE_TAKEN_ALL 2 @@ -117,3 +117,4 @@ #undef SUBSTANCE_TAKEN_NONE #undef SUBSTANCE_TAKEN_SOME #undef SUBSTANCE_TAKEN_ALL +*/ diff --git a/code/modules/fabrication/fabricator_microlathe.dm b/code/modules/fabrication/fabricator_microlathe.dm index 26240ecbb4303..9823e9753e526 100644 --- a/code/modules/fabrication/fabricator_microlathe.dm +++ b/code/modules/fabrication/fabricator_microlathe.dm @@ -1,4 +1,4 @@ -/obj/machinery/fabricator/micro +/*/obj/machinery/fabricator/micro name = "microlathe" desc = "It produces small items from common resources." icon = 'icons/obj/machines/fabricators/microlathe.dmi' @@ -22,4 +22,4 @@ /obj/machinery/fabricator/micro/bartender/Initialize() . = ..() - stored_material[/material/glass] = base_storage_capacity[/material/glass] \ No newline at end of file + stored_material[/material/glass] = base_storage_capacity[/material/glass]*/ diff --git a/code/modules/fabrication/fabricator_topic.dm b/code/modules/fabrication/fabricator_topic.dm index f98dfbc77e96a..cbddc00a83d06 100644 --- a/code/modules/fabrication/fabricator_topic.dm +++ b/code/modules/fabrication/fabricator_topic.dm @@ -1,3 +1,4 @@ +/* /obj/machinery/fabricator/OnTopic(user, href_list, state) if(href_list["change_category"]) var/choice = input("Which category do you wish to display?") as null|anything in SSfabrication.get_categories(fabricator_class)|"All" @@ -35,3 +36,4 @@ mat.place_sheet(get_turf(src), sheet_count) else if(!isnull(stored_material[mat_path])) stored_material[mat_path] = 0 +*/ diff --git a/code/modules/fabrication/fabricator_ui.dm b/code/modules/fabrication/fabricator_ui.dm index 464542fe52750..6f6da5e2fa3f0 100644 --- a/code/modules/fabrication/fabricator_ui.dm +++ b/code/modules/fabrication/fabricator_ui.dm @@ -1,4 +1,4 @@ -#define PRINT_MULTIPLIER_DIVISOR 5 +/*#define PRINT_MULTIPLIER_DIVISOR 5 /obj/machinery/fabricator/ui_interact(mob/user, ui_key = "rcon", datum/nanoui/ui=null, force_open=1) @@ -89,3 +89,4 @@ return TRUE #undef PRINT_MULTIPLIER_DIVISOR +*/ diff --git a/code/modules/modular_computers/file_system/programs/generic/file_browser.dm b/code/modules/modular_computers/file_system/programs/generic/file_browser.dm index 635e02a84b408..062eb0582348c 100644 --- a/code/modules/modular_computers/file_system/programs/generic/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/generic/file_browser.dm @@ -47,13 +47,25 @@ return if(href_list["PRG_usbdeletefile"]) . = TOPIC_HANDLED - computer.delete_file(href_list["PRG_usbdeletefile"], computer.get_component(PART_DRIVE)) + if(istype(computer.holder, /obj/machinery/computer/modular)) + var/obj/machinery/computer/modular/modular_machine = computer.holder + computer.delete_file(href_list["PRG_usbdeletefile"], modular_machine.portable_drive) + else + computer.delete_file(href_list["PRG_usbdeletefile"], computer.get_component(PART_DRIVE)) if(href_list["PRG_copytousb"]) . = TOPIC_HANDLED - computer.copy_between_disks(href_list["PRG_copytousb"], computer.get_component(PART_HDD), computer.get_component(PART_DRIVE)) + if(istype(computer.holder, /obj/machinery/computer/modular)) + var/obj/machinery/computer/modular/modular_machine = computer.holder + computer.copy_between_disks(href_list["PRG_copytousb"], computer.get_component(PART_HDD), modular_machine.portable_drive) + else + computer.copy_between_disks(href_list["PRG_copytousb"], computer.get_component(PART_HDD), computer.get_component(PART_DRIVE)) if(href_list["PRG_copyfromusb"]) . = TOPIC_HANDLED - computer.copy_between_disks(href_list["PRG_copyfromusb"], computer.get_component(PART_DRIVE), computer.get_component(PART_HDD)) + if(istype(computer.holder, /obj/machinery/computer/modular)) + var/obj/machinery/computer/modular/modular_machine = computer.holder + computer.copy_between_disks(href_list["PRG_copyfromusb"], modular_machine.portable_drive, computer.get_component(PART_HDD)) + else + computer.copy_between_disks(href_list["PRG_copyfromusb"], computer.get_component(PART_DRIVE), computer.get_component(PART_HDD)) if(href_list["PRG_closefile"]) . = TOPIC_HANDLED open_file = null @@ -149,7 +161,12 @@ "undeletable" = F.undeletable ))) data["files"] = files - var/obj/item/stock_parts/computer/hard_drive/portable/RHDD = PRG.computer.get_component(PART_DRIVE) + var/obj/item/stock_parts/computer/hard_drive/portable/RHDD + if(PRG.computer.get_component(PART_DRIVE)) + RHDD = PRG.computer.get_component(PART_DRIVE) + else if(istype(PRG.computer.holder, /obj/machinery/computer/modular)) + var/obj/machinery/computer/modular/modular_machine = PRG.computer.holder + RHDD = modular_machine.portable_drive if(RHDD) data["usbconnected"] = TRUE var/list/usbfiles[0] diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 7ce951d91ed88..5d5615416ed2e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -386,7 +386,7 @@ var/obj/item/rig/R = H.back for(var/obj/item/rig_module/stealth_field/S in R.installed_modules) S.deactivate() - +/* if(space_recoil && !user.check_space_footing()) var/old_dir = user.dir var/mob/living/carbon/human/H = user @@ -395,7 +395,7 @@ user.inertia_ignore = projectile step(user,get_dir(target,user)) user.set_dir(old_dir) - +*/ update_icon() diff --git a/code/modules/research/designs/_designs.dm b/code/modules/research/designs/_designs.dm index 653e05ba79396..7100d83744daf 100644 --- a/code/modules/research/designs/_designs.dm +++ b/code/modules/research/designs/_designs.dm @@ -1,3 +1,4 @@ +/* /*************************************************************** ** Design Datums ** ** All the data for building stuff and tracking reliability. ** @@ -17,9 +18,9 @@ other types of metals and chemistry for reagents). */ //Note: More then one of these can be added to a design. -//[SIERRA-EDIT] - MODPACK_RND + /datum/design //Datum for object designs, used in construction - var/name = null //Name of the created object. If null it will be 'guessed' from build_path if possible. + var/name = null //Name of the created object. If null it will be 'guessed' from build_path if possible. var/desc = null //Description of the created object. If null it will use group_desc and name where applicable. var/item_name = null //An item name before it is modified by various name-modifying procs var/id = "id" //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols. @@ -29,16 +30,13 @@ other types of metals and chemistry for reagents). var/list/chemicals = list() //List of chemicals. var/build_path = null //The path of the object that gets created. var/time = 10 //How many ticks it requires to build - var/list/category = null //Primarily used for Mech Fabricators, but can be used for anything + var/category = null //Primarily used for Mech Fabricators, but can be used for anything. var/sort_string = "ZZZZZ" //Sorting order - var/starts_unlocked = FALSE //If true does not require any technologies and unlocked from the start - var/shortname = null // Used for naming in RDconsole - var/datum/computer_file/binary/design/file /datum/design/New() ..() - AssembleDesignInfo() item_name = name + AssembleDesignInfo() //These procs are used in subtypes for assigning names and descriptions dynamically /datum/design/proc/AssembleDesignInfo() @@ -51,27 +49,13 @@ other types of metals and chemistry for reagents). var/atom/movable/A = build_path name = initial(A.name) item_name = name - if(!shortname) - shortname = capitalize(name) return /datum/design/proc/AssembleDesignDesc() - if(desc) - return if(!desc) //Try to make up a nice description if we don't have one desc = "Allows for the construction of \a [item_name]." - return - -/datum/design/proc/AssembleFileDesignInfo(atom/temp_atom) - AssembleDesignName() - AssembleDesignDesc() - AssembleDesignId() + return -/datum/design/proc/AssembleDesignId() - if(id) - return - id = type -//[/SIERRA-EDIT] - MODPACK_RND //Returns a new instance of the item for this design //This is to allow additional initialization to be performed, including possibly additional contructor arguments. /datum/design/proc/Fabricate(newloc, fabricator) @@ -90,3 +74,4 @@ GLOBAL_LIST_INIT(build_path_to_design_datum_path, populate_design_datum_index()) var/datum/design/fake_design = path if(initial(fake_design.build_path)) .[initial(fake_design.build_path)] = path +*/ diff --git a/code/modules/research/designs/designs_circuits.dm b/code/modules/research/designs/designs_circuits.dm index 7df343d51b170..0846a3e85112d 100644 --- a/code/modules/research/designs/designs_circuits.dm +++ b/code/modules/research/designs/designs_circuits.dm @@ -12,19 +12,21 @@ if(build_path) var/obj/item/stock_parts/circuitboard/C = build_path if(initial(C.board_type) == "machine") - name = "Machine circuit design ([item_name])" + name = "Machine circuit design ([C.name])" category = list("Machine Circuit") else if(initial(C.board_type) == "computer") - name = "Computer circuit design ([item_name])" + name = "Computer circuit design ([C.name])" category = list("Computer Circuit") else - name = "Circuit design ([item_name])" + name = "([C.name])" category = list("Circuit") -//[/SIERRA-EDIT] - MODPACK_RND /datum/design/circuit/AssembleDesignDesc() - if(!desc) - desc = "Allows for the construction of \a [item_name] circuit board." + if(build_path) + var/obj/item/stock_parts/circuitboard/C = build_path + if(!desc) + desc = "Allows for the construction of \a [C.desc] circuit board." +//[/SIERRA-EDIT] - MODPACK_RND /datum/design/circuit/arcademachine name = "battle arcade machine" @@ -224,14 +226,14 @@ req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) build_path = /obj/item/stock_parts/circuitboard/autolathe sort_string = "HABAD" - +/* /datum/design/circuit/replicator name = "replicator board" id = "replicator" req_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 3, TECH_BIO = 3) build_path = /obj/item/stock_parts/circuitboard/replicator sort_string = "HABAE" - +*/ /datum/design/circuit/microlathe name = "microlathe board" id = "microlathe" diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 1df120b86b770..e508ec385b094 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -51,8 +51,8 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/can_research = TRUE //Is this console capable of researching - var/selected_tech_tree - var/selected_technology + var/datum/tech/selected_tech_tree + var/datum/technology/selected_technology var/show_settings = FALSE var/show_link_menu = FALSE var/selected_protolathe_category @@ -327,23 +327,24 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(..()) return 1 - if(href_list["select_tech_tree"]) - var/new_select_tech_tree = href_list["select_tech_tree"] - if(files.all_technologies[new_select_tech_tree]) - selected_tech_tree = new_select_tech_tree + if(href_list["select_tech_tree"]) // User selected a tech tree. + var/datum/tech/tech_tree = locate(href_list["select_tech_tree"]) in files.researched_tech + if(tech_tree && tech_tree.shown) + selected_tech_tree = tech_tree selected_technology = null - if(href_list["select_technology"]) - var/new_selected_technology = href_list["select_technology"] - if(files.all_technologies[selected_tech_tree][new_selected_technology]) - selected_technology = new_selected_technology - if(href_list["unlock_technology"]) - var/unlock = href_list["unlock_technology"] - files.UnlockTechology(files.all_technologies[selected_tech_tree][unlock]) - if(href_list["go_screen"]) + if(href_list["select_technology"]) // User selected a technology node. + var/tech_node = locate(href_list["select_technology"]) in SSresearch.all_tech_nodes + if(tech_node) + selected_technology = tech_node + if(href_list["unlock_technology"]) // User attempts to unlock a technology node (Safeties are within UnlockTechnology) + var/tech_node = locate(href_list["unlock_technology"]) in SSresearch.all_tech_nodes + if(tech_node) + files.UnlockTechology(tech_node) + if(href_list["go_screen"]) // User is changing the screen. var/where = href_list["go_screen"] if(href_list["need_access"]) if(!allowed(usr) && !emagged) - to_chat(usr, "Unauthorized Access.") + to_chat(usr, SPAN_WARNING("Unauthorized access.")) return screen = where if(screen == "protolathe" || screen == "circuit_imprinter") @@ -511,16 +512,16 @@ won't update every console in existence) but it's more of a hassle to do. Also, data["can_research"] = can_research var/list/tech_tree_list = list() - for(var/tech_tree_id in files.tech_trees) - var/datum/tech/Tech_Tree = files.tech_trees[tech_tree_id] - if(!Tech_Tree.shown) + for(var/tree in files.researched_tech) + var/datum/tech/tech_tree = tree + if(!tech_tree.shown) continue var/list/tech_tree_data = list( - "id" = Tech_Tree.id, - "name" = "[Tech_Tree.name]", - "shortname" = "[Tech_Tree.shortname]", - "level" = Tech_Tree.level, - "maxlevel" = Tech_Tree.maxlevel, + "id" = tech_tree.type, + "name" = "[tech_tree.name]", + "shortname" = "[tech_tree.shortname]", + "level" = tech_tree.level, + "maxlevel" = tech_tree.maxlevel, ) tech_tree_list += list(tech_tree_data) data["tech_trees"] = tech_tree_list @@ -641,113 +642,123 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/list/line_list = list() var/list/tech_tree_list = list() - for(var/tech_tree_id in files.tech_trees) - var/datum/tech/Tech_Tree = files.tech_trees[tech_tree_id] - if(!Tech_Tree.shown) + for(var/tree in files.researched_tech) + var/datum/tech/tech_tree = tree + if(!tech_tree.shown) continue var/list/tech_tree_data = list( - "id" = Tech_Tree.id, - "name" = "[Tech_Tree.name]", - "shortname" = "[Tech_Tree.shortname]", + "id" = "\ref[tech_tree]", + "name" = "[tech_tree.name]", + "shortname" = "[tech_tree.shortname]", ) tech_tree_list += list(tech_tree_data) data["tech_trees"] = tech_tree_list if(!selected_tech_tree) - selected_tech_tree = files.all_technologies[1] + selected_tech_tree = files.researched_tech[1] var/list/tech_list = list() - if(selected_tech_tree && files.all_technologies[selected_tech_tree]) - var/datum/tech/Tech_Tree = files.tech_trees[selected_tech_tree] - data["tech_tree_name"] = Tech_Tree.name - data["tech_tree_desc"] = Tech_Tree.desc - data["tech_tree_level"] = Tech_Tree.level - - for(var/tech_id in files.all_technologies[selected_tech_tree]) - var/datum/technology/Tech = files.all_technologies[selected_tech_tree][tech_id] + if(selected_tech_tree) + data["tech_tree_name"] = selected_tech_tree.name + data["tech_tree_desc"] = selected_tech_tree.desc + data["tech_tree_level"] = selected_tech_tree.level + + for(var/tech in SSresearch.all_tech_trees[selected_tech_tree.type]) + var/datum/technology/tech_node = tech var/list/tech_data = list( - "id" = Tech.id, - "name" = "[Tech.name]", - "x" = round(Tech.x*100), - "y" = round(Tech.y*100), - "icon" = "[Tech.icon]", - "isresearched" = "[files.IsResearched(Tech)]", - "canresearch" = "[files.CanResearch(Tech)]", + "id" = "\ref[tech_node]", + "name" = "[tech_node.name]", + "x" = round(tech_node.x*100), + "y" = round(tech_node.y*100), + "icon" = "[tech_node.icon]", + "isresearched" = "[files.IsResearched(tech_node)]", + "canresearch" = "[files.CanResearch(tech_node)]", + "description" = "[tech_node.desc]" ) tech_list += list(tech_data) - for(var/req_tech_id in Tech.required_technologies) - if(files.all_technologies[selected_tech_tree][req_tech_id]) - var/datum/technology/OTech = files.all_technologies[selected_tech_tree][req_tech_id] - if(OTech.tech_type == Tech.tech_type) - var/line_x = (min(round(OTech.x*100), round(Tech.x*100))) - var/line_y = (min(round(OTech.y*100), round(Tech.y*100))) - var/width = (abs(round(OTech.x*100) - round(Tech.x*100))) - var/height = (abs(round(OTech.y*100) - round(Tech.y*100))) - - var/istop = FALSE - if(OTech.y > Tech.y) - istop = TRUE - var/isright = FALSE - if(OTech.x < Tech.x) - isright = TRUE - - var/list/line_data = list( - "line_x" = line_x, - "line_y" = line_y, - "width" = width, - "height" = height, - "istop" = istop, - "isright" = isright, - ) - line_list += list(line_data) + for(var/req_tech in tech_node.required_technologies) + var/datum/technology/other_tech = locate(req_tech) in SSresearch.all_tech_nodes + if(other_tech && other_tech.tech_type == tech_node.tech_type) + var/line_x = (min(round(other_tech.x*100), round(tech_node.x*100))) + var/line_y = (min(round(other_tech.y*100), round(tech_node.y*100))) + var/width = (abs(round(other_tech.x*100) - round(tech_node.x*100))) + var/height = (abs(round(other_tech.y*100) - round(tech_node.y*100))) + + var/istop = FALSE + if(other_tech.y > tech_node.y) + istop = TRUE + var/isright = FALSE + if(other_tech.x < tech_node.x) + isright = TRUE + + var/list/line_data = list( + "line_x" = line_x, + "line_y" = line_y, + "width" = width, + "height" = height, + "istop" = istop, + "isright" = isright, + ) + line_list += list(line_data) data["techs"] = tech_list data["lines"] = line_list - data["selected_tech_tree"] = selected_tech_tree + data["selected_tech_tree"] = "\ref[selected_tech_tree]" data["research_points"] = files.research_points data["selected_technology_id"] = "" if(selected_technology) - var/datum/technology/Tech = files.all_technologies[selected_tech_tree][selected_technology] + var/datum/technology/tech_node = selected_technology var/list/technology_data = list( - "name" = Tech.name, - "desc" = Tech.desc, - "id" = Tech.id, - "tech_type" = Tech.tech_type, - "cost" = Tech.cost, - "isresearched" = files.IsResearched(Tech), + "name" = tech_node.name, + "desc" = tech_node.desc, + "id" = "\ref[tech_node]", + "tech_type" = tech_node.tech_type, + "cost" = tech_node.cost, + "isresearched" = files.IsResearched(tech_node), ) - data["selected_technology_id"] = Tech.id + data["selected_technology_id"] = "\ref[tech_node]" var/list/requirement_list = list() - for(var/t in Tech.required_tech_levels) - var/datum/tech/Tech_Tree = files.tech_trees[t] - - var/level = Tech.required_tech_levels[t] + for(var/t in tech_node.required_tech_levels) + var/datum/tech/tree = locate(t) in files.researched_tech + var/level = tech_node.required_tech_levels[t] var/list/req_data = list( - "text" = "[Tech_Tree.shortname] level [level]", - "isgood" = (Tech_Tree.level >= level) + "text" = "[tree.shortname] level [level]", + "isgood" = (tree.level >= level) ) requirement_list += list(req_data) - for(var/t in Tech.required_technologies) - var/datum/technology/OTech = files.all_technologies[selected_tech_tree][t] - + for(var/t in tech_node.required_technologies) + var/datum/technology/other_tech = locate(t) in SSresearch.all_tech_nodes var/list/req_data = list( - "text" = "[OTech.name]", - "isgood" = files.IsResearched(OTech) + "text" = "[other_tech.name]", + "isgood" = files.IsResearched(other_tech) ) requirement_list += list(req_data) technology_data["requirements"] = requirement_list var/list/unlock_list = list() - for(var/T in Tech.unlocks_designs) - var/datum/design/D = files.design_by_id[T] - var/list/unlock_data = list( - "text" = "[D.shortname]" - ) - unlock_list += list(unlock_data) + for(var/T in tech_node.unlocks_designs) + var/datum/design/D = SSresearch.get_design(T) + if(D) // remove? + var/list/build_types = list() + if(D.build_type & IMPRINTER) + build_types += "imprinter" + if(D.build_type & PROTOLATHE) + build_types += "protolathe" + if(D.build_type & BIOPRINTER) + build_types += "bioprinter" + if(D.build_type & MECHFAB) + build_types += "exosuit fabricator" + if(D.build_type & ORGAN_GROWER) + build_types += "organ grower" + var/list/unlock_data = list( + "text" = "[D.name]", + "build_types" = english_list(build_types, "") + ) + unlock_list += list(unlock_data) technology_data["unlocks"] = unlock_list data["selected_technology"] = technology_data @@ -758,6 +769,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, ui.set_initial_data(data) ui.open() + ui.set_auto_update(1) //[/SIERRA-EDIT] - MODPACK_RND /obj/machinery/computer/rdconsole/robotics diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm index 94b60b6e305d9..6e4ee2b4b837b 100644 --- a/code/modules/research/research.dm +++ b/code/modules/research/research.dm @@ -1,66 +1,222 @@ -//[SIERRA-EDIT] - MODPACK_RND - +/* // mods\RnD\code\research.dm /* General Explination: The research datum is the "folder" where all the research information is stored in a R&D console. It's also a holder for all the various procs used to manipulate it. It has four variables and seven procs: Variables: -- tech_trees is a list of all /datum/tech that can potentially be researched by the player. -- all_technologies is a list of all /datum/technology that can potentially be researched by the player. -- researched_tech contains all researched technologies -- design_by_id contains all existing /datum/design. -- known_designs contains all researched /datum/design. -- experiments contains data related to earning research points, more info in experiment.dm -- research_points is an amount of points that can be spend on researching technologies -- design_categories_protolathe stores all unlocked categories for protolathe designs -- design_categories_imprinter stores all unlocked categories for circuit imprinter designs +- possible_tech is a list of all the /datum/tech that can potentially be researched by the player. The RefreshResearch() proc +(explained later) only goes through those when refreshing what you know. Generally, possible_tech contains ALL of the existing tech +but it is possible to add tech to the game that DON'T start in it (example: Xeno tech). Generally speaking, you don't want to mess +with these since they should be the default version of the datums. They're actually stored in a list rather then using typesof to +refer to them since it makes it a bit easier to search through them for specific information. +- know_tech is the companion list to possible_tech. It's the tech you can actually research and improve. Until it's added to this +list, it can't be improved. All the tech in this list are visible to the player. +- possible_designs is functionally identical to possbile_tech except it's for /datum/design. +- known_designs is functionally identical to known_tech except it's for /datum/design Procs: -- AddDesign2Known: Adds a /datum/design to known_designs. -- IsResearched -- CanResearch -- UnlockTechology -- download_from: Unlocks all technologies from a different /datum/research and syncs experiment data -- forget_techology -- forget_random_technology -- forget_all +- TechHasReqs: Used by other procs (specifically RefreshResearch) to see whether all of a tech's requirements are currently in +known_tech and at a high enough level. +- DesignHasReqs: Same as TechHasReqs but for /datum/design and known_design. +- AddTech2Known: Adds a /datum/tech to known_tech. It checks to see whether it already has that tech (if so, it just replaces it). If +it doesn't have it, it adds it. Note: It does NOT check possible_tech at all. So if you want to add something strange to it (like +a player made tech?) you can. +- AddDesign2Known: Same as AddTech2Known except for /datum/design and known_designs. +- RefreshResearch: This is the workhorse of the R&D system. It updates the /datum/research holder and adds any unlocked tech paths +and designs you have reached the requirements for. It only checks through possible_tech and possible_designs, however, so it won't +accidentally add "secret" tech to it. +- UpdateTech is used as part of the actual researching process. It takes an ID and finds techs with that same ID in known_tech. When +it finds it, it checks to see whether it can improve it at all. If the known_tech's level is less then or equal to +the inputted level, it increases the known tech's level to the inputted level -1 or know tech's level +1 (whichever is higher). The tech datums are the actual "tech trees" that you improve through researching. Each one has five variables: - Name: Pretty obvious. This is often viewable to the players. - Desc: Pretty obvious. Also player viewable. - ID: This is the unique ID of the tech that is used by the various procs to find and/or maniuplate it. -- Level: This is the current level of the tech. Based on the amount of researched technologies -- MaxLevel: Maxium level possible for this tech. Based on the amount of technologies of that tech +- Level: This is the current level of the tech. All techs start at 1 and have a max of 20. Devices and some techs require a certain +level in specific techs before you can produce them. +- Req_tech: This is a list of the techs required to unlock this tech path. If left blank, it'll automatically be loaded into the +research holder datum. */ /*************************************************************** ** Master Types ** ** Includes all the helper procs and basic tech processing. ** ***************************************************************/ -#define RESEARCH_ENGINEERING "engineering" -#define RESEARCH_BIOTECH "biotech" -#define RESEARCH_COMBAT "combat" -#define RESEARCH_DATA "computer" -#define RESEARCH_POWERSTORAGE "powerstorage" -#define RESEARCH_BLUESPACE "bluespace" -#define RESEARCH_ESOTERIC "illegal" -#define RESEARCH_MAGNETS "magnets" //used in robotics -#define RESEARCH_MATERIALS "materials" /datum/research //Holder for all the existing, archived, and known tech. Individual to console. - var/list/known_designs = list() //List of available designs (at base reliability). - var/list/design_by_id = list() - //Increased by each created prototype with formula: reliability += reliability * (RND_RELIABILITY_EXPONENT^created_prototypes) + var/list/known_tech = list() //List of locally known tech. Datum/tech go here. + var/list/possible_designs = list() //List of all designs. + var/list/known_designs = list() //List of available designs. + +/datum/research/New() //Insert techs into possible_tech here. Known_tech automatically updated. + for(var/T in typesof(/datum/tech) - /datum/tech) + known_tech += new T(src) + for(var/D in typesof(/datum/design) - /datum/design) + possible_designs += new D(src) + RefreshResearch() + +/datum/research/techonly + +/datum/research/techonly/New() + for(var/T in typesof(/datum/tech) - /datum/tech) + known_tech += new T(src) + RefreshResearch() + +//Checks to see if design has all the required pre-reqs. +//Input: datum/design; Output: 0/1 (false/true) +/datum/research/proc/DesignHasReqs(datum/design/D) + if(length(D.req_tech) == 0) + return 1 + + var/list/k_tech = list() + + for(var/datum/tech/known in known_tech) + k_tech[known.id] = known.level + + for(var/req in D.req_tech) + if(isnull(k_tech[req]) || k_tech[req] < D.req_tech[req]) + return 0 - var/list/design_categories_protolathe = list() - var/list/design_categories_imprinter = list() + return 1 - var/list/datum/tech/tech_trees = list() // associative - var/list/all_technologies = list() // associative - var/list/researched_tech = list() +//Adds a tech to known_tech list. Checks to make sure there aren't duplicates and updates existing tech's levels if needed. +//Input: datum/tech; Output: Null +/datum/research/proc/AddTech2Known(datum/tech/T) + for(var/datum/tech/known in known_tech) + if(T.id == known.id) + if(T.level > known.level) + known.level = T.level + return + return + +/datum/research/proc/AddDesign2Known(datum/design/D) + if(!length(known_designs)) // Special case + known_designs.Add(D) + return + for(var/i = 1 to length(known_designs)) + var/datum/design/A = known_designs[i] + if(A.id == D.id) // We are guaranteed to reach this if the ids are the same, because sort_string will also be the same + return + if(A.sort_string > D.sort_string) + known_designs.Insert(i, D) + return + known_designs.Add(D) + return + +//Refreshes known_tech and known_designs list +//Input/Output: n/a +/datum/research/proc/RefreshResearch() + for(var/datum/design/PD in possible_designs) + if(DesignHasReqs(PD)) + AddDesign2Known(PD) + for(var/datum/tech/T in known_tech) + T = clamp(T.level, 0, 20) + return + +//Refreshes the levels of a given tech. +//Input: Tech's ID and Level; Output: null +/datum/research/proc/UpdateTech(ID, level) + // If a "brain expansion" event is active, we gain 1 extra level + for(var/datum/event/E in SSevent.active_events) + if(istype(E, /datum/event/brain_expansion)) + level += 1 + break + + for(var/datum/tech/KT in known_tech) + if(KT.id == ID && KT.level <= level) + KT.level = max(KT.level + 1, level - 1) + return + +// A simple helper proc to find the name of a tech with a given ID. +/proc/CallTechName(ID) + for(var/T in subtypesof(/datum/tech)) + var/datum/tech/check_tech = T + if(initial(check_tech.id) == ID) + return initial(check_tech.name) + +/*************************************************************** +** Technology Datums ** +** Includes all the various technoliges and what they make. ** +***************************************************************/ - var/datum/experiment_data/experiments - var/research_points = 0 - var/list/uniquekeys = list() -//[/SIERRA-EDIT] - MODPACK_RND +/datum/tech //Datum of individual technologies. + var/name = "name" //Name of the technology. + var/desc = "description" //General description of what it does and what it makes. + var/id = "id" //An easily referenced ID. Must be alphanumeric, lower-case, and no symbols. + var/level = 1 //A simple number scale of the research level. Level 0 = Secret tech. + +/datum/tech/materials + name = "Materials" + desc = "Development of new and improved materials." + id = TECH_MATERIAL + +/datum/tech/engineering + name = "Engineering" + desc = "Development of new and improved engineering parts." + id = TECH_ENGINEERING + +/datum/tech/phorontech + name = "Phoron Technology" + desc = "Manipulation of the mysterious substance colloqually known as 'phoron'." + id = TECH_PHORON + +/datum/tech/powerstorage + name = "Power Manipulation Technology" + desc = "The various technologies behind the storage and generation of electicity." + id = TECH_POWER + +/datum/tech/bluespace + name = "'Blue-space' Technology" + desc = "Devices that utilize the sub-reality known as 'blue-space'" + id = TECH_BLUESPACE + +/datum/tech/biotech + name = "Biological Technology" + desc = "Deeper mysteries of life and organic substances." + id = TECH_BIO + +/datum/tech/combat + name = "Combat Systems" + desc = "Offensive and defensive systems." + id = TECH_COMBAT + +/datum/tech/magnets + name = "Electromagnetic Spectrum Technology" + desc = "Electromagnetic spectrum and magnetic devices. No clue how they actually work, though." + id = TECH_MAGNET + +/datum/tech/programming + name = "Data Theory" + desc = "Computer and artificial intelligence and data storage systems." + id = TECH_DATA + +/datum/tech/esoteric + name = "Esoteric Technology" + desc = "A miscellaneous tech category filled with information on non-standard designs, personal projects and half-baked ideas." + id = TECH_ESOTERIC + level = 0 + +/obj/item/disk/tech_disk + name = "fabricator data disk" + desc = "A disk for storing fabricator learning data for backup." + icon = 'icons/obj/datadisks.dmi' + icon_state = "datadisk2" + item_state = "card-id" + w_class = ITEM_SIZE_SMALL + matter = list(MATERIAL_PLASTIC = 30, MATERIAL_STEEL = 30, MATERIAL_GLASS = 10) + var/datum/tech/stored + + +/obj/item/disk/design_disk + name = "component design disk" + desc = "A disk for storing device design data for construction in lathes." + icon = 'icons/obj/datadisks.dmi' + icon_state = "datadisk2" + item_state = "card-id" + w_class = ITEM_SIZE_SMALL + matter = list(MATERIAL_PLASTIC = 30, MATERIAL_STEEL = 30, MATERIAL_GLASS = 10) + var/datum/design/blueprint + +*/ diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 07ba605ca474b..cc21aed1635eb 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -273,18 +273,18 @@ //[SIERRA-EDIT] - MODPACK_RND if(2) //Data Management menu - dat += "[temp_server.name] Data ManagementP

" - dat += "Known Tech
" - for(var/tech_tree in temp_server.files.tech_trees) - var/datum/tech/T = temp_server.files.tech_trees[tech_tree] + dat += "[temp_server.name] Data Management

" + dat += "Known Tech Trees
" + for(var/datum/tech/T in temp_server.files.researched_tech) dat += "* [T.name] " - dat += "(Reset)
" //FYI, these are all strings. - dat += "Known Technology
" - for(var/D in temp_server.files.researched_tech) - var/datum/technology/T = temp_server.files.researched_tech[D] + dat += "(Reset)
" + dat += "Known Technologies
" + for(var/t in temp_server.files.researched_nodes) + var/datum/technology/T = t dat += "* [T.name] " - dat += "(Delete)
" + dat += "(Delete)
" dat += "
Main Menu" + //[/SIERRA-EDIT] - MODPACK_RND if(3) //Server Data Transfer diff --git a/code/unit_tests/machine_tests.dm b/code/unit_tests/machine_tests.dm index e792b8162332d..839885c3c9b56 100644 --- a/code/unit_tests/machine_tests.dm +++ b/code/unit_tests/machine_tests.dm @@ -67,7 +67,7 @@ /datum/unit_test/fabricator_recipes_shall_be_buildable name = "MACHINE: All fabricators will be able to produce all of their recipes" - +/* /datum/unit_test/fabricator_recipes_shall_be_buildable/start_test() var/failed = list() for(var/thing in typesof(/obj/machinery/fabricator)) @@ -84,3 +84,4 @@ else pass("All fabricators could produce their associated recipes.") return 1 +*/ diff --git a/maps/away/lost_supply_base/lost_supply_base.dmm b/maps/away/lost_supply_base/lost_supply_base.dmm index d99f37a6c5c7a..f2e95e4ca3bd1 100644 --- a/maps/away/lost_supply_base/lost_supply_base.dmm +++ b/maps/away/lost_supply_base/lost_supply_base.dmm @@ -986,7 +986,7 @@ /turf/simulated/wall, /area/lost_supply_base/common) "cw" = ( -/obj/machinery/fabricator/replicator, +///obj/machinery/fabricator/replicator, /turf/simulated/floor/tiled, /area/lost_supply_base/common) "cx" = ( diff --git a/maps/sierra/z1-z5_sierra.dmm b/maps/sierra/z1-z5_sierra.dmm index 49282d93ab42e..d104e2ca914c6 100644 --- a/maps/sierra/z1-z5_sierra.dmm +++ b/maps/sierra/z1-z5_sierra.dmm @@ -38004,7 +38004,7 @@ /area/quartermaster/hangar_stairs) "fAj" = ( /obj/structure/table/woodentable_reinforced/walnut, -/obj/machinery/fabricator/micro/bartender{ +/obj/machinery/fabricator{ pixel_x = 4 }, /obj/structure/noticeboard{ @@ -38586,7 +38586,7 @@ dir = 8 }, /obj/structure/table/standard, -/obj/machinery/fabricator/micro/bartender{ +/obj/machinery/fabricator{ pixel_x = 5; pixel_y = 2 }, @@ -82194,7 +82194,7 @@ /area/crew_quarters/cafe) "mdp" = ( /obj/structure/table/reinforced, -/obj/machinery/fabricator/micro/bartender{ +/obj/machinery/fabricator/{ pixel_x = 9; pixel_y = 7 }, @@ -101941,9 +101941,6 @@ /obj/structure/closet/walllocker{ pixel_x = -28 }, -/obj/machinery/fabricator{ - fab_status_flags = 1 - }, /obj/item/stack/material/steel/fifty{ pixel_x = -5 }, @@ -148992,7 +148989,7 @@ pixel_x = -28 }, /obj/structure/table/marble, -/obj/machinery/fabricator/micro/bartender{ +/obj/machinery/fabricator/{ pixel_x = 4 }, /obj/item/stack/material/glass/ten{ @@ -153604,7 +153601,7 @@ dir = 8 }, /obj/structure/table/woodentable_reinforced/ebony, -/obj/machinery/fabricator/micro/bartender{ +/obj/machinery/fabricator/{ pixel_x = 4 }, /turf/simulated/floor/wood/walnut, diff --git a/maps/sierra/z6_admin.dmm b/maps/sierra/z6_admin.dmm index f0268065f2296..1d0ea01c548ad 100644 --- a/maps/sierra/z6_admin.dmm +++ b/maps/sierra/z6_admin.dmm @@ -2344,7 +2344,6 @@ "aqf" = ( /obj/machinery/fabricator{ desc = "Your typical Autolathe. It appears to have much more options than your regular one, however..."; - fab_status_flags = 1; name = "unlocked autolathe" }, /obj/floor_decal/borderfloorblack{ @@ -10410,7 +10409,7 @@ dir = 9 }, /obj/structure/table/reinforced, -/obj/machinery/fabricator/micro, +/obj/machinery/fabricator, /turf/unsimulated/floor{ icon = 'icons/turf/flooring/tiles.dmi'; icon_state = "white" diff --git a/maps/using.dm b/maps/using.dm index ed1676799a660..365a8a23eccdc 100644 --- a/maps/using.dm +++ b/maps/using.dm @@ -1,5 +1,5 @@ //Easily change which map to build by uncommenting ONE below. -#define DEV_MODE 0 +#define DEV_MODE 1 #if DEV_MODE == 1 #include "../mods/dev_mode/code/dev_map/dev_map.dm" #warn Режим разработчика активен, не забудь выключить! diff --git a/mods/RnD/_RnD.dme b/mods/RnD/_RnD.dme index c53f9809c21e4..3bcfda700fd12 100644 --- a/mods/RnD/_RnD.dme +++ b/mods/RnD/_RnD.dme @@ -2,6 +2,10 @@ #define MODPACK_RND #include "_RnD.dm" +#include "code/_designs.dm" +#include "code/asset.dm" +#include "code/autolathe.dm" +#include "code/designownloader.dm" #include "code/research.dm" #include "code/experiment.dm" #include "code/tech_biotech.dm" @@ -15,8 +19,53 @@ #include "code/binary.dm" #include "code/design.dm" #include "code/camera.dm" +#include "code/SSresearch.dm" #include "code/sciefolder.dm" #include "code/misc.dm" +#include "code/designs_autolathe/designs_arms_ammo.dm" +#include "code/designs_autolathe/designs_cutlery.dm" +#include "code/designs_autolathe/designs_devices_components.dm" +#include "code/designs_autolathe/designs_engineering.dm" +#include "code/designs_autolathe/designs_medical.dm" +#include "code/designs_autolathe/designs_glasses.dm" +#include "code/designs_autolathe/designs_general.dm" #endif +// BEGIN_INTERNALS +// END_INTERNALS +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR +// BEGIN_PREFERENCES +// END_PREFERENCES +// BEGIN_INCLUDE +#include "_RnD.dm" +#include "code\_designs.dm" +#include "code\asset.dm" +#include "code\autolathe.dm" +#include "code\binary.dm" +#include "code\camera.dm" +#include "code\design.dm" +#include "code\designownloader.dm" +#include "code\experiment.dm" +#include "code\misc.dm" +#include "code\research.dm" +#include "code\sciefolder.dm" +#include "code\SSresearch.dm" +#include "code\tech_biotech.dm" +#include "code\tech_combat.dm" +#include "code\tech_data.dm" +#include "code\tech_engineering.dm" +#include "code\tech_illegal.dm" +#include "code\tech_power.dm" +#include "code\tech_robotics.dm" +#include "code\tech_telecom.dm" +#include "code\designs_autolathe\designs_arms_ammo.dm" +#include "code\designs_autolathe\designs_cutlery.dm" +#include "code\designs_autolathe\designs_devices_components.dm" +#include "code\designs_autolathe\designs_engineering.dm" +#include "code\designs_autolathe\designs_general.dm" +#include "code\designs_autolathe\designs_glasses.dm" +#include "code\designs_autolathe\designs_medical.dm" +// END_INCLUDE diff --git a/mods/RnD/code/SSresearch.dm b/mods/RnD/code/SSresearch.dm new file mode 100644 index 0000000000000..516f3fba9368b --- /dev/null +++ b/mods/RnD/code/SSresearch.dm @@ -0,0 +1,114 @@ +/* + Research subsystem. Manages the static part of R&D, aka designs, technology nodes and such. + Does NOT handle tech trees since they're supposed to be instantiated per console, to track user's progress. + It holds instantiated designs, instantiated technologies (nodes) and tech tree types. + It sets research datums' designs and creates a new tree for each datum. +*/ + +SUBSYSTEM_DEF(research) + name = "Research" + flags = SS_NO_FIRE + init_order = SS_INIT_DEFAULT + + var/list/all_designs = list() // All design datums + var/list/starting_designs = list() // List of designs starts_unlocked = TRUE + var/list/statting_technologies = list() // List of technologies that have no cost and no unlock requirements + var/list/list/all_tech_trees = list() // All tech tree typepaths (keys) associated to a list of their tech node instances (list(values)) + var/list/all_tech_nodes = list() // All tech nodes + var/list/design_categories_autolathe = list() + + var/research_initialized = FALSE + + // If a research holder or a design file is created before SS is initialized, put it here and initialize it later. + var/list/design_files_to_init = list() + var/list/research_files_to_init = list() + +/datum/controller/subsystem/research/Initialize() + for(var/R in subtypesof(/datum/design)) + var/datum/design/design = new R + design.AssembleDesignInfo() + if(!design.build_path) + continue + + all_designs += design + if(design.starts_unlocked) + starting_designs += design + + var/datum/computer_file/binary/design/design_file = new + design_file.design = design + design_file.on_design_set() + design.file = design_file + + for(var/T in subtypesof(/datum/tech)) + all_tech_trees[T] = list() + + for(var/T in subtypesof(/datum/technology)) + var/datum/technology/tech = new T + all_tech_nodes += tech + + if(!tech.cost && !length(tech.required_technologies) && !length(tech.required_tech_levels)) + statting_technologies += tech + + if(tech.tech_type in all_tech_trees) + all_tech_trees[tech.tech_type] += tech + else + WARNING("Unknown tech_type '[tech.tech_type]' in technology '[tech.name]'") + + research_initialized = TRUE + for(var/i in research_files_to_init) + initialize_research_datum(i) + // Initialize design files that were created before + for(var/file in design_files_to_init) + initialize_design_file(file) + design_files_to_init = list() + + AddAutolatheCategory() + return ..() + + +/datum/controller/subsystem/research/proc/initialize_design_file(datum/computer_file/binary/design/design_file) + // If designs are already generated, initialized right away. + // If not, add them to the list to be initialized later. + if(research_initialized) + design_file.design = SSresearch.get_design(design_file.design) + design_file.on_design_set() + else + design_files_to_init += design_file + +/datum/controller/subsystem/research/proc/initialize_research_datum(datum/research/R) + if(!research_initialized) + research_files_to_init += R + return + for(var/i in all_tech_trees) + var/datum/tech/T = new i + T.maxlevel = LAZYLEN(all_tech_trees[i]) + R.researched_tech[T] = list() + + for(var/tech in statting_technologies) + R.UnlockTechology(tech, initial = TRUE) + + for(var/design in starting_designs) + R.AddDesign2Known(design) + +/datum/controller/subsystem/research/proc/get_design(id) + for(var/_design in all_designs) + var/datum/design/design = _design + if(design.id == id) + return design + + error("Incorrect design ID or path: [id]") + +/datum/controller/subsystem/research/proc/get_autolathe_design_by_build_path(build_path) + for(var/datum/design/autolathe/design in all_designs) + if("[design.build_path]" == build_path) + return design + + error("Incorrect design ID or path: [build_path]") + +/datum/controller/subsystem/research/proc/AddAutolatheCategory() + for(var/datum/design/autolathe/D in SSresearch.all_designs) + if(D.category in design_categories_autolathe) + continue + if(D.build_type) + if(D.category) + design_categories_autolathe |= D.category diff --git a/mods/RnD/code/_designs.dm b/mods/RnD/code/_designs.dm new file mode 100644 index 0000000000000..a1cf8131e40e2 --- /dev/null +++ b/mods/RnD/code/_designs.dm @@ -0,0 +1,156 @@ +/*************************************************************** +** Design Datums ** +** All the data for building stuff and tracking reliability. ** +***************************************************************/ +/* +For the materials datum, it assumes you need reagents unless specified otherwise. To designate a material that isn't a reagent, +you use one of the material IDs below. These are NOT ids in the usual sense (they aren't defined in the object or part of a datum), +they are simply references used as part of a "has materials?" type proc. They all start with a to denote that they aren't reagents. +The currently supporting non-reagent materials: + +Don't add new keyword/IDs if they are made from an existing one (such as rods which are made from metal). Only add raw materials. + +Design Guidlines +- When adding new designs, check rdreadme.dm to see what kind of things have already been made and where new stuff is needed. +- A single sheet of anything is 2000 units of material. Materials besides metal/glass require help from other jobs (mining for +other types of metals and chemistry for reagents). + +*/ +//Note: More then one of these can be added to a design. +/datum/design //Datum for object designs, used in construction + var/name = null //Name of the created object. If null it will be 'guessed' from build_path if possible. + var/desc = null //Description of the created object. If null it will use group_desc and name where applicable. + var/item_name = null //An item name before it is modified by various name-modifying procs + var/name_category //If set, name is modified into "[name_category] ([item_name])" + var/id = "id" //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols. + var/list/req_tech = list() //IDs of that techs the object originated from and the minimum level requirements. + var/build_type = null //Flag as to what kind machine the design is built in. See defines. + var/list/materials = list() //List of materials. Format: "id" = amount. + var/list/chemicals = list() //List of chemicals. + var/build_path = null //The path of the object that gets created. + var/time = 10 //How many ticks it requires to build + var/list/category = null //Primarily used for Mech Fabricators, but can be used for anything + var/sort_string = "ZZZZZ" //Sorting order + var/starts_unlocked = FALSE //If true does not require any technologies and unlocked from the start + var/shortname = null // Used for naming in RDconsole + var/datum/computer_file/binary/design/file + var/adjust_materials = TRUE //Whether material efficiency applies to this design + var/list/ui_data = new // Additional data for UI use + var/list/autolathe_category = list() //Categories for the autolathe design download software + var/list/access = list() //List of access groups that can use this design + + +/datum/design/New() + ..() + AssembleDesignInfo() + item_name = name + +//These procs are used in subtypes for assigning names and descriptions dynamically +/datum/design/proc/AssembleDesignInfo() + AssembleDesignName() + AssembleDesignDesc() + AssembleDesignId() + AssembleDesignUIData() + + + return + +/datum/design/proc/AssembleDesignName() + if(!name && build_path) //Get name from build path if posible + var/atom/movable/A = build_path + name = initial(A.name) + item_name = name + if(!shortname) + shortname = capitalize(name) + return + +/datum/design/proc/AssembleDesignDesc() + if(desc) + return + if(!desc) //Try to make up a nice description if we don't have one + desc = "Allows for the construction of \a [item_name]." + return + +/datum/design/proc/AssembleFileDesignInfo(atom/temp_atom) + AssembleDesignName() + AssembleDesignDesc() + AssembleDesignId() + +/datum/design/proc/AssembleDesignId() + if(id) + return + id = type + +/datum/design/proc/AssembleDesignUIData() + ui_data = list( + "id" = "[id]", "name" = name, "desc" = desc, "time" = time, + "category" = category, "adjust_materials" = adjust_materials + ) + + if(length(materials)) + var/list/RS = list() + + for(var/material in materials) + var/material/material_datum = SSmaterials.get_material_by_name(material) + RS.Add(list(list("id" = material, "name" = material_datum.display_name, "req" = materials[material]))) + + ui_data["materials"] = RS + + if(length(chemicals)) + var/list/RS = list() + + for(var/datum/reagent/reagent in chemicals) + RS.Add(list(list("id" = reagent, "name" = reagent.name, "req" = chemicals[reagent]))) + + ui_data["chemicals"] = RS + +/datum/design/ui_data() + RETURN_TYPE(/list) + return ui_data +//Returns a new instance of the item for this design +//This is to allow additional initialization to be performed, including possibly additional contructor arguments. +/datum/design/proc/Fabricate(newloc, mat_efficiency, fabricator) + + var/atom/A = new build_path(newloc) + + if(mat_efficiency != 1 && adjust_materials) + for(var/obj/O in A.GetAllContents(includeSelf = TRUE)) + if(length(O.matter)) + for(var/i in O.matter) + O.matter[i] = round(O.matter[i] * mat_efficiency, 0.01) + + + return A + +/datum/design/item + build_type = PROTOLATHE + +// Testing helper +GLOBAL_LIST_INIT(build_path_to_design_datum_path, populate_design_datum_index()) + +/proc/populate_design_datum_index() + RETURN_TYPE(/list) + . = list() + for(var/path in typesof(/datum/design)) + var/datum/design/fake_design = path + if(initial(fake_design.build_path)) + .[initial(fake_design.build_path)] = path + +/datum/design/autolathe/ + build_type = PROTOLATHE // From now on autolathe capable printing protolathe designs + +/datum/design/autolathe/New() + . = ..() + if(!build_path) + return + var/obj/item/A = new src.build_path + materials = A.matter + desc = A.desc + +/datum/design/proc/autolathe_list_category() + for(var/datum/design/autolathe/P in subtypesof(/datum/design/autolathe)) + if(P.category in autolathe_category) + continue + else + autolathe_category += P.category + return autolathe_category diff --git a/mods/RnD/code/asset.dm b/mods/RnD/code/asset.dm new file mode 100644 index 0000000000000..b72211b4bb268 --- /dev/null +++ b/mods/RnD/code/asset.dm @@ -0,0 +1,27 @@ +/datum/asset/simple/design_icons/register() + for(var/D in SSresearch.all_designs) + var/datum/design/design = D + + var/filename = sanitizeFileName("[design.build_path].png") + + var/atom/item = design.build_path + var/icon_file = initial(item.icon) + var/icon_state = initial(item.icon_state) + + // eugh + if (!icon_file) + icon_file = "" + + #ifdef UNIT_TESTS + if(!(icon_state in icon_states(icon_file))) + // stack_trace("design [D] with icon '[icon_file]' missing state '[icon_state]'") + continue + #endif + var/icon/I = icon(icon_file, icon_state, SOUTH) + + assets[filename] = I + ..() + + for(var/D in SSresearch.all_designs) + var/datum/design/design = D + design.ui_data["icon"] = (sanitizeFileName("[design.build_path].png")) diff --git a/mods/RnD/code/autolathe.dm b/mods/RnD/code/autolathe.dm new file mode 100644 index 0000000000000..40154ad0aff1c --- /dev/null +++ b/mods/RnD/code/autolathe.dm @@ -0,0 +1,968 @@ +/client/proc/browse_queue_flush(timeout = 50) + var/job = ++last_asset_job + var/t = 0 + var/timeout_time = timeout + src << browse({""}, "window=asset_cache_browser&file=asset_cache_send_verify.htm") + + while(!completed_asset_jobs["[job]"] && t < timeout_time) // Reception is handled in Topic() + stoplag(1) // Lock up the caller until this is received. + t++ + if (t < timeout_time) + return TRUE + + +//Autolathe defines +#define ERR_OK 0 +#define ERR_NOTFOUND "not found" +#define ERR_NOMATERIAL "no material" +#define ERR_NOREAGENT "no reagent" +#define ERR_NOCOMPAT "not copmatible" +#define ERR_PAUSED "paused" +#define ERR_DISTANT "no users" +#define ERR_STOPPED "lazy user" +#define ERR_SKILL_ISSUE "unskilled user" +//AUTOLATHE +#define SANITIZE_LATHE_COST(n) round(n * mat_efficiency, 0.01) + +/obj/machinery/fabricator + name = "autolathe" + desc = "A general purpose fabricator capable of producing nearly any item you need, provided you have the necessary materials and design disks." + icon = 'mods/RnD/icons/autolathe.dmi' + icon_state = "autolathe" + density = TRUE + anchored = TRUE + layer = BELOW_OBJ_LAYER + use_power = POWER_USE_IDLE + idle_power_usage = 20 + active_power_usage = 2000 + var/base_icon_state + var/build_type = PROTOLATHE + + var/obj/item/stock_parts/computer/hard_drive/portable/disk + + var/list/stored_material = list() + var/obj/item/reagent_containers/glass/container + + var/unfolded + var/show_category + var/list/categories + + var/list/special_actions + + // Used by wires - unused for now + var/disabled = FALSE + var/shocked = FALSE + + var/working = FALSE + var/paused = FALSE + var/error + var/progress = 0 + + var/datum/computer_file/binary/design/current_file + var/list/queue = list() + var/queue_max = 8 + + var/storage_capacity = 0 + var/speed = 1 + var/mat_efficiency = 1 + var/max_quality = 0 + var/fab_status_flags = 0 + var/default_disk // The disk that spawns in autolathe by default + + // Various autolathe functions that can be disabled in subtypes + var/have_disk = TRUE + var/have_reagents = TRUE + var/have_materials = TRUE + var/have_recycling = TRUE + var/have_design_selector = TRUE + + var/list/unsuitable_materials = list() + var/list/suitable_materials //List that limits autolathes to eating mats only in that list. + + var/list/selectively_recycled_types = list() + + var/global/list/error_messages = list( + ERR_NOLICENSE = "Not enough license points left.", + ERR_NOTFOUND = "Design data not found.", + ERR_NOMATERIAL = "Not enough materials.", + ERR_NOREAGENT = "Not enough reagents.", + ERR_PAUSED = "**Construction Paused**", + ERR_NOCOMPAT = "Design is not copmatible.", + ERR_NOODDITY = "Catalyst not found.", + ERR_DISTANT = "User too far to operate machine.", + ERR_STOPPED = "User stopped operating machine.", + ERR_SKILL_ISSUE = "User cannot produce this design." + ) + + var/list/saved_designs = list() + + wires = /datum/wires/fabricator + base_type = /obj/machinery/fabricator + construct_state = /singleton/machine_construction/default/panel_closed + uncreated_component_parts = list( + /obj/item/stock_parts/matter_bin, + /obj/item/stock_parts/matter_bin, + /obj/item/stock_parts/matter_bin, + /obj/item/stock_parts/manipulator, + + ) + + var/mechfabmod = 1 + +/obj/machinery/fabricator/Initialize() + . = ..() + if(have_disk && default_disk) + disk = new default_disk(src) + + RefreshParts() + update_icon() + +/obj/machinery/fabricator/Destroy() + QDEL_NULL(wires) + return ..() + +/obj/machinery/fabricator/proc/materials_data() + var/list/data = list() + + data["mat_efficiency"] = mat_efficiency + data["mat_capacity"] = storage_capacity + + data["container"] = !!container + if(container && container.reagents) + var/list/L = list() + for(var/datum/reagent/R in container.reagents.reagent_list) + var/list/LE = list("name" = R.name, "amount" = R.volume) + L.Add(list(LE)) + + data["reagents"] = L + + var/list/M = list() + for(var/mtype in stored_material) + if(stored_material[mtype] <= 0) + continue + + var/material/MAT = SSmaterials.get_material_by_name(mtype) + var/list/ME = list("name" = MAT.display_name, "id" = mtype, "amount" = stored_material[mtype], "ejectable" = !!MAT.stack_type) + + M.Add(list(ME)) + + data["materials"] = M + + return data + + +/obj/machinery/fabricator/ui_data(mob/user) + var/list/data = list() + + data["have_disk"] = have_disk + data["have_reagents"] = have_reagents + data["have_materials"] = have_materials + data["have_design_selector"] = have_design_selector + + data["error"] = error + data["paused"] = paused + + data["unfolded"] = unfolded + + data["speed"] = speed + + if(disk) + data["disk"] = list( + "name" = disk.get_disk_name(), + "read_only" = disk.read_only + ) + + if(categories) + data["categories"] = categories + data["show_category"] = show_category + + data["special_actions"] = special_actions + + data |= materials_data() + + var/list/L = list() + for(var/d in design_list()) + var/datum/computer_file/binary/design/design_file = d + if(!show_category || design_file.design.category == show_category) + L.Add(list(design_file.ui_data())) + data["designs"] = L + + + if(current_file) + data["current"] = current_file.ui_data() + data["progress"] = progress + + var/list/Q = list() + + var/list/qmats = stored_material.Copy() + + for(var/i = 1; i <= queue.len; i++) + var/datum/computer_file/binary/design/design_file = queue[i] + var/list/QR = design_file.ui_data() + + QR["ind"] = i + + QR["error"] = 0 + + for(var/rmat in design_file.design.materials) + if(!(rmat in qmats)) + qmats[rmat] = 0 + + qmats[rmat] -= design_file.design.materials[rmat] + if(qmats[rmat] < 0) + QR["error"] = 1 + + if(can_print(design_file) != ERR_OK) + QR["error"] = 2 + + Q.Add(list(QR)) + + data["queue"] = Q + data["queue_max"] = queue_max + + + return data + + +/obj/machinery/fabricator/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + var/list/data = ui_data(user, ui_key) + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "mods-autolathe.tmpl", capitalize(name), 600, 700) + + // template keys starting with _ are not appended to the UI automatically and have to be called manually + ui.add_template("_materials", "mods-autolathe_materials.tmpl") + ui.add_template("_reagents", "mods-autolathe_reagents.tmpl") + ui.add_template("_designs", "mods-autolathe_designs.tmpl") + ui.add_template("_queue", "mods-autolathe_queue.tmpl") + + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + +/obj/machinery/fabricator/use_tool(obj/item/I, mob/living/user, list/click_params) + if(fab_status_flags & FAB_SHOCKED) + shock(user, 50) + return TRUE + if((fab_status_flags & FAB_DISABLED) && !panel_open) + to_chat(user, SPAN_WARNING("\The [src] is disabled!")) + return TRUE + + if(panel_open && (isMultitool(I) || isWirecutter(I))) + attack_hand(user) + return TRUE + if ((. = ..())) + return + if(stat) + to_chat(user, SPAN_WARNING("\The [src] is not operating.")) + return TRUE + if(istype(I, /obj/item/stock_parts/computer/hard_drive/portable)) + insert_disk(user, I) + + // Some item types are consumed by default + if(istype(I, /obj/item/stack) || istype(I, /obj/item/trash) || istype(I, /obj/item/material/shard)) + eat(user, I) + return + + if(istype(I, /obj/item/reagent_containers/glass)) + insert_beaker(user, I) + return + + if(!check_user(user)) + return + + user.set_machine(src) + ui_interact(user) + +/obj/machinery/fabricator/proc/check_user(mob/user) + return TRUE + +/obj/machinery/fabricator/attack_hand(mob/user) + if(..()) + return TRUE + + if(!check_user(user)) + return TRUE + + if(fab_status_flags & FAB_SHOCKED) + shock(user, 50) + return TRUE + + user.set_machine(src) + ui_interact(user) + wires.Interact(user) + +/obj/machinery/fabricator/Topic(href, href_list) + if(..()) + return + + usr.set_machine(src) + + if(href_list["insert"]) + eat(usr) + return 1 + + if(href_list["disk"]) + if(disk) + eject_disk(usr) + else + insert_disk(usr) + return 1 + + if(href_list["container"]) + if(container) + eject_beaker(usr) + else + insert_beaker(usr) + return 1 + + if(href_list["category"] && categories) + var/new_category = text2num(href_list["category"]) + + if(new_category && new_category <= length(categories)) + show_category = categories[new_category] + return 1 + + if(href_list["eject_material"] && (!current_file || paused || error)) + var/material = href_list["eject_material"] + var/material/M = SSmaterials.get_material_by_name(material) + + if(!M.stack_type) + return + + var/num = input("Enter sheets number to eject. 0-[stored_material[material]]","Eject",0) as num + if(!CanUseTopic(usr)) + return + + num = min(max(num,0), stored_material[material]) + + eject(material, num) + return 1 + + + if(href_list["add_to_queue"]) + var/recipe_filename = href_list["add_to_queue"] + var/datum/computer_file/binary/design/design_file + + for(var/f in design_list()) + var/datum/computer_file/temp_file = f + if(temp_file.filename == recipe_filename) + design_file = temp_file + break + + if(design_file) + var/amount = 1 + + if(href_list["several"]) + amount = input("How many \"[design_file.design.name]\" you want to print ?", "Print several") as null|num + if(!CanUseTopic(usr) || !(design_file in design_list())) + return + + queue_design(design_file, amount) + + return 1 + + if(href_list["remove_from_queue"]) + var/ind = text2num(href_list["remove_from_queue"]) + if(ind >= 1 && ind <= queue.len) + queue.Cut(ind, ind + 1) + return 1 + + if(href_list["move_up_queue"]) + var/ind = text2num(href_list["move_up_queue"]) + if(ind >= 2 && ind <= queue.len) + queue.Swap(ind, ind - 1) + return 1 + + if(href_list["move_down_queue"]) + var/ind = text2num(href_list["move_down_queue"]) + if(ind >= 1 && ind <= queue.len-1) + queue.Swap(ind, ind + 1) + return 1 + + + if(href_list["abort_print"]) + abort() + return 1 + + if(href_list["pause"]) + paused = !paused + return 1 + + if(href_list["unfold"]) + if(unfolded == href_list["unfold"]) + unfolded = null + else + unfolded = href_list["unfold"] + return 1 + +/obj/machinery/fabricator/proc/insert_disk(mob/living/user, obj/item/stock_parts/computer/hard_drive/portable/inserted_disk) + if(!inserted_disk && istype(user)) + inserted_disk = user.get_active_hand() + + if(!istype(inserted_disk)) + return + + if(!Adjacent(user) && !Adjacent(inserted_disk)) + return + + if(!have_disk) + to_chat(user, SPAN_WARNING("[src] has no slot for a data disk.")) + return + + if(disk) + to_chat(user, SPAN_NOTICE("There's already \a [disk] inside [src].")) + return + + if(istype(user) && (inserted_disk in user)) + user.unEquip(inserted_disk, src) + + inserted_disk.forceMove(src) + disk = inserted_disk + to_chat(user, SPAN_NOTICE("You insert \the [inserted_disk] into [src].")) + SSnano.update_uis(src) + + +/obj/machinery/fabricator/proc/insert_beaker(mob/living/user, obj/item/reagent_containers/glass/beaker) + if(!beaker && istype(user)) + beaker = user.get_active_hand() + + if(!istype(beaker)) + return + + if(!Adjacent(user) && !Adjacent(beaker)) + return + + if(!have_reagents) + to_chat(user, SPAN_WARNING("[src] has no slot for a beaker.")) + return + + if(container) + to_chat(user, SPAN_WARNING("There's already \a [container] inside [src].")) + return + + if(istype(user) && (beaker in user)) + user.unEquip(beaker, src) + + beaker.forceMove(src) + container = beaker + to_chat(user, SPAN_NOTICE("You put \the [beaker] into [src].")) + SSnano.update_uis(src) + + +/obj/machinery/fabricator/proc/eject_beaker(mob/living/user) + if(!container) + return + + if(current_file && !paused && !error) + return + + container.forceMove(dropInto(loc)) + to_chat(usr, SPAN_NOTICE("You remove \the [container] from \the [src].")) + + if(istype(user) && Adjacent(user)) + user.put_in_active_hand(container) + + container = null + + +//This proc ejects the autolathe disk, but it also does some DRM fuckery to prevent exploits +/obj/machinery/fabricator/proc/eject_disk(mob/living/user) + if(!disk) + return + + var/list/design_list = design_list() + + // Go through the queue and remove any recipes we find which came from this disk + for(var/design in queue) + if(design in design_list) + queue -= design + + //Check the current too + if(current_file in design_list) + //And abort it if it came from this disk + abort() + + + //Digital Rights have been successfully managed. The corporations win again. + //Now they will graciously allow you to eject the disk + disk.forceMove(get_turf(src)) + to_chat(usr, SPAN_NOTICE("You remove \the [disk] from \the [src].")) + disk = null + +/obj/machinery/fabricator/AltClick(mob/living/user) + if(user.incapacitated()) + to_chat(user, SPAN_WARNING("You can't do that right now!")) + return + if(!in_range(src, user)) + return + src.eject_disk(user) + +/obj/machinery/fabricator/proc/eat(mob/living/user, obj/item/eating) + if(!eating && istype(user)) + eating = user.get_active_hand() + + if(!istype(eating)) + return FALSE + + if(stat) + return FALSE + + if(!Adjacent(user) && !Adjacent(eating)) + return FALSE + + if(is_robot_module(eating)) + return FALSE + + if(!have_recycling && !(istype(eating, /obj/item/stack) || can_recycle(eating))) + to_chat(user, SPAN_WARNING("[src] does not support material recycling.")) + return FALSE + + var/filltype = 0 // Used to determine message. + var/reagents_filltype = 0 + var/total_used = 0 // Amount of material used. + + var/list/total_material_gained = list() + + for(var/obj/O in eating.GetAllContents(includeSelf = TRUE)) + var/list/_matter = O.matter + if(_matter) + for(var/material in _matter) + var/total_material = _matter[material] + if(material in unsuitable_materials) + continue + + if(suitable_materials) + if(!(material in suitable_materials)) + continue + + if(!(material in stored_material)) + stored_material[material] = 0 + + if(stored_material[material] + total_material_gained[material] >= storage_capacity) + continue + + if(stored_material[material] + total_material > storage_capacity) + total_material = storage_capacity - stored_material[material] + filltype = 1 + else + filltype = 2 + total_material_gained[material] += total_material + total_used += total_material + +/* It's not used for now, and i think never will be. + if(O.reagents) + if(container) + var/datum/reagents/RG = new(0) + for(var/r in O.reagents) + RG.maximum_volume += O.reagents[r] + RG.add_reagent(r ,O.reagents[r]) + reagents_filltype = 1 + RG.trans_to(container, RG.total_volume) + + else + reagents_filltype = 2 +*/ + if(O.reagents && container) + O.reagents.trans_to(container, O.reagents.total_volume) + + if(!filltype && !reagents_filltype) + to_chat(user, SPAN_NOTICE("\The [src] is full or this thing isn't suitable for this autolathe type. Try remove material from [src] in order to insert more.")) + return + + // Determine what was the main material + var/main_material + var/main_material_amt = 0 + for(var/material in total_material_gained) + stored_material[material] += total_material_gained[material] + if(total_material_gained[material] > main_material_amt) + main_material_amt = total_material_gained[material] + main_material = material + + if(istype(eating, /obj/item/stack/material)) + res_load() + var/obj/item/stack/material/stack = eating + var/used_sheets = min(stack.get_amount(), round(total_used/stack.perunit)) + + to_chat(user, SPAN_NOTICE("You add [used_sheets] [main_material] [stack.singular_name]\s to \the [src].")) + + if(!stack.use(used_sheets)) + qdel(stack) // Protects against weirdness + else + res_load() // Play insertion animation. + to_chat(user, SPAN_NOTICE("You recycle \the [eating] in \the [src].")) + qdel(eating) + + if(reagents_filltype == 1) + to_chat(user, SPAN_NOTICE("Some liquid flowed to \the [container].")) + else if(reagents_filltype == 2) + to_chat(user, SPAN_NOTICE("Some liquid flowed to the floor from \the [src].")) + + +/obj/machinery/fabricator/state_transition(singleton/machine_construction/default/new_state) + . = ..() + if(istype(new_state)) + updateUsrDialog() + +/obj/machinery/fabricator/proc/can_recycle(obj/O) + if(!selectively_recycled_types) + return FALSE + if(!selectively_recycled_types.len) + return FALSE + + for(var/type in selectively_recycled_types) + if(istype(O, type)) + return TRUE + + return FALSE + +/obj/machinery/fabricator/proc/queue_design(datum/computer_file/binary/design/design_file, amount=1) + if(!design_file || !amount) + return + + if(design_file) + design_file = design_file.clone() + + while(amount && queue.len < queue_max) + queue.Add(design_file) + amount-- + + if(!current_file) + next_file() + +/obj/machinery/fabricator/proc/clear_queue() + queue.Cut() + +/obj/machinery/fabricator/proc/check_craftable_amount_by_material(datum/design/design, material) + return stored_material[material] / max(1, SANITIZE_LATHE_COST(design.materials[material])) // loaded material / required material + +/obj/machinery/fabricator/proc/check_craftable_amount_by_chemical(datum/design/design, reagent) + if(!container || !container.reagents) + return 0 + + return container.reagents.get_reagent_amount(reagent) / max(1, design.chemicals[reagent]) + + +////////////////////////////////////////// +//Helper procs for derive possibility +////////////////////////////////////////// +/obj/machinery/fabricator/proc/design_list() + if(!disk) + return saved_designs + + return disk.find_files_by_type(/datum/computer_file/binary/design) + +/obj/machinery/fabricator/proc/icon_off() + if(stat & MACHINE_STAT_NOPOWER) + return TRUE + return FALSE + +/obj/machinery/fabricator/update_icon() + overlays.Cut() + + icon_state = initial(icon_state) + + if(panel_open) + overlays.Add(image(icon, "[icon_state]_panel")) + + if(icon_off()) + return + + if(working) // if paused, work animation looks awkward. + if(paused || error) + icon_state = "[icon_state]_pause" + else + icon_state = "[icon_state]_work" + +//Procs for handling print animation +/obj/machinery/fabricator/proc/print_pre() + flick("[initial(icon_state)]_start", src) + +/obj/machinery/fabricator/proc/print_post() + flick("[initial(icon_state)]_finish", src) + if(!current_file && !queue.len) + playsound(src.loc, 'sound/machines/ping.ogg', 50, 1, -3) + visible_message("\The [src] pings, indicating that queue is complete.") + + +/obj/machinery/fabricator/proc/res_load() + flick("autolathe_load_m", src) + +/obj/machinery/fabricator/components_are_accessible(path) + return !(fab_status_flags & FAB_BUSY) && ..() + +/obj/machinery/fabricator/proc/check_materials(datum/design/design) + mechfabmod = 1 + for(var/rmat in design.materials) + if(!(rmat in stored_material)) + return ERR_NOMATERIAL + + if(stored_material[rmat] < SANITIZE_LATHE_COST(design.materials[rmat])) + return ERR_NOMATERIAL + + if(design.chemicals.len) + if(!container) + return ERR_NOREAGENT + + for(var/rgn in design.chemicals) + if(!container.reagents.has_reagent(rgn, design.chemicals[rgn])) + return ERR_NOREAGENT + + if(design.build_type == MECHFAB) + mechfabmod = 2 + if(!(fab_status_flags & FAB_HACKED)) + return ERR_NOCOMPAT + + return ERR_OK + +/obj/machinery/fabricator/proc/can_print(datum/computer_file/binary/design/design_file) + + if(paused) + return ERR_PAUSED + + if(progress <= 0) + if(!design_file || !design_file.design) + return ERR_NOTFOUND + + var/datum/design/design = design_file.design + var/error_mat = check_materials(design) + if(error_mat != ERR_OK) + return error_mat + + return ERR_OK + + +/obj/machinery/fabricator/power_change() + ..() + if(stat & MACHINE_STAT_NOPOWER) + working = FALSE + update_icon() + SSnano.update_uis(src) + +/obj/machinery/fabricator/Process() + if(stat & MACHINE_STAT_NOPOWER) + return + + if(current_file) + var/err = can_print(current_file) + + if(err == ERR_OK) + error = null + + working = TRUE + progress += speed + + else if(err in error_messages) + error = error_messages[err] + else + error = "Unknown error." + + if(current_file.design && progress >= current_file.design.time * mechfabmod) + finish_construction() + + else + error = null + working = FALSE + next_file() + + update_use_power(working ? POWER_USE_ACTIVE : POWER_USE_IDLE) + + special_process() + update_icon() + SSnano.update_uis(src) + + +/obj/machinery/fabricator/proc/consume_materials(datum/design/design) + for(var/material in design.materials) + var/material_cost = design.adjust_materials ? SANITIZE_LATHE_COST(design.materials[material]) : design.materials[material] + stored_material[material] = max(0, stored_material[material] - material_cost) + + for(var/reagent in design.chemicals) + container.reagents.remove_reagent(reagent, design.chemicals[reagent]) + + return TRUE + + +/obj/machinery/fabricator/proc/next_file() + current_file = null + progress = 0 + if(queue.len) + current_file = queue[1] + print_pre() + working = TRUE + queue.Cut(1, 2) // Cut queue[1] + else + working = FALSE + update_icon() + +/obj/machinery/fabricator/proc/special_process() + return + +/obj/machinery/fabricator/proc/eject(material, amount) + var/recursive = amount == -1 ? 1 : 0 + material = lowertext(material) + var/mattype + switch(material) + if(MATERIAL_STEEL) + mattype = /obj/item/stack/material/steel + if(MATERIAL_PLASTEEL) + mattype = /obj/item/stack/material/plasteel + if(MATERIAL_GLASS) + mattype = /obj/item/stack/material/glass + if(MATERIAL_ALUMINIUM) + mattype = /obj/item/stack/material/aluminium + if(MATERIAL_PLASTIC) + mattype = /obj/item/stack/material/plastic + if(MATERIAL_GOLD) + mattype = /obj/item/stack/material/gold + if(MATERIAL_SILVER) + mattype = /obj/item/stack/material/silver + if(MATERIAL_DIAMOND) + mattype = /obj/item/stack/material/diamond + if(MATERIAL_PHORON) + mattype = /obj/item/stack/material/phoron + if(MATERIAL_URANIUM) + mattype = /obj/item/stack/material/uranium + else + return + var/obj/item/stack/material/S = new mattype(loc) + if(amount <= 0) + amount = S.max_amount + var/ejected = min(round(stored_material[material] / S.perunit), amount) + S.amount = min(ejected, amount) + if(S.amount <= 0) + qdel(S) + return + stored_material[material] -= ejected * S.perunit + if(recursive && stored_material[material] >= S.perunit) + eject(material, -1) + S.update_strings() + S.update_icon() + + +/obj/machinery/fabricator/dismantle() + eject_disk() + for(var/mat in stored_material) + if(ispath(mat, /material)) + var/mat_name = stored_material[mat] + var/material/M = SSmaterials.get_material_by_name(mat_name) + if(stored_material[mat] > M.units_per_sheet) + M.place_sheet(get_turf(src), round(stored_material[mat] / M.units_per_sheet), M.name) + ..() + return TRUE + +//Updates lathe material storage size, production speed and material efficiency. +/obj/machinery/fabricator/RefreshParts() + for(var/a in uncreated_component_parts) + get_component_of_type(a) + var/mb_rating = 0 + var/mb_amount = 0 + for(var/obj/item/stock_parts/matter_bin/MB in component_parts) + mb_rating += MB.rating + mb_amount++ + + if(mb_amount == 0) + return + + var/man_rating = 0 + var/man_amount = 0 + man_rating = total_component_rating_of_type(/obj/item/stock_parts/manipulator) + man_amount = number_of_components(/obj/item/stock_parts/manipulator) + man_rating -= man_amount + max_quality = man_rating + + var/las_rating = 0 + las_rating = total_component_rating_of_type(/obj/item/stock_parts/micro_laser) + + speed = initial(speed) + man_rating + las_rating + mat_efficiency = max(0.2, 1 - (man_rating * 0.1)) + + storage_capacity = 30000 * clamp(total_component_rating_of_type(/obj/item/stock_parts/matter_bin), 0, 20) + ..() + +//Cancels the current construction +/obj/machinery/fabricator/proc/abort() + if(working) + print_post() + current_file = null + paused = TRUE + working = FALSE + update_icon() + +//Finishing current construction +/obj/machinery/fabricator/proc/finish_construction() + fabricate_design(current_file.design) + + +/obj/machinery/fabricator/proc/fabricate_design(datum/design/design) + consume_materials(design) + design.Fabricate(get_turf(loc), mat_efficiency, src) + working = FALSE + current_file = null + print_post() + next_file() + + +/obj/machinery/fabricator/micro + name = "microlathe" + desc = "It produces small items from common resources." + icon = 'icons/obj/machines/fabricators/microlathe.dmi' + icon_state = "minilathe" + base_icon_state = "minilathe" + + idle_power_usage = 10 + active_power_usage = 1000 + machine_name = "microlathe" + machine_desc = "A smaller-sized autolathe, typically used for cutlery, dinnerware, and drinking glasses." + + +/obj/machinery/fabricator/micro/check_materials(datum/design/design) + . = ..() + var/cat = design.category[1] + if(!(cat == "Cutlery" || cat == "Drinking Glasses")) + return ERR_NOCOMPAT + + +/obj/machinery/fabricator/micro/update_icon() + ClearOverlays() + if(panel_open) + AddOverlays("[icon_state]_panel") + if(working) + AddOverlays(emissive_appearance(icon, "[icon_state]_lights_working")) + AddOverlays("[icon_state]_lights_working") + else if(!disabled) + AddOverlays(emissive_appearance(icon, "[icon_state]_lights")) + AddOverlays("[icon_state]_lights") + + +// You (still) can't flick_light overlays in BYOND, and this is a vis_contents hack to provide the same functionality. +// Used for materials loading animation. +/obj/effect/flick_light_overlay + name = "" + icon_state = "" + // Acts like a part of the object it's created for when in vis_contents + // Inherits everything but the icon_state + vis_flags = VIS_INHERIT_ICON | VIS_INHERIT_DIR | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID + +/obj/effect/flick_light_overlay/New(atom/movable/loc) + ..() + // Just VIS_INHERIT_ICON isn't enough: flick_light() needs an actual icon to be set + icon = loc.icon + loc.vis_contents += src + +/obj/effect/flick_light_overlay/Destroy() + if(istype(loc, /atom/movable)) + var/atom/movable/A = loc + A.vis_contents -= src + return ..() + +#undef ERR_OK +#undef ERR_NOTFOUND +#undef ERR_NOMATERIAL +#undef ERR_NOREAGENT +#undef ERR_NOCOMPAT +#undef ERR_PAUSED diff --git a/mods/RnD/code/design.dm b/mods/RnD/code/design.dm index 00ab8ebdf85ed..0381549f9f56c 100644 --- a/mods/RnD/code/design.dm +++ b/mods/RnD/code/design.dm @@ -14,6 +14,12 @@ size += 1 return size +/datum/computer_file/binary/design/proc/on_design_set() + if(design.id == "id") + set_filename(design.name) + else + set_filename(design.id) + /datum/computer_file/binary/design/proc/set_filename(new_name) filename = sanitizeFileName("[new_name]") if(findtext(filename, "datum_design_") == 1) diff --git a/mods/RnD/code/designownloader.dm b/mods/RnD/code/designownloader.dm new file mode 100644 index 0000000000000..c152010463c3d --- /dev/null +++ b/mods/RnD/code/designownloader.dm @@ -0,0 +1,214 @@ +/datum/computer_file/program/ntnetdesign + filename = "dsgndownloader" + filedesc = "Fabricator Design Downloader" + program_icon_state = "generic" + program_key_state = "generic_key" + program_menu_icon = "arrowthickstop-1-s" + extended_desc = "This program allows downloads of desings from official repositories" + size = 6 + processing_size = 0.5 + requires_ntnet = TRUE + requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD + nanomodule_path = /datum/nano_module/program/computer_ntnetdesign + ui_header = "downloader_finished.gif" + var/datum/computer_file/binary/design/downloaded_file = null + var/hacked_download = FALSE + /// GQ of downloaded data. + var/download_completion = 0 + var/download_netspeed = 0 + var/downloaderror = "" + var/list/downloads_queue[0] + /// For logging, can be faked by antags. + var/file_info + var/server + var/selected_autolathe_category + var/show_desc_menu = FALSE + usage_flags = PROGRAM_ALL + size = 6 + available_on_ntnet = TRUE + category = PROG_UTIL + requires_ntnet = TRUE + +/datum/computer_file/program/ntnetdesign/on_shutdown() + ..() + downloaded_file = null + download_completion = 0 + download_netspeed = 0 + downloaderror = "" + ui_header = "downloader_finished.gif" + +/datum/computer_file/program/ntnetdesign/proc/begin_file_download(build_path, skill) + if(downloaded_file) + return FALSE + + var/datum/design/autolathe/design = SSresearch.get_autolathe_design_by_build_path(build_path) + + var/datum/computer_file/binary/design/design_file = design.file + + if(!design_file) + return + + if(!computer || !computer.try_create_file(design_file)) + return + + ui_header = "downloader_running.gif" + + generate_network_log("Began downloading file [file_info] from [server].") + downloaded_file = design_file.clone() + +/datum/computer_file/program/ntnetdesign/proc/hide_file_info(datum/computer_file/file, skill) + server = (file in ntnet_global.available_station_software) ? "NTNet Software Repository" : "unspecified server" + if(!hacked_download) + return "[file.filename].[file.filetype]" + var/stealth_chance = max(skill - SKILL_BASIC, 0) * 30 + if(!prob(stealth_chance)) + return "**ENCRYPTED**.[file.filetype]" + var/datum/computer_file/fake_file = pick(ntnet_global.available_station_software) + server = "NTNet Software Repository" + return "[fake_file.filename].[fake_file.filetype]" + +/datum/computer_file/program/ntnetdesign/proc/abort_file_download() + if(!downloaded_file) + return + generate_network_log("Aborted download of file [file_info].") + downloaded_file = null + download_completion = 0 + ui_header = "downloader_finished.gif" + +/datum/computer_file/program/ntnetdesign/proc/complete_file_download() + if(!downloaded_file) + return + generate_network_log("Completed download of file [file_info].") + if(!computer || !computer.create_file(downloaded_file)) + // The download failed + downloaderror = "I/O ERROR - Unable to save file. Check whether you have enough free space on your hard drive and whether your hard drive is properly connected. If the issue persists contact your system administrator for assistance." + downloaded_file = null + download_completion = 0 + ui_header = "downloader_finished.gif" + +/datum/computer_file/program/ntnetdesign/process_tick() + if(!downloaded_file) + return + if(download_completion >= downloaded_file.size) + complete_file_download() + if(length(downloads_queue) > 0) + begin_file_download(downloads_queue[1], downloads_queue[downloads_queue[1]]) + downloads_queue.Remove(downloads_queue[1]) + + // Download speed according to connectivity state. NTNet server is assumed to be on unlimited speed so we're limited by our local connectivity + download_netspeed = computer.get_ntnet_speed(computer.get_ntnet_status()) + download_completion += download_netspeed + +/datum/computer_file/program/ntnetdesign/Topic(href, href_list) + if(..()) + return TOPIC_HANDLED + if(href_list["PRG_downloadfile"]) + if(!downloaded_file) + begin_file_download(href_list["PRG_downloadfile"], usr.get_skill_value(SKILL_COMPUTER)) + else if(!downloads_queue.Find(href_list["PRG_downloadfile"]) && downloaded_file.filename != href_list["PRG_downloadfile"]) + downloads_queue[href_list["PRG_downloadfile"]] = usr.get_skill_value(SKILL_COMPUTER) + return TOPIC_HANDLED + if(href_list["PRG_removequeued"]) + downloads_queue.Remove(href_list["PRG_removequeued"]) + return TOPIC_HANDLED + if(href_list["PRG_reseterror"]) + if(downloaderror) + download_completion = 0 + download_netspeed = 0 + downloaded_file = null + downloaderror = "" + return TOPIC_HANDLED + if(href_list["select_category"]) + var/what_cat = href_list["select_category"] + selected_autolathe_category = what_cat + return TOPIC_HANDLED + if(href_list["show_desc_menu"]) + show_desc_menu = !show_desc_menu + return TOPIC_HANDLED + return TOPIC_NOACTION + +/datum/nano_module/program/computer_ntnetdesign + name = "Network Downloader" + var/lastusr + +/datum/nano_module/program/computer_ntnetdesign/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, datum/topic_state/state = GLOB.default_state) + var/list/data = list() + var/datum/computer_file/program/ntnetdesign/prog = program + // For now limited to execution by the downloader program + if(!prog || !istype(prog)) + return + if(program) + data = program.get_header_data() + + // This IF cuts on data transferred to client, so i guess it's worth it. + if(prog.downloaderror) // Download errored. Wait until user resets the program. + data["error"] = prog.downloaderror + if(prog.downloaded_file) // Download running. Wait please.. + data["downloadname"] = prog.downloaded_file.filename + //data["downloaddesc"] = prog.downloaded_file.filedesc + data["downloadsize"] = prog.downloaded_file.size + data["downloadspeed"] = prog.download_netspeed + data["downloadcompletion"] = round(prog.download_completion, 0.1) + + data["disk_size"] = program.computer.max_disk_capacity() + data["disk_used"] = program.computer.used_disk_capacity() + data["all_categories"] = get_category() + data["show_desc_menu"] = prog.show_desc_menu + + if((!prog.selected_autolathe_category || !(prog.selected_autolathe_category in data["all_categories"])) && LAZYLEN(SSresearch.design_categories_autolathe)) + prog.selected_autolathe_category = SSresearch.design_categories_autolathe[2] + + if(prog.selected_autolathe_category) + data["selected_category"] = prog.selected_autolathe_category + data["possible_designs"] = get_autolathe_designs_data(prog.selected_autolathe_category) + + var/list/all_entries[0] + data["downloadable_programs"] = all_entries + + if(length(prog.downloads_queue) > 0) + var/list/queue = list() // Nanoui can't iterate through assotiative lists, so we have to do this + for(var/item in prog.downloads_queue) + queue += item + data["downloads_queue"] = queue + + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "mods-ntnetdsgn_downloader.tmpl", "NTNet Download Program", 600, 700, state = state) + ui.auto_update_layout = 1 + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(1) + +/datum/nano_module/program/computer_ntnetdesign/proc/get_category() + var/list/categories = list() + var/list/all_cat = SSresearch.design_categories_autolathe + if(usr) + lastusr = usr + if(!lastusr) + return all_cat + var/mob/living/carbon/human/H = lastusr + var/obj/item/card/id/I = H.GetIdCard() + if(!I) + categories = all_cat - list("Arms and Ammunition") + return categories + if(!(access_security in I.access)) + categories = all_cat - list("Arms and Ammunition") + return categories + return all_cat + +/datum/nano_module/program/computer_ntnetdesign/proc/get_autolathe_designs_data(category) + var/list/designs_list = list() + for(var/datum/design/autolathe/D in SSresearch.all_designs) + if(D.build_type) + var/cat = "Unspecified" + if(D.category) + cat = D.category + if(category in cat) + designs_list += list(list( + "build_path" = D.build_path, + "name" = D.shortname, + "desc" = D.desc, + "size" = D.file.size, + "materials" = D.materials, + )) + return designs_list diff --git a/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm b/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm new file mode 100644 index 0000000000000..8dc744ff068d2 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm @@ -0,0 +1,148 @@ +/datum/design/autolathe/arms_ammo + build_path = /obj/item/syringe_cartridge + category = list("Arms and Ammunition") + access = list(access_security) + +/datum/design/autolathe/arms_ammo/shotgun_holder + build_path = /obj/item/ammo_magazine/shotholder/empty + +/datum/design/autolathe/arms_ammo/shotgun_blanks + name = "ammunition (shotgun blank)" + build_path = /obj/item/ammo_casing/shotgun/blank + +/datum/design/autolathe/arms_ammo/flaregun + name = "flare launcher" + build_path = /obj/item/gun/projectile/flare + +/datum/design/autolathe/arms_ammo/hidden + build_path = /obj/item/material/hatchet/machete/steel + +/datum/design/autolathe/arms_ammo/hidden/shotgun + name = "ammunition (shotgun beanbag)" + build_path = /obj/item/ammo_casing/shotgun/beanbag + +/datum/design/autolathe/arms_ammo/shotgun_flash + name = "ammunition (shotgun flash)" + build_path = /obj/item/ammo_casing/shotgun/flash + +/datum/design/autolathe/arms_ammo/hidden/magazine_smg_rubber + name = "ammunition (SMG rubber) top mounted" + build_path = /obj/item/ammo_magazine/smg_top/rubber + +/datum/design/autolathe/arms_ammo/hidden/flamethrower + build_path = /obj/item/flamethrower/full + +/datum/design/autolathe/arms_ammo/hidden/speedloader + name = "ammunition (speedloader)" + build_path = /obj/item/ammo_magazine/speedloader + +/datum/design/autolathe/arms_ammo/hidden/speedloader_small + name = "ammunition (speedloader holdout)" + build_path = /obj/item/ammo_magazine/speedloader/small + +/datum/design/autolathe/arms_ammo/hidden/speedloader_magnum + name = "ammunition (speedloader magnum)" + build_path = /obj/item/ammo_magazine/speedloader/magnum + +/datum/design/autolathe/arms_ammo/hidden/magazine_pistol + name = "ammunition (pistol)" + build_path = /obj/item/ammo_magazine/pistol + +/datum/design/autolathe/arms_ammo/hidden/magazine_pistol_rubber + name = "ammunition (pistol rubber)" + build_path = /obj/item/ammo_magazine/pistol/rubber + +/datum/design/autolathe/arms_ammo/hidden/magazine_pistol_double + name = "ammunition (pistol doublestack)" + build_path = /obj/item/ammo_magazine/pistol/double + +/datum/design/autolathe/arms_ammo/hidden/magazine_pistol_double_rubber + name = "ammunition (pistol doublestack. rubber)" + build_path = /obj/item/ammo_magazine/pistol/double/rubber + +/datum/design/autolathe/arms_ammo/hidden/magazine_small + name = "ammunition (holdout)" + build_path = /obj/item/ammo_magazine/pistol/small + +/datum/design/autolathe/arms_ammo/hidden/magazine_magnum + name = "ammunition (magnum)" + build_path = /obj/item/ammo_magazine/magnum + +/datum/design/autolathe/arms_ammo/hidden/magazine_smg + name = "ammunition (submachine gun)" + build_path = /obj/item/ammo_magazine/smg + +/datum/design/autolathe/arms_ammo/hidden/magazine_uzi + name = "ammunition (machine pistol)" + build_path = /obj/item/ammo_magazine/machine_pistol + +/datum/design/autolathe/arms_ammo/hidden/magazine_smg_topmounted + name = "ammunition (SMG top mounted)" + build_path = /obj/item/ammo_magazine/smg_top + +/datum/design/autolathe/arms_ammo/hidden/magazine_arifle + name = "ammunition (rifle magazine)" + build_path = /obj/item/ammo_magazine/rifle + +/datum/design/autolathe/arms_ammo/hidden/magazine_bullpupheavy + name = "ammunition (heavy bullpup rifle)" + build_path = /obj/item/ammo_magazine/mil_rifle/heavy + +/datum/design/autolathe/arms_ammo/hidden/magazine_bullpuplight + name = "ammunition (light bullpup rifle)" + build_path = /obj/item/ammo_magazine/mil_rifle/light + +/datum/design/autolathe/arms_ammo/hidden/shotgun + name = "ammunition (slug shotgun)" + build_path = /obj/item/ammo_casing/shotgun + +/datum/design/autolathe/arms_ammo/hidden/shotgun_pellet + name = "ammunition (shell shotgun)" + build_path = /obj/item/ammo_casing/shotgun/pellet + +/datum/design/autolathe/arms_ammo/hidden/tacknife + build_path = /obj/item/material/knife/combat + +/datum/design/autolathe/arms_ammo/hidden/stunshell + name = "ammunition (stun cartridge shotgun)" + build_path = /obj/item/ammo_casing/shotgun/stunshell + +/datum/design/autolathe/arms_ammo/hidden/flechette + name = "ammunition (flechette rifle)" + build_path = /obj/item/magnetic_ammo + +/datum/design/autolathe/arms_ammo/hidden/skrellian_rifle_flechette + name = "ammunition (skrellian rifle flechette)" + build_path = /obj/item/magnetic_ammo/skrell + +/datum/design/autolathe/arms_ammo/hidden/skrellian_rifle_slug + name = "ammunition (skrellian rifle slug)" + build_path = /obj/item/magnetic_ammo/skrell/slug + +/datum/design/autolathe/arms_ammo/hidden/stripperclip + name = "ammunition (rifle stripper clip)" + build_path = /obj/item/ammo_magazine/speedloader/clip + +/datum/design/autolathe/arms_ammo/hidden/pistolstripperclip + name = "ammunition (magnum pistol stripper clip)" + build_path = /obj/item/ammo_magazine/speedloader/pclip + +/datum/design/autolathe/arms_ammo/hidden/broomstickstripperclip + name = "ammunition (holdout pistol stripper clip)" + build_path = /obj/item/ammo_magazine/speedloader/hpclip + +/datum/design/autolathe/arms_ammo/hidden/rifleinternalclip + name = "ammunition (en-bloc clip)" + build_path = /obj/item/ammo_magazine/iclipr + +/datum/design/autolathe/arms_ammo/hidden/beandrum + name = "ammunition (drum magazine beanbag)" + build_path = /obj/item/ammo_magazine/shotgunmag/beanbag + +/datum/design/autolathe/arms_ammo/hidden/nt10mag + name = "ammunition (NT41)" + build_path = /obj/item/ammo_magazine/n10mm + +/datum/design/autolathe/arms_ammo/hidden/shotgun_flechette + name = "ammunition (flechette shotgun)" + build_path = /obj/item/ammo_casing/shotgun/flechette diff --git a/mods/RnD/code/designs_autolathe/designs_cutlery.dm b/mods/RnD/code/designs_autolathe/designs_cutlery.dm new file mode 100644 index 0000000000000..6bf616a09220b --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_cutlery.dm @@ -0,0 +1,40 @@ +/datum/design/autolathe/cutlery + name = "fork aluminium" + build_path = /obj/item/material/utensil/fork + category = list("Cutlery") + +/datum/design/autolathe/cutlery/spoon_aluminium + name = "spoon aluminium" + build_path = /obj/item/material/utensil/spoon + +/datum/design/autolathe/cutlery/spork_aluminium + name = "spork aluminium" + build_path = /obj/item/material/utensil/spork + +/datum/design/autolathe/cutlery/knife_aluminium + name = "table knife aluminium" + build_path = /obj/item/material/utensil/knife + +/datum/design/autolathe/cutlery/foon_aluminium + name = "foon aluminium" + build_path = /obj/item/material/utensil/foon + +/datum/design/autolathe/cutlery/fork_plastic + name = "fork plastic" + build_path = /obj/item/material/utensil/fork/plastic + +/datum/design/autolathe/cutlery/spoon_plastic + name = "spoon plastic" + build_path = /obj/item/material/utensil/spoon/plastic + +/datum/design/autolathe/cutlery/spork_plastic + name = "spork plastic" + build_path = /obj/item/material/utensil/spork/plastic + +/datum/design/autolathe/cutlery/knife_plastic + name = "table knife plastic" + build_path = /obj/item/material/utensil/knife/plastic + +/datum/design/autolathe/cutlery/foon_plastic + name = "foon plastic" + build_path = /obj/item/material/utensil/foon/plastic diff --git a/mods/RnD/code/designs_autolathe/designs_devices_components.dm b/mods/RnD/code/designs_autolathe/designs_devices_components.dm new file mode 100644 index 0000000000000..8e039d6e76691 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_devices_components.dm @@ -0,0 +1,76 @@ +/datum/design/autolathe/device_component + build_path = /obj/item/stock_parts/console_screen + category = list("Devices and Components") + +/datum/design/autolathe/device_component/keyboard + build_path = /obj/item/stock_parts/keyboard + +/datum/design/autolathe/device_component/tesla_component + build_path = /obj/item/stock_parts/power/apc/buildable + +/datum/design/autolathe/device_component/radio_transmitter + build_path = /obj/item/stock_parts/radio/transmitter/basic/buildable + +/datum/design/autolathe/device_component/radio_transmitter_event + build_path = /obj/item/stock_parts/radio/transmitter/on_event/buildable + +/datum/design/autolathe/device_component/radio_receiver + build_path = /obj/item/stock_parts/radio/receiver/buildable + +/datum/design/autolathe/device_component/battery_backup_crap + name = "battery backup (weak)" + build_path = /obj/item/stock_parts/power/battery/buildable/crap + +/datum/design/autolathe/device_component/battery_backup_stock + name = "battery backup (standard)" + build_path = /obj/item/stock_parts/power/battery/buildable/stock + +/datum/design/autolathe/device_component/battery_backup_turbo + name = "battery backup (rapid)" + build_path = /obj/item/stock_parts/power/battery/buildable/turbo + +/datum/design/autolathe/device_component/battery_backup_responsive + name = "battery backup (responsive)" + build_path = /obj/item/stock_parts/power/battery/buildable/responsive + +/datum/design/autolathe/device_component/terminal + build_path = /obj/item/stock_parts/power/terminal/buildable + +/datum/design/autolathe/device_component/igniter + build_path = /obj/item/device/assembly/igniter + +/datum/design/autolathe/device_component/signaler + build_path = /obj/item/device/assembly/signaler + +/datum/design/autolathe/device_component/sensor_infra + build_path = /obj/item/device/assembly/infra + +/datum/design/autolathe/device_component/timer + build_path = /obj/item/device/assembly/timer + +/datum/design/autolathe/device_component/sensor_prox + build_path = /obj/item/device/assembly/prox_sensor + +/datum/design/autolathe/device_component/cable_coil + build_path = /obj/item/stack/cable_coil/single + +/datum/design/autolathe/device_component/electropack + build_path = /obj/item/device/radio/electropack + +/datum/design/autolathe/device_component/beartrap + build_path = /obj/item/beartrap + +/datum/design/autolathe/device_component/cell_device + build_path = /obj/item/cell/device/standard + +/datum/design/autolathe/device_component/ecigcartridge + build_path = /obj/item/reagent_containers/ecig_cartridge/blank + +/datum/design/autolathe/device_component/conveyor_construct + build_path = /obj/item/conveyor_construct + +/datum/design/autolathe/device_component/conveyor_switch_construct + build_path = /obj/item/conveyor_switch_construct + +/datum/design/autolathe/device_component/conveyor_switch_oneway_construct + build_path = /obj/item/conveyor_switch_construct/oneway diff --git a/mods/RnD/code/designs_autolathe/designs_engineering.dm b/mods/RnD/code/designs_autolathe/designs_engineering.dm new file mode 100644 index 0000000000000..f1a959a82f263 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_engineering.dm @@ -0,0 +1,27 @@ +/datum/design/autolathe/engineering + build_path = /obj/item/airlock_electronics + category = list("Engineering") + +/datum/design/autolathe/engineering/airalarm + build_path = /obj/item/airalarm_electronics + +/datum/design/autolathe/engineering/firealarm + build_path = /obj/item/firealarm_electronics + +/datum/design/autolathe/engineering/intercom + build_path = /obj/item/intercom_electronics + +/datum/design/autolathe/engineering/powermodule + build_path = /obj/item/module/power_control + +/datum/design/autolathe/engineering/rcd_ammo + build_path = /obj/item/rcd_ammo + +/datum/design/autolathe/engineering/rcd_ammo_large + build_path = /obj/item/rcd_ammo/large + +/datum/design/autolathe/engineering/camera_assembly + build_path = /obj/item/camera_assembly + +/datum/design/autolathe/engineering/transfer_valve + build_path = /obj/item/device/transfer_valve diff --git a/mods/RnD/code/designs_autolathe/designs_general.dm b/mods/RnD/code/designs_autolathe/designs_general.dm new file mode 100644 index 0000000000000..910649af65b88 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_general.dm @@ -0,0 +1,121 @@ +/datum/design/autolathe/general + build_path = /obj/item/reagent_containers/glass/bucket + category = list("General") + +/datum/design/autolathe/general/flashlight + build_path = /obj/item/device/flashlight + +/datum/design/autolathe/general/floor_light + build_path = /obj/machinery/floor_light + +/datum/design/autolathe/general/extinguisher + build_path = /obj/item/extinguisher/empty + +/datum/design/autolathe/general/extinguisher/mini + build_path = /obj/item/extinguisher/mini/empty + +/datum/design/autolathe/general/jar + build_path = /obj/item/glass_jar + +/datum/design/autolathe/general/radio_headset + build_path = /obj/item/device/radio/headset + +/datum/design/autolathe/general/radio_bounced + build_path = /obj/item/device/radio/off + +/datum/design/autolathe/general/suit_cooler + build_path = /obj/item/device/suit_cooling_unit + +/datum/design/autolathe/general/weldermask + build_path = /obj/item/clothing/head/welding + +/datum/design/autolathe/general/knife + build_path = /obj/item/material/knife/kitchen + +/datum/design/autolathe/general/taperecorder + build_path = /obj/item/device/taperecorder/empty + +/datum/design/autolathe/general/tape + build_path = /obj/item/device/tape + +/datum/design/autolathe/general/tube/large/warm + build_path = /obj/item/light/tube/large/warm + +/datum/design/autolathe/general/tube/large/cool + build_path = /obj/item/light/tube/large/cool + +/datum/design/autolathe/general/tube/large/white + build_path = /obj/item/light/tube/large/white + +/datum/design/autolathe/general/tube/warm + build_path = /obj/item/light/tube/warm + +/datum/design/autolathe/general/tube/cool + build_path = /obj/item/light/tube/cool + +/datum/design/autolathe/general/tube/white + build_path = /obj/item/light/tube/white + +/datum/design/autolathe/general/bulb/warm + build_path = /obj/item/light/bulb/warm + +/datum/design/autolathe/general/bulb/cool + build_path = /obj/item/light/bulb/cool + +/datum/design/autolathe/general/bulb/white + build_path = /obj/item/light/bulb/white + +/datum/design/autolathe/general/ashtray_glass + build_path = /obj/item/material/ashtray/glass + +/datum/design/autolathe/general/weldinggoggles + build_path = /obj/item/clothing/glasses/welding + +/datum/design/autolathe/general/blackpen + build_path = /obj/item/pen + +/datum/design/autolathe/general/bluepen + build_path = /obj/item/pen/blue + +/datum/design/autolathe/general/redpen + build_path = /obj/item/pen/red + +/datum/design/autolathe/general/greenpen + build_path = /obj/item/pen/green + +/datum/design/autolathe/general/clipboard_steel + name = "clipboard, steel" + build_path = /obj/item/material/clipboard/steel + +/datum/design/autolathe/general/clipboard_alum + name = "clipboard, aluminium" + build_path = /obj/item/material/clipboard/aluminium + +/datum/design/autolathe/general/clipboard_glass + name = "clipboard, glass" + build_path = /obj/item/material/clipboard/glass + +/datum/design/autolathe/general/clipboard_alum + name = "clipboard, plastic" + build_path = /obj/item/material/clipboard/plastic + +/datum/design/autolathe/general/destTagger + build_path = /obj/item/device/destTagger + +/datum/design/autolathe/general/labeler + build_path = /obj/item/hand_labeler + +/datum/design/autolathe/general/handcuffs + build_path = /obj/item/handcuffs + +/datum/design/autolathe/general/plunger + build_path = /obj/item/clothing/mask/plunger + +/datum/design/autolathe/general/toolbox + build_path = /obj/item/storage/toolbox + +/datum/design/autolathe/general/binoculars + build_path = /obj/item/device/binoculars + +/datum/design/autolathe/general/tape_roll + build_path = /obj/item/tape_roll diff --git a/mods/RnD/code/designs_autolathe/designs_glasses.dm b/mods/RnD/code/designs_autolathe/designs_glasses.dm new file mode 100644 index 0000000000000..75903e14ca847 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_glasses.dm @@ -0,0 +1,42 @@ +/datum/design/autolathe/drinkingglass + build_path = /obj/item/reagent_containers/food/drinks/glass2/square + category = list("Drinking Glasses") + +/datum/design/autolathe/drinkingglass/rocks + build_path = /obj/item/reagent_containers/food/drinks/glass2/rocks + +/datum/design/autolathe/drinkingglass/shake + build_path = /obj/item/reagent_containers/food/drinks/glass2/shake + +/datum/design/autolathe/drinkingglass/cocktail + build_path = /obj/item/reagent_containers/food/drinks/glass2/cocktail + +/datum/design/autolathe/drinkingglass/shot + build_path = /obj/item/reagent_containers/food/drinks/glass2/shot + +/datum/design/autolathe/drinkingglass/pint + build_path = /obj/item/reagent_containers/food/drinks/glass2/pint + +/datum/design/autolathe/drinkingglass/mug + build_path = /obj/item/reagent_containers/food/drinks/glass2/mug + +/datum/design/autolathe/drinkingglass/wine + build_path = /obj/item/reagent_containers/food/drinks/glass2/wine + +/datum/design/autolathe/drinkingglass/carafe + build_path = /obj/item/reagent_containers/food/drinks/glass2/carafe + +/datum/design/autolathe/drinkingglass/flute + build_path = /obj/item/reagent_containers/food/drinks/glass2/flute + +/datum/design/autolathe/drinkingglass/coffeecup + build_path = /obj/item/reagent_containers/food/drinks/glass2/coffeecup + +/datum/design/autolathe/drinkingglass/cognac + build_path = /obj/item/reagent_containers/food/drinks/glass2/cognac + +/datum/design/autolathe/drinkingglass/goblet + build_path = /obj/item/reagent_containers/food/drinks/glass2/goblet + +/datum/design/autolathe/drinkingglass/coffeecup/glass + build_path = /obj/item/reagent_containers/food/drinks/glass2/coffeecup/glass diff --git a/mods/RnD/code/designs_autolathe/designs_medical.dm b/mods/RnD/code/designs_autolathe/designs_medical.dm new file mode 100644 index 0000000000000..d44496c84c014 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_medical.dm @@ -0,0 +1,51 @@ +/datum/design/autolathe/medical + category = list("Medical") + +/datum/design/autolathe/medical/circularsaw + build_path = /obj/item/circular_saw + +/datum/design/autolathe/medical/surgicaldrill + build_path = /obj/item/surgicaldrill + +/datum/design/autolathe/medical/retractor + build_path = /obj/item/retractor + +/datum/design/autolathe/medical/dropper + build_path = /obj/item/reagent_containers/dropper + +/datum/design/autolathe/medical/cautery + build_path = /obj/item/cautery + +/datum/design/autolathe/medical/hemostat + build_path = /obj/item/hemostat + +/datum/design/autolathe/medical/beaker + build_path = /obj/item/reagent_containers/glass/beaker + +/datum/design/autolathe/medical/beaker_large + build_path = /obj/item/reagent_containers/glass/beaker/large + +/datum/design/autolathe/medical/beaker_insul + build_path = /obj/item/reagent_containers/glass/beaker/insulated + +/datum/design/autolathe/medical/beaker_insul_large + build_path = /obj/item/reagent_containers/glass/beaker/insulated/large + +/datum/design/autolathe/medical/vial + build_path = /obj/item/reagent_containers/glass/beaker/vial + +/datum/design/autolathe/medical/syringe + build_path = /obj/item/reagent_containers/syringe + +/* [SIERRA-REMOVE] Имплантер теперь в протолате +/datum/design/autolathe/medical/implanter + build_path = /obj/item/implanter +*/ +/datum/design/autolathe/medical/pill_bottle + build_path = /obj/item/storage/pill_bottle + +/datum/design/autolathe/medical/hypospray/autoinjector + build_path = /obj/item/reagent_containers/hypospray/autoinjector + +/datum/design/autolathe/medical/scalpel + build_path = /obj/item/scalpel/basic diff --git a/mods/RnD/code/designs_autolathe/designs_tools.dm b/mods/RnD/code/designs_autolathe/designs_tools.dm new file mode 100644 index 0000000000000..96a14249bed89 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/designs_tools.dm @@ -0,0 +1,49 @@ +/datum/design/autolathe/tool + build_path = /obj/item/crowbar + category = list("Tools") + +/datum/design/autolathe/tool/prybar + build_path = /obj/item/crowbar/prybar + +/datum/design/autolathe/tool/rescuetool + build_path = /obj/item/crowbar/emergency_forcing_tool + +/datum/design/autolathe/tool/int_wirer + build_path = /obj/item/device/integrated_electronics/wirer + +/datum/design/autolathe/tool/int_debugger + build_path = /obj/item/device/integrated_electronics/debugger + +/datum/design/autolathe/tool/int_analyzer + build_path = /obj/item/device/integrated_electronics/analyzer + +/datum/design/autolathe/tool/multitool + build_path = /obj/item/device/multitool + +/datum/design/autolathe/tool/t_scanner + build_path = /obj/item/device/t_scanner + +/datum/design/autolathe/tool/weldertool + build_path = /obj/item/weldingtool + +/datum/design/autolathe/tool/screwdriver + build_path = /obj/item/screwdriver + +/datum/design/autolathe/tool/wirecutters + build_path = /obj/item/wirecutters + +/datum/design/autolathe/tool/wrench + build_path = /obj/item/wrench + +/datum/design/autolathe/tool/hatchet + build_path = /obj/item/material/hatchet + +/datum/design/autolathe/tool/minihoe + build_path = /obj/item/material/minihoe + +/datum/design/autolathe/tool/welder_industrial + build_path = /obj/item/weldingtool/largetank + hidden = TRUE + +/datum/design/autolathe/tool/designator + build_path = /obj/item/device/drone_designator diff --git a/mods/RnD/code/research.dm b/mods/RnD/code/research.dm index 08ebe8c1f65e1..e4b24a4405f6b 100644 --- a/mods/RnD/code/research.dm +++ b/mods/RnD/code/research.dm @@ -1,108 +1,151 @@ - +/* +General Explination: +The research datum is the "folder" where all the research information is stored in a R&D console. It's also a holder for all the +various procs used to manipulate it. It has four variables and seven procs: + +Variables: +- tech_trees is a list of all /datum/tech that can potentially be researched by the player. +- all_designs is a list of all /datum/technology that can potentially be researched by the player. +- researched_tech contains all researched technologies +- known_designs contains all researched /datum/design. +- experiments contains data related to earning research points, more info in experiment.dm +- research_points is an amount of points that can be spend on researching technologies +- design_categories_protolathe stores all unlocked categories for protolathe designs +- design_categories_imprinter stores all unlocked categories for circuit imprinter designs + +Procs: +- AddDesign2Known: Adds a /datum/design to known_designs. +- IsResearched +- CanResearch +- UnlockTechology +- download_from: Unlocks all technologies from a different /datum/research and syncs experiment data +- forget_techology +- forget_random_technology +- forget_all + +The tech datums are the actual "tech trees" that you improve through researching. Each one has five variables: +- Name: Pretty obvious. This is often viewable to the players. +- Desc: Pretty obvious. Also player viewable. +- ID: This is the unique ID of the tech that is used by the various procs to find and/or maniuplate it. +- Level: This is the current level of the tech. Based on the amount of researched technologies +- MaxLevel: Maxium level possible for this tech. Based on the amount of technologies of that tech + +*/ +/*************************************************************** +** Master Types ** +** Includes all the helper procs and basic tech processing. ** +***************************************************************/ +#define RESEARCH_ENGINEERING /datum/tech/engineering +#define RESEARCH_BIOTECH /datum/tech/biotech +#define RESEARCH_COMBAT /datum/tech/combat +#define RESEARCH_DATA /datum/tech/programming +#define RESEARCH_POWERSTORAGE /datum/tech/powerstorage +#define RESEARCH_BLUESPACE /datum/tech/bluespace +#define RESEARCH_ESOTERIC /datum/tech/esoteric +#define RESEARCH_MAGNETS /datum/tech/magnets +#define RESEARCH_MATERIALS /datum/tech/materials + +GLOBAL_VAR_INIT(research_point_gained, 0) +GLOBAL_VAR_INIT(score_research_point_gained, 0) var/global/list/RDcomputer_list = list() var/global/list/explosion_watcher_list = list() -/datum/research/New() - for(var/D in subtypesof(/datum/design)) - var/datum/design/d = new D(src) - design_by_id[d.id] = d - var/datum/computer_file/binary/design/design_file = new - design_file.design = d - design_file.set_filename(d.shortname) - d.file = design_file - d.file.setsize(d) - - for(var/T in subtypesof(/datum/tech)) - var/datum/tech/Tech_Tree = new T - tech_trees[Tech_Tree.id] = Tech_Tree - all_technologies[Tech_Tree.id] = list() - - for(var/T in subtypesof(/datum/technology)) - var/datum/technology/Tech = new T - if(all_technologies[Tech.tech_type]) - all_technologies[Tech.tech_type][Tech.id] = Tech - else - WARNING("Unknown tech_type '[Tech.tech_type]' in technology '[Tech.name]'") - - for(var/tech_tree_id in tech_trees) - var/datum/tech/Tech_Tree = tech_trees[tech_tree_id] - Tech_Tree.maxlevel = length(all_technologies[tech_tree_id]) - - for(var/design_id in design_by_id) - var/datum/design/D = design_by_id[design_id] - if(D.starts_unlocked) - AddDesign2Known(D) +/datum/research //Holder for all the existing, archived, and known tech. Individual to console. + var/list/known_designs = list() //List of available designs (at base reliability). + //Increased by each created prototype with formula: reliability += reliability * (RND_RELIABILITY_EXPONENT^created_prototypes) + var/list/design_categories_protolathe = list() + var/list/design_categories_imprinter = list() + + var/list/researched_tech = list() // Tree = list(of_researched_tech) + var/list/researched_nodes = list() // All research nodes + + var/datum/experiment_data/experiments + var/research_points = 0 + var/list/uniquekeys = list() + var/known_research_file_ids = list() + +/datum/research/New() + ..() + SSresearch.initialize_research_datum(src) experiments = new /datum/experiment_data() // This is a science station. Most tech is already at least somewhat known. experiments.init_known_tech() /datum/research/proc/IsResearched(datum/technology/T) - return !!researched_tech[T.id] + return (T in researched_nodes) /datum/research/proc/CanResearch(datum/technology/T) if(T.cost > research_points) return FALSE + var/datum/tech/mytree = locate(T.tech_type) in researched_tech + if(!mytree || !mytree.shown) // invalid tech_type or hidden tree, no bypassing safeties! + return - for(var/t in T.required_tech_levels) - var/datum/tech/Tech_Tree = tech_trees[t] - var/level = T.required_tech_levels[t] + for(var/tree in T.required_tech_levels) + var/datum/tech/tech_tree = locate(tree) in researched_tech + var/level = T.required_tech_levels[tree] - if(Tech_Tree.level < level) + if(tech_tree.level < level) return FALSE - for(var/t in T.required_technologies) - var/datum/technology/OTech = all_technologies[T.tech_type][t] - - if(!IsResearched(OTech)) + for(var/tech in T.required_technologies) + var/datum/technology/tech_node = locate(tech) in SSresearch.all_tech_nodes + if(!IsResearched(tech_node)) return FALSE return TRUE -/datum/research/proc/UnlockTechology(datum/technology/T, force = FALSE) +/datum/research/proc/UnlockTechology(datum/technology/T, force = FALSE, initial = FALSE) if(IsResearched(T)) - return + return FALSE if(!CanResearch(T) && !force) - return - - researched_tech[T.id] = T + return FALSE + researched_nodes += T + var/datum/tech/tree = locate(T.tech_type) in researched_tech + researched_tech[tree] += T if(!force) - research_points -= T.cost - tech_trees[T.tech_type].level += 1 - - for(var/t in T.unlocks_designs) - var/datum/design/D = design_by_id[t] - - AddDesign2Known(D) + adjust_research_points(-T.cost) + if(initial) // Initial technologies don't add levels + tree.maxlevel -= 1 + else + tree.level += 1 -/datum/research/proc/download_from(datum/research/O) - - for(var/tech_tree_id in O.tech_trees) - var/datum/tech/Tech_Tree = O.tech_trees[tech_tree_id] - var/datum/tech/Our_Tech_Tree = tech_trees[tech_tree_id] + for(var/id in T.unlocks_designs) + AddDesign2Known(SSresearch.get_design(id)) - if(Tech_Tree.shown) - Our_Tech_Tree.shown = Tech_Tree.shown + return TRUE - for(var/tech_id in O.researched_tech) - var/datum/technology/T = O.researched_tech[tech_id] - UnlockTechology(T, force = TRUE) +/datum/research/proc/download_from(datum/research/O) + for(var/t in O.researched_tech) + var/datum/tech/tree = t + var/datum/tech/our_tree = locate(tree.type) in researched_tech + + if(tree.shown && !our_tree.shown) + our_tree.shown = tree.shown + . = TRUE // we actually updated something + + for(var/tech in O.researched_tech[t]) + var/datum/technology/T = tech + if(UnlockTechology(T, force = TRUE)) + . = TRUE // we actually updated something + known_research_file_ids |= O.known_research_file_ids experiments.merge_with(O.experiments) /datum/research/proc/forget_techology(datum/technology/T) if(!IsResearched(T)) return - var/datum/tech/Tech_Tree = tech_trees[T.tech_type] - if(!Tech_Tree) + var/datum/tech/tree = locate(T.tech_type) in researched_tech + if(!tree) return - Tech_Tree.level -= 1 - researched_tech -= T.id + tree.level -= 1 + researched_tech[tree] -= T + researched_nodes -= T - for(var/t in T.unlocks_designs) - var/datum/design/D = design_by_id[t] + for(var/D in T.unlocks_designs) known_designs -= D /datum/research/proc/forget_random_technology() @@ -113,18 +156,15 @@ var/global/list/explosion_watcher_list = list() forget_techology(T) /datum/research/proc/forget_all(tech_type) - var/datum/tech/Tech_Tree = tech_trees[tech_type] - if(!Tech_Tree) + var/datum/tech/tree = locate(tech_type) in researched_tech + if(!tree) return - Tech_Tree.level = 1 - for(var/tech_id in researched_tech) - var/datum/technology/T = researched_tech[tech_id] - if(T.tech_type == tech_type) - researched_tech -= tech_id - - for(var/t in T.unlocks_designs) - var/datum/design/D = design_by_id[t] - known_designs -= D + tree.level = 1 + researched_nodes -= researched_tech[tree] // Remove all the nodes of the tree from the general researched nodes list + for(var/tech in researched_tech[tree]) + var/datum/technology/T = tech + for(var/D in T.unlocks_designs) + known_designs -= D /datum/research/proc/AddDesign2Known(datum/design/D) if(D in known_designs) @@ -150,19 +190,44 @@ var/global/list/explosion_watcher_list = list() // Unlocks hidden tech trees /datum/research/proc/check_item_for_tech(obj/item/I) - if(!LAZYLEN(I.origin_tech)) + var/list/temp_tech = I.origin_tech + if(!temp_tech.len) return - for(var/tech_tree_id in tech_trees) - var/datum/tech/T = tech_trees[tech_tree_id] + for(var/tree in researched_tech) + var/datum/tech/T = tree if(T.shown || !T.item_tech_req) continue - for(var/item_tech in I.origin_tech) + for(var/item_tech in temp_tech) if(item_tech == T.item_tech_req) T.shown = TRUE return +/* +/datum/research/proc/is_research_file_type(datum/computer_file/file) + if(istype(file, /datum/computer_file/binary/research_points)) + return TRUE + + return FALSE +/datum/research/proc/can_load_file(datum/computer_file/file) + if(istype(file, /datum/computer_file/binary/research_points)) + var/datum/computer_file/binary/research_points/research_points_file = file + return !(research_points_file.research_id in known_research_file_ids) + + return FALSE + +/datum/research/proc/load_file(datum/computer_file/file) + if(!can_load_file(file)) + return FALSE + + if(istype(file, /datum/computer_file/binary/research_points)) + var/datum/computer_file/binary/research_points/research_points_file = file + known_research_file_ids += research_points_file.research_id + adjust_research_points(research_points_file.size * 1000) + return TRUE +*/ + return FALSE /datum/research/proc/AddSciPoints(datum/computer_file/binary/sci/D) if(D.uniquekey in uniquekeys) @@ -170,6 +235,10 @@ var/global/list/explosion_watcher_list = list() uniquekeys += D.uniquekey return (rand(500, 1000) * D.size) +/datum/research/proc/adjust_research_points(value) + if(value > 0) + GLOB.research_point_gained += value + research_points += value /datum/tech //Datum of individual technologies. var/name = "name" //Name of the technology. @@ -215,13 +284,11 @@ var/global/list/explosion_watcher_list = list() name = "Power Manipulation Technology" shortname = "Power Manipulation" desc = "The various technologies behind the storage and generation of electicity." - id = RESEARCH_POWERSTORAGE /datum/tech/bluespace name = "'Blue-space' Technology" shortname = "Blue-space" desc = "Devices that utilize the sub-reality known as 'blue-space'" - id = RESEARCH_BLUESPACE /datum/tech/biotech name = "Biological Technology" @@ -233,19 +300,16 @@ var/global/list/explosion_watcher_list = list() name = "Robotics" shortname = "Robotics" desc = "The use of magnetic fields to make electrical devices." - id = RESEARCH_MAGNETS /datum/tech/combat name = "Combat Systems" shortname = "Combat" desc = "Offensive and defensive systems." - id = RESEARCH_COMBAT /datum/tech/programming name = "Data Theory" shortname = "Data Theory" desc = "Computer and artificial intelligence and data storage systems." - id = RESEARCH_DATA /datum/tech/esoteric name = "Esoteric Technology" @@ -290,3 +354,11 @@ var/global/list/explosion_watcher_list = list() var/list/required_tech_levels = list() // list("biotech" = 5, ...) Ids and required levels of tech var/cost = 100 // How much research points required to unlock this techology var/list/unlocks_designs = list() // Ids of designs that this technology unlocks + +/datum/technology/proc/getCost() + // Calculates tech disk's supply points sell cost + var/datum/tech/tree = locate(tech_type) in SSresearch.all_tech_trees + if(tree) + return (cost/100)*initial(tree.rare) + else + return cost/100 diff --git a/mods/RnD/code/tech_biotech.dm b/mods/RnD/code/tech_biotech.dm index c5fc3b1332591..0c95bef85f0c1 100644 --- a/mods/RnD/code/tech_biotech.dm +++ b/mods/RnD/code/tech_biotech.dm @@ -19,11 +19,12 @@ desc = "Basic Medical Machines" id = "basic_medical_machines" + x = 0.2 y = 0.5 icon = "operationcomputer" - required_technologies = list("basic_biotech") + required_technologies = list(/datum/technology/bio) required_tech_levels = list() cost = 250 @@ -34,11 +35,12 @@ desc = "Hydroponics" id = "hydroponics" + x = 0.1 y = 0.4 icon = "hydroponics" - required_technologies = list("basic_biotech") + required_technologies = list(/datum/technology/bio) required_tech_levels = list() cost = 500 @@ -49,11 +51,12 @@ desc = "Advanced Hydroponics" id = "adv_hydroponics" + x = 0.1 y = 0.3 icon = "gene" - required_technologies = list("hydroponics") + required_technologies = list(/datum/technology/bio/hydroponics) required_tech_levels = list() cost = 1200 @@ -64,11 +67,12 @@ desc = "Food Processing" id = "food_process" + x = 0.2 y = 0.4 icon = "microwave" - required_technologies = list("hydroponics") + required_technologies = list(/datum/technology/bio/hydroponics) required_tech_levels = list() cost = 500 @@ -79,11 +83,12 @@ desc = "Implants" id = "implants" + x = 0.2 y = 0.6 icon = "implant" - required_technologies = list("basic_medical_machines") + required_technologies = list(/datum/technology/bio/basic_medical_machines) required_tech_levels = list() cost = 1500 @@ -94,11 +99,12 @@ desc = "Advanced Medical Machines" id = "adv_med_machines" + x = 0.3 y = 0.5 icon = "sleeper" - required_technologies = list("basic_medical_machines") + required_technologies = list(/datum/technology/bio/basic_medical_machines) required_tech_levels = list() cost = 1500 @@ -109,11 +115,12 @@ desc = "Additional Medical Tools" id = "add_med_tools" + x = 0.4 y = 0.5 icon = "medhud" - required_technologies = list("adv_med_machines") + required_technologies = list(/datum/technology/bio/adv_med_machines) required_tech_levels = list() cost = 1000 @@ -124,11 +131,12 @@ desc = "Advanced Additional Medical Tools" id = "adv_add_med_tools" + x = 0.6 y = 0.5 icon = "adv_mass_spec" - required_technologies = list("add_med_tools") + required_technologies = list(/datum/technology/bio/add_med_tools) required_tech_levels = list() cost = 1500 @@ -138,13 +146,13 @@ name = "Hypospray" desc = "Hypospray" id = "hypospray" - tech_type = RESEARCH_BIOTECH + x = 0.6 y = 0.4 icon = "hypo" - required_technologies = list("adv_add_med_tools") + required_technologies = list(/datum/technology/bio/add_med_tools) required_tech_levels = list() cost = 2000 @@ -155,11 +163,12 @@ desc = "Incision Management System" id = "scalpelmanager" + x = 0.7 y = 0.5 icon = "scalpelmanager" - required_technologies = list("adv_add_med_tools") + required_technologies = list(/datum/technology/bio/add_med_tools) required_tech_levels = list() cost = 2000 @@ -170,11 +179,12 @@ desc = "Special Beakers" id = "beakers" + x = 0.6 y = 0.6 icon = "blue_beaker" - required_technologies = list("adv_add_med_tools") + required_technologies = list(/datum/technology/bio/add_med_tools) required_tech_levels = list() cost = 2000 diff --git a/mods/RnD/code/tech_combat.dm b/mods/RnD/code/tech_combat.dm index 04e8fc576a700..5f707000f6cd4 100644 --- a/mods/RnD/code/tech_combat.dm +++ b/mods/RnD/code/tech_combat.dm @@ -23,7 +23,7 @@ y = 0.6 icon = "seccomputer" - required_technologies = list("sec_eq") + required_technologies = list(/datum/technology/combat) required_tech_levels = list() cost = 250 @@ -38,7 +38,7 @@ y = 0.5 icon = "add_sec_eq" - required_technologies = list("sec_eq") + required_technologies = list(/datum/technology/combat) required_tech_levels = list() cost = 500 @@ -53,7 +53,7 @@ y = 0.5 icon = "adflash" - required_technologies = list("add_eq") + required_technologies = list(/datum/technology/combat/add_eq) required_tech_levels = list() cost = 750 @@ -68,7 +68,7 @@ y = 0.5 icon = "riotgun" - required_technologies = list("nleth_eq") + required_technologies = list(/datum/technology/combat/nleth_eq) required_tech_levels = list() cost = 1250 @@ -83,7 +83,7 @@ y = 0.4 icon = "decloner" - required_technologies = list("shock") + required_technologies = list(/datum/technology/combat/shock) required_tech_levels = list() cost = 1000 @@ -99,7 +99,7 @@ y = 0.5 icon = "shock" - required_technologies = list("riotgun") + required_technologies = list(/datum/technology/combat/riotgun) required_tech_levels = list() cost = 2500 @@ -114,7 +114,7 @@ y = 0.6 icon = "laser" - required_technologies = list("shock") + required_technologies = list(/datum/technology/combat/shock) required_tech_levels = list() cost = 1500 @@ -129,7 +129,7 @@ y = 0.5 icon = "wt550" - required_technologies = list("shock") + required_technologies = list(/datum/technology/combat/shock) required_tech_levels = list() cost = 1500 @@ -144,7 +144,7 @@ y = 0.6 icon = "smg" - required_technologies = list("wt550") + required_technologies = list(/datum/technology/combat/wt550) required_tech_levels = list() cost = 750 @@ -161,7 +161,7 @@ y = 0.4 icon = "bullpup" - required_technologies = list("wt550") + required_technologies = list(/datum/technology/combat/wt550) required_tech_levels = list() cost = 1500 @@ -177,7 +177,7 @@ y = 0.5 icon = "emiammo" - required_technologies = list("wt550") + required_technologies = list(/datum/technology/combat/wt550) required_tech_levels = list() cost = 3500 diff --git a/mods/RnD/code/tech_data.dm b/mods/RnD/code/tech_data.dm index 0f9613fa0ae28..490c1236df282 100644 --- a/mods/RnD/code/tech_data.dm +++ b/mods/RnD/code/tech_data.dm @@ -23,7 +23,7 @@ y = 0.2 icon = "tablet_frame" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 750 @@ -38,7 +38,7 @@ y = 0.4 icon = "hdd64" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 250 @@ -53,7 +53,7 @@ y = 0.5 icon = "hdd256" - required_technologies = list("ms_hdd") + required_technologies = list(/datum/technology/data/ms_hdd) required_tech_levels = list() cost = 500 @@ -68,7 +68,7 @@ y = 0.6 icon = "hdd512" - required_technologies = list("adv_hdd") + required_technologies = list(/datum/technology/data/adv_hdd) required_tech_levels = list() cost = 750 @@ -83,7 +83,7 @@ y = 0.7 icon = "hdd2048" - required_technologies = list("sup_hdd") + required_technologies = list(/datum/technology/data/sup_hdd) required_tech_levels = list() cost = 1250 @@ -98,7 +98,7 @@ y = 0.4 icon = "netcard_w" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 500 @@ -113,7 +113,7 @@ y = 0.5 icon = "netcard_adv" - required_technologies = list("netcard_w") + required_technologies = list(/datum/technology/data/netcard_w) required_tech_levels = list() cost = 1250 @@ -128,7 +128,7 @@ y = 0.4 icon = "cpu_small" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data/netcard_adv) required_tech_levels = list() cost = 250 @@ -143,7 +143,7 @@ y = 0.5 icon = "pcpu_small" - required_technologies = list("cpu_small") + required_technologies = list(/datum/technology/data/cpu_small) required_tech_levels = list() cost = 500 @@ -158,7 +158,7 @@ y = 0.6 icon = "pcpu" - required_technologies = list("pcpu_small") + required_technologies = list(/datum/technology/data/pcpu_small) required_tech_levels = list() cost = 1200 @@ -173,7 +173,7 @@ y = 0.4 icon = "modular_bat_micro" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 250 @@ -188,7 +188,7 @@ y = 0.5 icon = "modular_bat_advanced" - required_technologies = list("modular_bat_micro") + required_technologies = list(/datum/technology/data/modular_bat_micro) required_tech_levels = list() cost = 500 @@ -203,7 +203,7 @@ y = 0.6 icon = "modular_bat_super" - required_technologies = list("modular_bat_advanced") + required_technologies = list(/datum/technology/data/modular_bat_advanced) required_tech_levels = list() cost = 750 @@ -218,7 +218,7 @@ y = 0.7 icon = "modular_bat_ultra" - required_technologies = list("modular_bat_super") + required_technologies = list(/datum/technology/data/modular_bat_super) required_tech_levels = list() cost = 1250 @@ -233,7 +233,7 @@ y = 0.2 icon = "tesla_link" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 500 @@ -248,7 +248,7 @@ y = 0.2 icon = "nanoprinter" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 500 @@ -263,7 +263,7 @@ y = 0.2 icon = "rfid" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 750 @@ -278,7 +278,7 @@ y = 0.3 icon = "nanoprinter" - required_technologies = list("basic_modular") + required_technologies = list(/datum/technology/data) required_tech_levels = list() cost = 750 @@ -294,7 +294,7 @@ y = 0.6 icon = "aicircuit" - required_technologies = list("pcpu_small") + required_technologies = list(/datum/technology/data/pcpu_small) required_tech_levels = list() cost = 1500 @@ -309,7 +309,7 @@ y = 0.7 icon = "aicircuit" - required_technologies = list("ai_laws") + required_technologies = list(/datum/technology/data/ai_laws) required_tech_levels = list() cost = 1500 diff --git a/mods/RnD/code/tech_engineering.dm b/mods/RnD/code/tech_engineering.dm index 307ed1ce7bbb2..1db34dbf7ead4 100644 --- a/mods/RnD/code/tech_engineering.dm +++ b/mods/RnD/code/tech_engineering.dm @@ -23,7 +23,7 @@ y = 0.6 icon = "spaceheater" - required_technologies = list("monitoring") + required_technologies = list(/datum/technology/engineering/monitoring) required_tech_levels = list() cost = 500 @@ -38,7 +38,7 @@ y = 0.7 icon = "pump" - required_technologies = list("gas_heat") + required_technologies = list(/datum/technology/engineering/gas_heat) required_tech_levels = list() cost = 1000 @@ -53,7 +53,7 @@ y = 0.7 icon = "jetpack" - required_technologies = list("gas_heat") + required_technologies = list(/datum/technology/engineering/gas_heat) required_tech_levels = list() cost = 1500 @@ -68,7 +68,7 @@ y = 0.4 icon = "advmatterbin" - required_technologies = list("monitoring") + required_technologies = list(/datum/technology/engineering/monitoring) required_tech_levels = list() cost = 1000 @@ -83,7 +83,7 @@ y = 0.5 icon = "supermatterbin" - required_technologies = list("adv_eng") + required_technologies = list(/datum/technology/engineering/adv_eng) required_tech_levels = list() cost = 2000 @@ -98,7 +98,7 @@ y = 0.5 icon = "monitoring" - required_technologies = list("basic_engineering") + required_technologies = list(/datum/technology/engineering) required_tech_levels = list() cost = 500 @@ -113,7 +113,7 @@ y = 0.5 icon = "rd" - required_technologies = list("monitoring") + required_technologies = list(/datum/technology/engineering/monitoring) required_tech_levels = list() cost = 750 @@ -129,7 +129,7 @@ y = 0.5 icon = "pickaxe" - required_technologies = list("res_tech") + required_technologies = list(/datum/technology/engineering/res_tech) required_tech_levels = list() cost = 1000 @@ -145,7 +145,7 @@ y = 0.6 icon = "anom" - required_technologies = list("basic_mining") + required_technologies = list(/datum/technology/engineering/basic_mining) required_tech_levels = list() cost = 500 @@ -161,7 +161,7 @@ y = 0.7 icon = "drill" - required_technologies = list("xenoarch") + required_technologies = list(/datum/technology/engineering/xenoarch) required_tech_levels = list() cost = 750 @@ -177,7 +177,7 @@ y = 0.7 icon = "diamond_drill" - required_technologies = list("excavation_drill") + required_technologies = list(/datum/technology/engineering/excavation_drill) required_tech_levels = list() cost = 1250 @@ -193,7 +193,7 @@ y = 0.3 icon = "smelter" - required_technologies = list("basic_mining") + required_technologies = list(/datum/technology/engineering/basic_mining) required_tech_levels = list() cost = 1000 @@ -208,7 +208,7 @@ y = 0.2 icon = "cutter" - required_technologies = list("mining_prod") + required_technologies = list(/datum/technology/engineering/mining_prod) required_tech_levels = list() cost = 1500 @@ -224,7 +224,7 @@ y = 0.4 icon = "nav" - required_technologies = list("basic_mining") + required_technologies = list(/datum/technology/engineering/basic_mining) required_tech_levels = list() cost = 2000 @@ -239,7 +239,7 @@ y = 0.5 icon = "rped" - required_technologies = list("nav") + required_technologies = list(/datum/technology/engineering/ship) required_tech_levels = list() cost = 2000 @@ -254,7 +254,7 @@ y = 0.5 icon = "jawsoflife" - required_technologies = list("adv_eng") + required_technologies = list(/datum/technology/engineering/adv_eng) required_tech_levels = list() cost = 2000 @@ -269,7 +269,7 @@ y = 0.4 icon = "brace" - required_technologies = list("res_tech") + required_technologies = list(/datum/technology/engineering/res_tech) required_tech_levels = list() cost = 1500 @@ -284,7 +284,7 @@ y = 0.3 icon = "icprinter" - required_technologies = list("adv_eng") + required_technologies = list(/datum/technology/engineering/adv_eng) required_tech_levels = list() cost = 750 @@ -299,7 +299,7 @@ y = 0.2 icon = "icupgradv" - required_technologies = list("icprinter") + required_technologies = list(/datum/technology/engineering/icprinter) required_tech_levels = list() cost = 1500 @@ -314,7 +314,7 @@ y = 0.3 icon = "icupclo" - required_technologies = list("icprinter") + required_technologies = list(/datum/technology/engineering/icprinter) required_tech_levels = list() cost = 1000 diff --git a/mods/RnD/code/tech_illegal.dm b/mods/RnD/code/tech_illegal.dm index 7ebc100a278a5..12ae24e11d6bb 100644 --- a/mods/RnD/code/tech_illegal.dm +++ b/mods/RnD/code/tech_illegal.dm @@ -23,7 +23,7 @@ y = 0.6 icon = "kit" - required_technologies = list("radiokey") + required_technologies = list(/datum/technology/esoteric) required_tech_levels = list() cost = 1500 @@ -38,7 +38,7 @@ y = 0.6 icon = "kit" - required_technologies = list("chameleon_kit") + required_technologies = list(/datum/technology/esoteric/chameleon_kit) required_tech_levels = list() cost = 1500 @@ -55,7 +55,7 @@ y = 0.5 icon = "implantcase" - required_technologies = list("radiokey") + required_technologies = list(/datum/technology/esoteric) required_tech_levels = list() cost = 1500 @@ -71,7 +71,7 @@ y = 0.5 icon = "aicircuit" - required_technologies = list("radiokey") + required_technologies = list(/datum/technology/esoteric) required_tech_levels = list() cost = 2000 @@ -86,7 +86,7 @@ y = 0.4 icon = "aicircuit" - required_technologies = list("borg_syndicate_module") + required_technologies = list(/datum/technology/esoteric/borg_syndicate_module) required_tech_levels = list() cost = 1500 @@ -101,7 +101,7 @@ y = 0.6 icon = "implantcase" - required_technologies = list("freedom_implant") + required_technologies = list(/datum/technology/esoteric/freedom_implant) required_tech_levels = list() cost = 1250 @@ -116,7 +116,7 @@ y = 0.4 icon = "hardsuitmodule" - required_technologies = list("radiokey") + required_technologies = list(/datum/technology/esoteric) required_tech_levels = list() cost = 1250 @@ -132,7 +132,7 @@ y = 0.4 icon = "hardsuitmodule" - required_technologies = list("enet") + required_technologies = list(/datum/technology/esoteric/enet) required_tech_levels = list() cost = 2000 diff --git a/mods/RnD/code/tech_power.dm b/mods/RnD/code/tech_power.dm index 230bf3dfb0122..e8af57b9999ba 100644 --- a/mods/RnD/code/tech_power.dm +++ b/mods/RnD/code/tech_power.dm @@ -23,7 +23,7 @@ y = 0.6 icon = "cell" - required_technologies = list("basic_power") + required_technologies = list(/datum/technology/power) required_tech_levels = list() cost = 500 @@ -38,7 +38,7 @@ y = 0.4 icon = "cell" - required_technologies = list("adv_power") + required_technologies = list(/datum/technology/power/adv_power) required_tech_levels = list() cost = 1000 @@ -53,7 +53,7 @@ y = 0.4 icon = "cell" - required_technologies = list("sup_power") + required_technologies = list(/datum/technology/power/sup_power) required_tech_levels = list() cost = 1500 @@ -68,7 +68,7 @@ y = 0.6 icon = "solarcontrol" - required_technologies = list("adv_power") + required_technologies = list(/datum/technology/power/adv_power) required_tech_levels = list() cost = 750 @@ -83,7 +83,7 @@ y = 0.6 icon = "generator" - required_technologies = list("adv_power") + required_technologies = list(/datum/technology/power/adv_power) required_tech_levels = list() cost = 1250 @@ -98,7 +98,7 @@ y = 0.6 icon = "batteryrack" - required_technologies = list("adv_power_gen") + required_technologies = list(/datum/technology/power/adv_power_gen) required_tech_levels = list() cost = 1750 @@ -113,7 +113,7 @@ y = 0.5 icon = "smes" - required_technologies = list("power_storage") + required_technologies = list(/datum/technology/power/power_storage) required_tech_levels = list() cost = 2500 @@ -128,7 +128,7 @@ y = 0.4 icon = "generator" - required_technologies = list("adv_power_gen","sup_power") + required_technologies = list(/datum/technology/power/adv_power_storage, /datum/technology/power/sup_power) required_tech_levels = list() cost = 2000 @@ -143,7 +143,7 @@ y = 0.4 icon = "fusion" - required_technologies = list("sup_power_gen") + required_technologies = list(/datum/technology/power/sup_power_gen) required_tech_levels = list() cost = 2500 diff --git a/mods/RnD/code/tech_robotics.dm b/mods/RnD/code/tech_robotics.dm index 58ea1015b1262..bdacf1edd7fb5 100644 --- a/mods/RnD/code/tech_robotics.dm +++ b/mods/RnD/code/tech_robotics.dm @@ -23,7 +23,7 @@ y = 0.4 icon = "cpu_small" - required_technologies = list("robo") + required_technologies = list(/datum/technology/robo) required_tech_levels = list() cost = 750 @@ -38,7 +38,7 @@ y = 0.4 icon = "circuit" - required_technologies = list("robo") + required_technologies = list(/datum/technology/robo) required_tech_levels = list() cost = 750 @@ -53,7 +53,7 @@ y = 0.4 icon = "mechloader" - required_technologies = list("robo") + required_technologies = list(/datum/technology/robo) required_tech_levels = list() cost = 1000 @@ -68,7 +68,7 @@ y = 0.6 icon = "pcpu_small" - required_technologies = list("basic_augments") + required_technologies = list(/datum/technology/robo/basic_augments) required_tech_levels = list() cost = 2500 @@ -83,7 +83,7 @@ y = 0.6 icon = "hardsuitmodule" - required_technologies = list("basic_hardsuitmods") + required_technologies = list(/datum/technology/robo/basic_hardsuitmods) required_tech_levels = list() cost = 2500 @@ -98,7 +98,7 @@ y = 0.7 icon = "mechheavy" - required_technologies = list("basic_mech") + required_technologies = list(/datum/technology/robo/loader_mech) required_tech_levels = list() cost = 2000 @@ -113,7 +113,7 @@ y = 0.7 icon = "mechlight" - required_technologies = list("basic_mech") + required_technologies = list(/datum/technology/robo/loader_mech) required_tech_levels = list() cost = 1500 @@ -128,7 +128,7 @@ y = 0.7 icon = "mechcombat" - required_technologies = list("basic_mech") + required_technologies = list(/datum/technology/robo/loader_mech) required_tech_levels = list() cost = 2500 @@ -144,7 +144,7 @@ y = 0.4 icon = "mechclaw" - required_technologies = list("basic_mech") + required_technologies = list(/datum/technology/robo/loader_mech) required_tech_levels = list() cost = 500 @@ -159,7 +159,7 @@ y = 0.5 icon = "eva" - required_technologies = list("mech_equipment") + required_technologies = list(/datum/technology/robo/mech_equipment) required_tech_levels = list() cost = 1500 @@ -174,7 +174,7 @@ y = 0.4 icon = "mechlaser" - required_technologies = list("mech_equipment") + required_technologies = list(/datum/technology/robo/mech_equipment) required_tech_levels = list() cost = 1500 @@ -189,7 +189,7 @@ y = 0.3 icon = "mechsleeper" - required_technologies = list("mech_equipment") + required_technologies = list(/datum/technology/robo/mech_equipment) required_tech_levels = list() cost = 500 @@ -204,7 +204,7 @@ y = 0.2 icon = "aicircuit" - required_technologies = list("robo") + required_technologies = list(/datum/technology/robo) required_tech_levels = list() cost = 1000 @@ -219,7 +219,7 @@ y = 0.2 icon = "posibrain" - required_technologies = list("roboupgrade") + required_technologies = list(/datum/technology/robo/roboupgrade) required_tech_levels = list() cost = 1000 @@ -234,7 +234,7 @@ y = 0.2 icon = "ai" - required_technologies = list("robot") + required_technologies = list(/datum/technology/robo/robotconstruction) required_tech_levels = list() cost = 3500 diff --git a/mods/RnD/code/tech_telecom.dm b/mods/RnD/code/tech_telecom.dm index d40f527e658db..5cabfed8e8351 100644 --- a/mods/RnD/code/tech_telecom.dm +++ b/mods/RnD/code/tech_telecom.dm @@ -22,7 +22,7 @@ y = 0.6 icon = "monitoring" - required_technologies = list("telecomm_parts") + required_technologies = list(/datum/technology/tcom/tcom_parts) required_tech_levels = list() cost = 1250 @@ -37,7 +37,7 @@ y = 0.7 icon = "monitoring" - required_technologies = list("tcom_monitoring") + required_technologies = list(/datum/technology/tcom/monitoring) required_tech_levels = list() cost = 1550 @@ -52,7 +52,7 @@ y = 0.6 icon = "relay" - required_technologies = list("telecomm_parts") + required_technologies = list(/datum/technology/tcom/tcom_parts) required_tech_levels = list() cost = 1500 @@ -67,7 +67,7 @@ y = 0.6 icon = "solnet_relay" - required_technologies = list("telecomm_parts") + required_technologies = list(/datum/technology/tcom/tcom_parts) required_tech_levels = list() cost = 1750 @@ -82,7 +82,7 @@ y = 0.6 icon = "subspace" - required_technologies = list("telecomm_parts") + required_technologies = list(/datum/technology/tcom/tcom_parts) required_tech_levels = list() cost = 1500 @@ -97,7 +97,7 @@ y = 0.6 icon = "processor" - required_technologies = list("telecomm_parts") + required_technologies = list(/datum/technology/tcom/tcom_parts) required_tech_levels = list() cost = 1500 @@ -113,7 +113,7 @@ y = 0.5 icon = "telecom_part" - required_technologies = list("track_dev") + required_technologies = list(/datum/technology/tcom) required_tech_levels = list() cost = 750 @@ -128,7 +128,7 @@ y = 0.3 icon = "bscrystal" - required_technologies = list("track_dev") + required_technologies = list(/datum/technology/tcom) required_tech_levels = list() cost = 1000 @@ -144,7 +144,7 @@ y = 0.2 icon = "telepad" - required_technologies = list("crystal") + required_technologies = list(/datum/technology/tcom/arti_blue) required_tech_levels = list() cost = 3000 @@ -160,7 +160,7 @@ y = 0.2 icon = "rd" - required_technologies = list("crystal") + required_technologies = list(/datum/technology/tcom/arti_blue) required_tech_levels = list() cost = 2500 @@ -176,7 +176,7 @@ y = 0.2 icon = "teleport" - required_technologies = list("crystal") + required_technologies = list(/datum/technology/tcom/arti_blue) required_tech_levels = list() cost = 3000 @@ -192,7 +192,7 @@ y = 0.2 icon = "bluespace" - required_technologies = list("crystal") + required_technologies = list(/datum/technology/tcom/arti_blue) required_tech_levels = list() cost = 1800 @@ -207,7 +207,7 @@ y = 0.2 icon = "shieldgen" - required_technologies = list("crystal") + required_technologies = list(/datum/technology/tcom/arti_blue) required_tech_levels = list() cost = 1500 diff --git a/mods/RnD/icons/autolathe.dmi b/mods/RnD/icons/autolathe.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3e611ee98b8d799ada2e99a94cd85dc005fa9600 GIT binary patch literal 38474 zcma%jby$>L_w~>qDM$!ND2NIO2nb3Hq7ot@N`oUQ9nv5(sHCDGB1j2JDIF40L!*Rr z$Iu}SLrs1M^m*Us_r-O6e~1Hf&$;(G_c?p7wfEW+uA`+&e}eM_1OlN~SG%PPfsh7* ze~+js!CyGTdq06+H2oeJdfc*hw|rvf>S5>N41xG0<>|LO=ZG_zH5wSMvGMcVSPRj7 z|NGLbJ@zP;yM=cgt;V@_H>#G_nx~55nXHUXyj|=l>e`Cn{n@^f(kM5AJkx-@OK*BY zH`**IsQ&#>rJ&%?5^>wp&~nV8W%mO~-DoPzS8G+zcAkdR1$#b0^~ThD=mt1^OgJa! z0q^GaqWBjhRiv7Fuk97Sq>pfhH`OE5F}Il}vZtRjuDzC0O4sW3d$r~fJvcCLlb-sn z*!zs9HpL2C#RIz(&t(G199YoNrC7u#aRV<+t_UMBnsr7yi>&M2LP+P+YJGoW{! z?vh*4-C0HC>%{tl&j!pUv#lB4Y`$c+&Ga>K94Sq=$vf$AGU2r1W0#B|@sFd% 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 Du@$dZ literal 0 HcmV?d00001 diff --git a/mods/dev_mode/maps/dev_map.dmm b/mods/dev_mode/maps/dev_map.dmm index 90a4941d74130..02af7adec770e 100644 --- a/mods/dev_mode/maps/dev_map.dmm +++ b/mods/dev_mode/maps/dev_map.dmm @@ -423,6 +423,13 @@ icon_state = "dark" }, /area/tdome/testing) +"beD" = ( +/obj/machinery/computer/rdconsole, +/obj/item/research, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "beU" = ( /obj/structure/flora/ausbushes/ywflowers, /turf/unsimulated/floor/grass, @@ -486,6 +493,12 @@ icon_state = "dark" }, /area/tdome/testing) +"bvm" = ( +/obj/machinery/robotics_fabricator, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "bZN" = ( /obj/floor_decal/corner/paleblue/mono, /turf/unsimulated/floor{ @@ -498,6 +511,21 @@ icon_state = "dark" }, /area/tdome/testing) +"cEM" = ( +/obj/machinery/r_n_d/destructive_analyzer, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) +"cZW" = ( +/obj/item/stock_parts/computer/hard_drive/portable/advanced, +/obj/item/stock_parts/computer/hard_drive/portable/advanced, +/obj/item/stock_parts/computer/hard_drive/portable/advanced, +/obj/item/stock_parts/computer/hard_drive/portable/advanced, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "dhn" = ( /obj/item/gun/projectile/pistol/magnum_pistol, /turf/unsimulated/floor{ @@ -543,6 +571,15 @@ icon_state = "dark" }, /area/tdome/testing) +"eEg" = ( +/obj/item/stack/material/steel/fifty, +/obj/item/stack/material/plastic/fifty, +/obj/item/stack/material/glass/fifty, +/obj/item/stack/material/aluminium/fifty, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "fuz" = ( /obj/item/gun/projectile/pistol/m19/empty, /turf/unsimulated/floor{ @@ -605,6 +642,12 @@ icon_state = "dark" }, /area/tdome/testing) +"iuO" = ( +/obj/machinery/r_n_d/circuit_imprinter, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "iQN" = ( /obj/item/gun/projectile/sniper/garand, /turf/unsimulated/floor{ @@ -657,6 +700,12 @@ icon_state = "dark" }, /area/tdome/testing) +"kwb" = ( +/obj/item/modular_computer/laptop/preset/custom_loadout/advanced, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "kAc" = ( /mob/living/exosuit/premade/random/boring, /turf/unsimulated/floor{ @@ -734,6 +783,12 @@ icon_state = "dark" }, /area/tdome/testing) +"olC" = ( +/obj/machinery/r_n_d/server, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "owp" = ( /mob/living/exosuit/premade/combat, /turf/unsimulated/floor{ @@ -746,6 +801,12 @@ icon_state = "dark" }, /area/tdome/testing) +"oDH" = ( +/obj/machinery/fabricator/micro, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "oPK" = ( /obj/anomaly/electra/three_and_three/preload, /obj/floor_decal/corner/paleblue/mono, @@ -790,6 +851,12 @@ icon_state = "dark" }, /area/tdome/testing) +"rkx" = ( +/obj/machinery/computer/modular/preset/civilian/professional, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "rlX" = ( /obj/structure/table/steel, /obj/item/mech_equipment/drill/diamond, @@ -862,6 +929,12 @@ icon_state = "dark" }, /area/tdome/testing) +"vVv" = ( +/obj/machinery/r_n_d/protolathe, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "wKa" = ( /obj/item/gun/projectile/sniper/semistrip, /turf/unsimulated/floor{ @@ -881,12 +954,24 @@ icon_state = "dark" }, /area/tdome/testing) +"wRk" = ( +/obj/machinery/computer/rdservercontrol, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "xcX" = ( /obj/item/stack/material/steel/fifty, /turf/unsimulated/floor{ icon_state = "dark" }, /area/tdome/testing) +"xKL" = ( +/obj/machinery/fabricator, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) (1,1,1) = {" aab @@ -17355,15 +17440,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +lCd +lCd +lCd +lCd +lCd +lCd +lCd +lCd aab aab aab @@ -17557,15 +17642,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +olC +gqB +gqB +gqB +gqB +gqB +gqB +lCd aab aab aab @@ -17759,15 +17844,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +wRk +gqB +gqB +gqB +gqB +gqB +gqB +lCd aab aab aab @@ -17961,15 +18046,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +gqB +gqB +gqB +gqB +gqB +gqB +gqB +lCd aab aab aab @@ -18163,15 +18248,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +cEM +gqB +gqB +gqB +gqB +gqB +gqB +lCd aab aab aab @@ -18365,15 +18450,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +vVv +gqB +gqB +gqB +gqB +gqB +gqB +lCd aab aab aab @@ -18567,15 +18652,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +beD +gqB +gqB +gqB +gqB +gqB +eEg +lCd aab aab aab @@ -18769,15 +18854,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +iuO +gqB +gqB +gqB +gqB +gqB +bvm +lCd aab aab aab @@ -18971,15 +19056,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +kwb +cZW +gqB +gqB +gqB +gqB +gqB +lCd aab aab aab @@ -19173,15 +19258,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +rkx +gqB +gqB +gqB +gqB +gqB +xKL +lCd aab aab aab @@ -19375,15 +19460,15 @@ aab aab aab aab -aab -aab -aab -aab -aab -aab -aab -aab -aab +lCd +gqB +gqB +gqB +gqB +gqB +gqB +eEg +lCd aab aab aab @@ -19577,12 +19662,14 @@ aab aab aab aab -aab -aab -lCd -lCd -lCd lCd +gqB +gqB +gqB +gqB +gqB +gqB +oDH lCd aab aab @@ -19671,8 +19758,6 @@ aab aab aab aab -aab -aab "} (94,1,1) = {" aab @@ -19780,13 +19865,13 @@ lCd lCd lCd lCd -lCd -lCd gqB gqB gqB -lCd -lCd +gqB +gqB +gqB +gqB lCd lCd lCd diff --git a/mods/utility_items/code/wires.dm b/mods/utility_items/code/wires.dm index d89ce6386eee5..28651415fd8e2 100644 --- a/mods/utility_items/code/wires.dm +++ b/mods/utility_items/code/wires.dm @@ -10,8 +10,8 @@ name_by_type = "APC" if(istype(src, /datum/wires/robot)) name_by_type = "Cyborg" - if(istype(src, /datum/wires/fabricator)) - name_by_type = "Autolathe" + //if(istype(src, /datum/wires/fabricator)) + // name_by_type = "Autolathe" if(istype(src, /datum/wires/alarm)) name_by_type = "Air Alarm" if(istype(src, /datum/wires/camera)) diff --git a/nano/templates/mods/autolathe.tmpl b/nano/templates/mods/autolathe.tmpl new file mode 100644 index 0000000000000..09d5a9dec58ab --- /dev/null +++ b/nano/templates/mods/autolathe.tmpl @@ -0,0 +1,79 @@ + + +
+ +
+ {{if data.have_materials && data.have_reagents}} +
+ {{#def._materials}} +
+
+ {{#def._reagents}} +
+ {{else data.have_materials}} + {{#def._materials}} + {{else data.have_reagents}} + {{#def._reagents}} + {{/if}} +
+ +{{if data.have_disk}} +
+
+
+
+ Disk: + {{if data.disk}} + {{:data.disk.name ? data.disk.name : 'data disk'}} + + {{if data.disk.license > 0}} +
{{:data.disk.license}} license points left
+ {{else data.disk.license == 0}} +
{{:data.disk.license}} license points left
+ {{/if}} + {{else}} + not inserted + {{/if}} +
+
{{:helper.link(data.disk ? 'eject' : 'insert', 'eject', {'disk' : 1}, null, 'statusValue')}}
+
+
+
+{{/if}} + + +{{if data.uses_stat}} +
+
+ With your skills and the current components, you may print "{{:data.max_quality < 0 ? data.max_quality : '+' + data.max_quality}}" quality parts. +
+
+{{/if}} + +{{if data.categories}} +
+
+
+ {{for data.categories :category:category_i}} + {{:helper.link(category, null, {'category' : category_i+1}, category == data.show_category ? 'selected' : null)}} + {{empty}} + There are no known designs + {{/for}} +
+
+
+{{/if}} + +
+
+ {{#def._designs}} +
+
+ {{#def._queue}} +
+
+ +
diff --git a/nano/templates/mods/autolathe_designs.tmpl b/nano/templates/mods/autolathe_designs.tmpl new file mode 100644 index 0000000000000..229844138f1c1 --- /dev/null +++ b/nano/templates/mods/autolathe_designs.tmpl @@ -0,0 +1,76 @@ +{{for data.designs}} +
+
+
+
+ +
+
{{:value.name}}
+
+ {{if value.point_cost > 0}} + {{if !data.disk}} + +
+ License point cost: {{:value.point_cost}} +
+
+ {{else}} + +
+ License point cost: {{:value.point_cost}} +
+
+ {{/if}} + {{/if}} +
+
+ {{if value.filename == data.unfolded}} +
+ {{if value.materials}} +
+
Materials
+ {{for value.materials :material:material_i}} + {{material.amount = value.adjust_materials ? Math.round((material.req * data.mat_efficiency) * 100) / 100 : material.req;}} +
{{:material.name}}: {{:material.amount}}
+ {{/for}} +
+ {{/if}} + {{if value.chemicals}} +
+
Reagents
+ {{for value.chemicals :chemical:chemical_i}} +
{{:chemical.name}}: {{:Math.round(chemical.req * 100) / 100}}
+ {{/for}} +
+ {{/if}} +
+
Build time: {{:value.time}}
+
+ {{if value.minimum_quality > -2}} +
+
Minimum quality required: {{:value.minimum_quality < 0 ? value.minimum_quality : '+' + value.minimum_quality}}
+
+ {{/if}} +
+ {{/if}} +
+
{{:helper.link('Print', 'plus', {'add_to_queue' : value.filename}, null, 'statusValue')}}
+
{{:helper.link('Print several', 'calculator', {'add_to_queue' : value.filename, 'several' : 1}, null, 'statusValue')}}
+
{{:helper.link('', 'triangle-1-' + value.filename == data.unfolded ? 'n' : 's', {'unfold' : value.filename}, null, 'statusValue')}}
+ +
+{{empty}} +
+
+
+ {{if !data.disk && data.have_disk}} + No disk + {{else !data.have_design_selector}} + This equipment is operated remotely + {{else}} + No designs + {{/if}} +
+
+
+{{/for}} diff --git a/nano/templates/mods/autolathe_disk_cloner.tmpl b/nano/templates/mods/autolathe_disk_cloner.tmpl new file mode 100644 index 0000000000000..5cd74bcd43b01 --- /dev/null +++ b/nano/templates/mods/autolathe_disk_cloner.tmpl @@ -0,0 +1,109 @@ + +
+
+
+
+ {{if data.copying}} + {{:helper.link('STOP', '', {'start' : 1}, null, 'bigRedButton')}} + {{else}} + {{:helper.link('START', '', {'start' : 1}, null, 'bigButton')}} + {{/if}} +
+
+ {{if data.copying}} + Copying {{:data.copyingnow}}/{{:data.copyingtotal}} + {{else}} + IDLE + {{/if}} +
+
+
+
+ +
+
+
+ {{if data.disk1}} +
Source disk
+
{{:data.disk1.disk_name ? data.disk1.disk_name : 'data disk'}}
+
+ {{if data.disk1.license >= 0}} + Licenses: {{:data.disk1.license}} + {{/if}} +
+
{{:helper.link('eject', 'eject', {'eject' : 'f'}, null, 'statusValue')}}
+ {{else}} +
Source disk
+
no disk
+
{{:helper.link('insert', 'eject', {'eject' : 'f'}, null, 'statusValue')}}
+ {{/if}} +
+
+ {{if data.disk1}} +
+ {{for data.disk1.files}} +
+ {{if value.filetype == 'CCD'}} +
+ {{else value.filetype == 'SCD'}} +
+ {{else}} +
+ {{/if}} + {{:value.filename}}.{{:value.filetype}} +
+
+ {{empty}} +
Empty.
+ {{/for}} +
+ {{/if}} +
+
+
+
+
+
+ {{if data.disk2}} +
Target disk
+
{{:data.disk2.disk_name ? data.disk2.disk_name : 'data disk'}}
+
+ {{if (data.copyingnow && !data.copying) || data.disk2.used_capacity}} + NOT EMPTY + {{else}} + OK + {{/if}} +
+
{{:helper.link('eject', 'eject', {'eject' : 's'}, null, 'statusValue')}}
+ {{else}} +
Target disk
+
no disk
+
{{:helper.link('insert', 'eject', {'eject' : 's'}, null, 'statusValue')}}
+ {{/if}} +
+
+ {{if data.disk2}} +
+ {{for data.disk2.files}} +
+ {{if value.filetype == 'CCD'}} +
+ {{else value.filetype == 'SCD'}} +
+ {{else}} +
+ {{/if}} + {{:value.filename}}.{{:value.filetype}} +
+
+ {{empty}} +
Empty.
+ {{/for}} +
+ {{/if}} +
+
+
diff --git a/nano/templates/mods/autolathe_materials.tmpl b/nano/templates/mods/autolathe_materials.tmpl new file mode 100644 index 0000000000000..b872977e09fce --- /dev/null +++ b/nano/templates/mods/autolathe_materials.tmpl @@ -0,0 +1,22 @@ +
+

Loaded materials

+ +
+ {{for data.materials}} +
+
+
{{:helper.link('', 'eject', {'eject_material' : value.id}, null, 'statusValue')}}
+ {{:value.name.toTitleCase()}} +
{{:Math.round(value.amount * 100) / 100}}/{{:data.mat_capacity}}
+
+
+ {{empty}} +
+ None loaded +
+ {{/for}} +
+

{{:helper.link('INSERT MATERIALS', '', {'insert' : 1}, null, 'bigButton')}}
+
+
+
diff --git a/nano/templates/mods/autolathe_oddity.tmpl b/nano/templates/mods/autolathe_oddity.tmpl new file mode 100644 index 0000000000000..ea690b0ec122e --- /dev/null +++ b/nano/templates/mods/autolathe_oddity.tmpl @@ -0,0 +1,34 @@ +
+
+
+
+ Oddity: + {{if data.oddity_name}} + {{:data.oddity_name ? data.oddity_name :'data oddity_name'}} + {{else}} + none + {{/if}} +
+
{{:helper.link(data.oddity_name ? 'remove' : 'insert', 'remove', {'oddity_name' : 1}, null, 'statusValue')}}
+ {{if data.oddity_stats}} +
+
Model Oddity Stats:
+ {{for data.oddity_stats}} +
+ {{if value.level >= 10}} + Overwhelming aspect of + {{else value.level >= 6}} + Strong aspect of + {{else value.level >= 3}} + Medium aspect of + {{else value.level >= 1}} + Weak aspect of + {{/if}} + {{:value.name}} +
+ {{/for}} +
+ {{/if}} +
+
+
diff --git a/nano/templates/mods/autolathe_queue.tmpl b/nano/templates/mods/autolathe_queue.tmpl new file mode 100644 index 0000000000000..7b1c6cebca056 --- /dev/null +++ b/nano/templates/mods/autolathe_queue.tmpl @@ -0,0 +1,94 @@ +
+
+
+ {{:helper.link('', data.paused ? 'play' : 'pause', {'pause' : 1}, null, 'bigButton')}} + {{if data.current}} + {{:helper.link('', 'close', {'abort_print' : 1}, null, 'bigButton')}} + {{/if}} +
+ {{if data.current}} +
+
+ +
+
Printing {{:data.current.name}}
+
+ {{if data.error}} +
{{:data.error}}
+ {{else}} + {{:helper.displayBar(data.progress / data.current.time, 0, 1, 'good', Math.round((data.progress / data.current.time) * 100) + "%")}} + {{/if}} +
+
+
+ {{if data.current.point_cost > 0}} + {{if !data.disk}} +
+ License point cost: {{:data.current.point_cost}} +
+ {{else}} +
+ License point cost: {{:data.current.point_cost}} +
+ {{/if}} + {{/if}} + + {{if data.current.materials}} +
+
Materials
+ {{for data.current.materials :material:material_i}} + {{material.amount = data.current.adjust_materials ? Math.round((material.req * data.mat_efficiency) * 100) / 100 : material.req;}} +
{{:material.name}}: {{:material.amount}}
+ {{/for}} +
+ {{/if}} + {{if data.current.chemicals}} +
+
Reagents
+ {{for data.current.chemicals :chemical:chemical_i}} +
{{:chemical.name}}: {{:Math.round(chemical.req * 100) / 100}}
+ {{/for}} +
+ {{/if}} +
+
Build time: {{:data.current.time}}
+
+ +
+ {{else}} +
Idle
+ {{/if}} +
+
+{{if data.queue_max}} +
+
+
Queue: {{:data.queue.length}}/{{:data.queue_max}}
+ {{for data.queue}} +
+
+
+ {{if value.error >= 2}} +
{{:value.name}}
+ {{else value.error == 1}} +
{{:value.name}}
+ {{else}} + {{:value.name}} + {{/if}} +
+
+ {{:helper.link('', 'close', {'remove_from_queue' : value.ind}, null, 'statusValue')}} + {{if value.ind > 1}} + {{:helper.link('', 'triangle-1-n', {'move_up_queue' : value.ind}, null, 'statusValue')}} + {{/if}} + {{if value.ind < data.queue_len}} + {{:helper.link('', 'triangle-1-s', {'move_down_queue' : value.ind}, null, 'statusValue')}} + {{/if}} +
+
+ {{empty}} +
Empty
+ {{/for}} +
+
+{{/if}} diff --git a/nano/templates/mods/autolathe_reagents.tmpl b/nano/templates/mods/autolathe_reagents.tmpl new file mode 100644 index 0000000000000..f54d271fcdc09 --- /dev/null +++ b/nano/templates/mods/autolathe_reagents.tmpl @@ -0,0 +1,30 @@ +
+

Inserted beaker

+ +
+ {{if data.container}} + {{for data.reagents}} +
+
+ {{:value.name}} +
{{:Math.round(value.amount * 100) / 100}}
+
+ + {{empty}} +
+ Empty +
+ {{/for}} +
+
{{:helper.link('Remove', '', {'container' : 1}, null, 'statusValue')}}
+
+ {{else}} +
+ Not inserted +
+
+
{{:helper.link('Insert', 'eject', {'container' : 1}, null, 'statusValue')}}
+
+ {{/if}} +
+
diff --git a/nano/templates/mods/ntnetdsgn_downloader.tmpl b/nano/templates/mods/ntnetdsgn_downloader.tmpl new file mode 100644 index 0000000000000..d8c6ae1daf647 --- /dev/null +++ b/nano/templates/mods/ntnetdsgn_downloader.tmpl @@ -0,0 +1,107 @@ +Welcome to the design download utility. Please select which design you wish to download.
+{{if data.error}} +

Download Error

+
+ Information: +
+
+ {{:data.error}} +
+
+ Reset Program: +
+
+ {{:helper.link("RESET", null, {'PRG_reseterror' : 1})}} +
+
+{{/if}} + +

{{:data.downloadname ? 'Download Running' : 'No Downloads In Progress'}}

+ {{:data.downloadname ? 'Please wait...' : 'Standing by...'}} +
+
+ File name: +
+
+ {{:data.downloadname ? data.downloadname : 'N/A'}} +
+
+ File size: +
+
+ {{:data.downloadname ? (data.downloadcompletion + 'GQ / ' + data.downloadsize + 'GQ') : 'N/A'}} +
+
+ Transfer Rate: +
+
+ {{:data.downloadname ? data.downloadspeed : '0'}} GQ/s +
+
+ Download progress: +
+
+ {{:helper.displayBar(data.downloadcompletion, 0, data.downloadname ? data.downloadsize : 0, 'good')}} +
+
+ +

+ +

Downloads Queue

+
+ {{for data.downloads_queue}} +
+ {{:index + 1}}: +
+
+ {{:value}} + {{:helper.link('', 'close', {'PRG_removequeued' : value})}} +
+ {{empty}} + The queue is currently empty. + {{/for}} +
+

+ +

Primary designs repository

+
+ Hard drive: +
+
+ {{:helper.displayBar(data.disk_used, 0, data.disk_size, 'good')}} + {{:data.disk_used}}GQ / {{:data.disk_size}}GQ +
+ +

+ + + +
+
{{for data.all_categories}} + {{:helper.link(value, '', {'select_category' : value}, data.selected_category == value ? 'selected' : null)}} + {{/for}} + +
+ +
+
+ +
{{for data.possible_designs}} +
{{:helper.link("Toggle Description", '', {'show_desc_menu' : 1})}}
+
+
+
+ + {{/if}} +
+
+ + + +
{{:helper.link( value.name, '', {'PRG_downloadfile' : value.build_path })}} + {{if data.show_desc_menu}} +
+
{{:value.desc}}
File size {{:value.size}} GQ
+ {{/for}} + + {{/if}} From 7ff5dce523a7c781bf288b20473a4f3509a84d96 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Sun, 19 Jan 2025 21:22:11 +0300 Subject: [PATCH 04/11] Update ntnetdsgn_downloader.tmpl --- nano/templates/mods/ntnetdsgn_downloader.tmpl | 1 - 1 file changed, 1 deletion(-) diff --git a/nano/templates/mods/ntnetdsgn_downloader.tmpl b/nano/templates/mods/ntnetdsgn_downloader.tmpl index d8c6ae1daf647..d47ba906a971e 100644 --- a/nano/templates/mods/ntnetdsgn_downloader.tmpl +++ b/nano/templates/mods/ntnetdsgn_downloader.tmpl @@ -104,4 +104,3 @@ {{/for}} - {{/if}} From e6af182f83e80ca7e9c00b5b3dd32f100d8ed4a5 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Mon, 20 Jan 2025 05:30:15 +0300 Subject: [PATCH 05/11] 1 --- mods/RnD/_RnD.dme | 37 ------------------------------------- mods/RnD/code/autolathe.dm | 24 ++++++++++++++++-------- 2 files changed, 16 insertions(+), 45 deletions(-) diff --git a/mods/RnD/_RnD.dme b/mods/RnD/_RnD.dme index 3bcfda700fd12..02d143fe2cce6 100644 --- a/mods/RnD/_RnD.dme +++ b/mods/RnD/_RnD.dme @@ -32,40 +32,3 @@ #endif -// BEGIN_INTERNALS -// END_INTERNALS -// BEGIN_FILE_DIR -#define FILE_DIR . -// END_FILE_DIR -// BEGIN_PREFERENCES -// END_PREFERENCES -// BEGIN_INCLUDE -#include "_RnD.dm" -#include "code\_designs.dm" -#include "code\asset.dm" -#include "code\autolathe.dm" -#include "code\binary.dm" -#include "code\camera.dm" -#include "code\design.dm" -#include "code\designownloader.dm" -#include "code\experiment.dm" -#include "code\misc.dm" -#include "code\research.dm" -#include "code\sciefolder.dm" -#include "code\SSresearch.dm" -#include "code\tech_biotech.dm" -#include "code\tech_combat.dm" -#include "code\tech_data.dm" -#include "code\tech_engineering.dm" -#include "code\tech_illegal.dm" -#include "code\tech_power.dm" -#include "code\tech_robotics.dm" -#include "code\tech_telecom.dm" -#include "code\designs_autolathe\designs_arms_ammo.dm" -#include "code\designs_autolathe\designs_cutlery.dm" -#include "code\designs_autolathe\designs_devices_components.dm" -#include "code\designs_autolathe\designs_engineering.dm" -#include "code\designs_autolathe\designs_general.dm" -#include "code\designs_autolathe\designs_glasses.dm" -#include "code\designs_autolathe\designs_medical.dm" -// END_INCLUDE diff --git a/mods/RnD/code/autolathe.dm b/mods/RnD/code/autolathe.dm index 40154ad0aff1c..fbc203b2c7fe2 100644 --- a/mods/RnD/code/autolathe.dm +++ b/mods/RnD/code/autolathe.dm @@ -22,7 +22,7 @@ #define ERR_STOPPED "lazy user" #define ERR_SKILL_ISSUE "unskilled user" //AUTOLATHE -#define SANITIZE_LATHE_COST(n) round(n * mat_efficiency, 0.01) +#define SANITIZE_LATHE_COST(n) round((n * mechfabmod), 0.01) /obj/machinery/fabricator name = "autolathe" @@ -124,7 +124,10 @@ /obj/machinery/fabricator/proc/materials_data() var/list/data = list() - data["mat_efficiency"] = mat_efficiency + if(mechfabmod == 2) + data["mat_efficiency"] = (mat_efficiency * mechfabmod) + else if (mechfabmod == 1) + data["mat_efficiency"] = mat_efficiency data["mat_capacity"] = storage_capacity data["container"] = !!container @@ -690,13 +693,23 @@ /obj/machinery/fabricator/proc/res_load() - flick("autolathe_load_m", src) + var/list/viewing = list() + for (var/mob/M in view(6,src)) + if (M.client) + viewing |= M.client + var/image/orderimage = image('mods/RnD/icons/autolathe.dmi', src, "autolathe_load_m") + flick_overlay(orderimage, viewing, 8) /obj/machinery/fabricator/components_are_accessible(path) return !(fab_status_flags & FAB_BUSY) && ..() /obj/machinery/fabricator/proc/check_materials(datum/design/design) mechfabmod = 1 + if(design.build_type == MECHFAB) + mechfabmod = 2 + if(!(fab_status_flags & FAB_HACKED)) + return ERR_NOCOMPAT + for(var/rmat in design.materials) if(!(rmat in stored_material)) return ERR_NOMATERIAL @@ -712,11 +725,6 @@ if(!container.reagents.has_reagent(rgn, design.chemicals[rgn])) return ERR_NOREAGENT - if(design.build_type == MECHFAB) - mechfabmod = 2 - if(!(fab_status_flags & FAB_HACKED)) - return ERR_NOCOMPAT - return ERR_OK /obj/machinery/fabricator/proc/can_print(datum/computer_file/binary/design/design_file) From e3b9032480cf5984c763bbf67a6a5b7bc639cc7b Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Tue, 21 Jan 2025 22:53:06 +0300 Subject: [PATCH 06/11] 2 --- mods/RnD/_RnD.dme | 2 + mods/RnD/code/SSresearch.dm | 2 +- mods/RnD/code/design.dm | 10 +- .../designs_autolathe/designs_arms_ammo.dm | 5 + .../code/designs_autolathe/designs_tools.dm | 3 +- mods/RnD/code/designs_autolathe/disks.dm | 257 ++++++++++++++++++ mods/RnD/icons/discs.dmi | Bin 0 -> 1942 bytes mods/RnD/icons/research.dmi | Bin 0 -> 18861 bytes mods/dev_mode/maps/dev_map.dmm | 8 +- 9 files changed, 280 insertions(+), 7 deletions(-) create mode 100644 mods/RnD/code/designs_autolathe/disks.dm create mode 100644 mods/RnD/icons/discs.dmi create mode 100644 mods/RnD/icons/research.dmi diff --git a/mods/RnD/_RnD.dme b/mods/RnD/_RnD.dme index 02d143fe2cce6..5f0016c0af952 100644 --- a/mods/RnD/_RnD.dme +++ b/mods/RnD/_RnD.dme @@ -29,6 +29,8 @@ #include "code/designs_autolathe/designs_medical.dm" #include "code/designs_autolathe/designs_glasses.dm" #include "code/designs_autolathe/designs_general.dm" +#include "code/designs_autolathe/designs_tools.dm" +#include "code/designs_autolathe/disks.dm" #endif diff --git a/mods/RnD/code/SSresearch.dm b/mods/RnD/code/SSresearch.dm index 516f3fba9368b..170c24ee37649 100644 --- a/mods/RnD/code/SSresearch.dm +++ b/mods/RnD/code/SSresearch.dm @@ -100,7 +100,7 @@ SUBSYSTEM_DEF(research) /datum/controller/subsystem/research/proc/get_autolathe_design_by_build_path(build_path) for(var/datum/design/autolathe/design in all_designs) - if("[design.build_path]" == build_path) + if("[design.build_path]" == build_path || design.build_path == build_path) return design error("Incorrect design ID or path: [build_path]") diff --git a/mods/RnD/code/design.dm b/mods/RnD/code/design.dm index 0381549f9f56c..b6520deecb65d 100644 --- a/mods/RnD/code/design.dm +++ b/mods/RnD/code/design.dm @@ -15,16 +15,20 @@ return size /datum/computer_file/binary/design/proc/on_design_set() - if(design.id == "id") + if(design) set_filename(design.name) - else - set_filename(design.id) /datum/computer_file/binary/design/proc/set_filename(new_name) filename = sanitizeFileName("[new_name]") if(findtext(filename, "datum_design_") == 1) filename = copytext(filename, 14) +/datum/computer_file/binary/design/proc/set_design_type(design_type) + set_filename(design_type) + design = design_type // Temporarily assign that to pass the type down into research controller + SSresearch.initialize_design_file(src) + + /datum/computer_file/binary/design/ui_data() var/list/data = design.ui_data() data["filename"] = filename diff --git a/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm b/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm index 8dc744ff068d2..5b343f61e3a17 100644 --- a/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm +++ b/mods/RnD/code/designs_autolathe/designs_arms_ammo.dm @@ -1,9 +1,11 @@ /datum/design/autolathe/arms_ammo + name = "syringe gun cartridge" build_path = /obj/item/syringe_cartridge category = list("Arms and Ammunition") access = list(access_security) /datum/design/autolathe/arms_ammo/shotgun_holder + name = "shotgun ammunition holder" build_path = /obj/item/ammo_magazine/shotholder/empty /datum/design/autolathe/arms_ammo/shotgun_blanks @@ -15,6 +17,7 @@ build_path = /obj/item/gun/projectile/flare /datum/design/autolathe/arms_ammo/hidden + name = "fabricated machete" build_path = /obj/item/material/hatchet/machete/steel /datum/design/autolathe/arms_ammo/hidden/shotgun @@ -30,6 +33,7 @@ build_path = /obj/item/ammo_magazine/smg_top/rubber /datum/design/autolathe/arms_ammo/hidden/flamethrower + name = "flamethrower" build_path = /obj/item/flamethrower/full /datum/design/autolathe/arms_ammo/hidden/speedloader @@ -101,6 +105,7 @@ build_path = /obj/item/ammo_casing/shotgun/pellet /datum/design/autolathe/arms_ammo/hidden/tacknife + name = "combat knife" build_path = /obj/item/material/knife/combat /datum/design/autolathe/arms_ammo/hidden/stunshell diff --git a/mods/RnD/code/designs_autolathe/designs_tools.dm b/mods/RnD/code/designs_autolathe/designs_tools.dm index 96a14249bed89..d618d4985a6dc 100644 --- a/mods/RnD/code/designs_autolathe/designs_tools.dm +++ b/mods/RnD/code/designs_autolathe/designs_tools.dm @@ -3,6 +3,7 @@ category = list("Tools") /datum/design/autolathe/tool/prybar + name = "pry bar" build_path = /obj/item/crowbar/prybar /datum/design/autolathe/tool/rescuetool @@ -43,7 +44,5 @@ /datum/design/autolathe/tool/welder_industrial build_path = /obj/item/weldingtool/largetank - hidden = TRUE - /datum/design/autolathe/tool/designator build_path = /obj/item/device/drone_designator diff --git a/mods/RnD/code/designs_autolathe/disks.dm b/mods/RnD/code/designs_autolathe/disks.dm new file mode 100644 index 0000000000000..0d2a189b59667 --- /dev/null +++ b/mods/RnD/code/designs_autolathe/disks.dm @@ -0,0 +1,257 @@ +/obj/item/stock_parts/computer/hard_drive/portable/design/ + name = "design disk" + desc = "Data disk used to store autolathe designs." + icon = 'mods/RnD/icons/discs.dmi' + icon_state = "yellow" + max_capacity = 512 // Up to 255 designs, automatically reduced to the nearest power of 2 + origin_tech = list(TECH_DATA = 3) // Most design disks end up being 64 to 128 GQ + matter = list(MATERIAL_STEEL = 100, MATERIAL_PLASTIC = 200, MATERIAL_GOLD = 50) + var/list/designs = list() + + +/obj/item/stock_parts/computer/hard_drive/portable/design/LateInitialize(mapload) + install_default_programs() + +/obj/item/stock_parts/computer/hard_drive/portable/design/install_default_programs() + // Add design files to the disk + for(var/D in designs) + var/datum/design/dsgn = D + var/build = dsgn.build_path + + if(!dsgn) + continue + var/datum/design/autolathe/design = SSresearch.get_autolathe_design_by_build_path(build) + if(!design) + continue + var/datum/computer_file/binary/design/design_file = design.file + + create_file(design_file) + + + // Shave off the extra space so a disk with two designs doesn't show up as 1024 GQ + while(max_capacity > 16 && max_capacity / 2 > used_capacity) + max_capacity /= 2 + + // Prevent people from breaking DRM by copying files across protected disks. + // Stops people from screwing around with unprotected disks too. + return TRUE + +// Disks formated as /designpath = pointcost , if no point cost is specified it defaults to 1. + + + +/obj/item/stock_parts/computer/hard_drive/portable/design/arm + name = "Arms and Ammo Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/arms_ammo, + /datum/design/autolathe/arms_ammo/shotgun_holder, + /datum/design/autolathe/arms_ammo/shotgun_blanks, + /datum/design/autolathe/arms_ammo/flaregun, + /datum/design/autolathe/arms_ammo/hidden, + /datum/design/autolathe/arms_ammo/hidden/shotgun, + /datum/design/autolathe/arms_ammo/shotgun_flash, + /datum/design/autolathe/arms_ammo/hidden/magazine_smg_rubber, + /datum/design/autolathe/arms_ammo/hidden/flamethrower, + /datum/design/autolathe/arms_ammo/hidden/speedloader, + /datum/design/autolathe/arms_ammo/hidden/speedloader_small, + /datum/design/autolathe/arms_ammo/hidden/speedloader_magnum, + /datum/design/autolathe/arms_ammo/hidden/magazine_pistol, + /datum/design/autolathe/arms_ammo/hidden/magazine_pistol_rubber, + /datum/design/autolathe/arms_ammo/hidden/magazine_pistol_double, + /datum/design/autolathe/arms_ammo/hidden/magazine_pistol_double_rubber, + /datum/design/autolathe/arms_ammo/hidden/magazine_small, + /datum/design/autolathe/arms_ammo/hidden/magazine_magnum, + /datum/design/autolathe/arms_ammo/hidden/magazine_smg, + /datum/design/autolathe/arms_ammo/hidden/magazine_uzi, + /datum/design/autolathe/arms_ammo/hidden/magazine_smg_topmounted, + /datum/design/autolathe/arms_ammo/hidden/magazine_arifle, + /datum/design/autolathe/arms_ammo/hidden/magazine_bullpupheavy, + /datum/design/autolathe/arms_ammo/hidden/magazine_bullpuplight, + /datum/design/autolathe/arms_ammo/hidden/shotgun, + /datum/design/autolathe/arms_ammo/hidden/shotgun_pellet, + /datum/design/autolathe/arms_ammo/hidden/tacknife, + /datum/design/autolathe/arms_ammo/hidden/stunshell, + /datum/design/autolathe/arms_ammo/hidden/flechette, + /datum/design/autolathe/arms_ammo/hidden/skrellian_rifle_flechette, + /datum/design/autolathe/arms_ammo/hidden/skrellian_rifle_slug, + /datum/design/autolathe/arms_ammo/hidden/stripperclip, + /datum/design/autolathe/arms_ammo/hidden/pistolstripperclip, + /datum/design/autolathe/arms_ammo/hidden/broomstickstripperclip, + /datum/design/autolathe/arms_ammo/hidden/rifleinternalclip, + /datum/design/autolathe/arms_ammo/hidden/beandrum, + /datum/design/autolathe/arms_ammo/hidden/nt10mag, + /datum/design/autolathe/arms_ammo/hidden/shotgun_flechette, + ) + + +/obj/item/stock_parts/computer/hard_drive/portable/design/components + name = "General Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/general, + /datum/design/autolathe/general/flashlight, + /datum/design/autolathe/general/floor_light, + /datum/design/autolathe/general/extinguisher, + /datum/design/autolathe/general/extinguisher/mini, + /datum/design/autolathe/general/jar, + /datum/design/autolathe/general/radio_headset, + /datum/design/autolathe/general/radio_bounced, + /datum/design/autolathe/general/suit_cooler, + /datum/design/autolathe/general/weldermask, + /datum/design/autolathe/general/knife, + /datum/design/autolathe/general/taperecorder, + /datum/design/autolathe/general/tape, + /datum/design/autolathe/general/tube/large/warm, + /datum/design/autolathe/general/tube/large/cool, + /datum/design/autolathe/general/tube/large/white, + /datum/design/autolathe/general/tube/warm, + /datum/design/autolathe/general/tube/cool, + /datum/design/autolathe/general/tube/white, + /datum/design/autolathe/general/bulb/warm, + /datum/design/autolathe/general/bulb/cool, + /datum/design/autolathe/general/bulb/white, + /datum/design/autolathe/general/ashtray_glass, + /datum/design/autolathe/general/weldinggoggles, + /datum/design/autolathe/general/blackpen, + /datum/design/autolathe/general/bluepen, + /datum/design/autolathe/general/redpen, + /datum/design/autolathe/general/greenpen, + /datum/design/autolathe/general/clipboard_steel, + /datum/design/autolathe/general/clipboard_alum, + /datum/design/autolathe/general/clipboard_glass, + /datum/design/autolathe/general/clipboard_alum, + /datum/design/autolathe/general/destTagger, + /datum/design/autolathe/general/labeler, + /datum/design/autolathe/general/handcuffs, + /datum/design/autolathe/general/plunger, + /datum/design/autolathe/general/toolbox, + /datum/design/autolathe/general/binoculars, + /datum/design/autolathe/general/tape_roll, + ) + +/obj/item/stock_parts/computer/hard_drive/portable/design/components + name = "Components Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/device_component, + /datum/design/autolathe/device_component/keyboard, + /datum/design/autolathe/device_component/tesla_component, + /datum/design/autolathe/device_component/radio_transmitter, + /datum/design/autolathe/device_component/radio_transmitter_event, + /datum/design/autolathe/device_component/radio_receiver, + /datum/design/autolathe/device_component/battery_backup_crap, + /datum/design/autolathe/device_component/battery_backup_stock, + /datum/design/autolathe/device_component/battery_backup_turbo, + /datum/design/autolathe/device_component/battery_backup_responsive, + /datum/design/autolathe/device_component/terminal, + /datum/design/autolathe/device_component/igniter, + /datum/design/autolathe/device_component/signaler, + /datum/design/autolathe/device_component/sensor_infra, + /datum/design/autolathe/device_component/timer, + /datum/design/autolathe/device_component/sensor_prox, + /datum/design/autolathe/device_component/cable_coil, + /datum/design/autolathe/device_component/electropack, + /datum/design/autolathe/device_component/beartrap, + /datum/design/autolathe/device_component/cell_device, + /datum/design/autolathe/device_component/ecigcartridge, + /datum/design/autolathe/device_component/conveyor_construct, + /datum/design/autolathe/device_component/conveyor_switch_construct, + /datum/design/autolathe/device_component/conveyor_switch_oneway_construct, + ) + +/obj/item/stock_parts/computer/hard_drive/portable/design/cuttery + name = "Cuttery Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/cutlery, + /datum/design/autolathe/cutlery/spoon_aluminium, + /datum/design/autolathe/cutlery/spork_aluminium, + /datum/design/autolathe/cutlery/knife_aluminium, + /datum/design/autolathe/cutlery/foon_aluminium, + /datum/design/autolathe/cutlery/fork_plastic, + /datum/design/autolathe/cutlery/spoon_plastic, + /datum/design/autolathe/cutlery/spork_plastic, + /datum/design/autolathe/cutlery/knife_plastic, + /datum/design/autolathe/cutlery/foon_plastic, + ) + +/obj/item/stock_parts/computer/hard_drive/portable/design/engineering + name = "Engineering Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/engineering, + /datum/design/autolathe/engineering/airalarm, + /datum/design/autolathe/engineering/firealarm, + /datum/design/autolathe/engineering/intercom, + /datum/design/autolathe/engineering/powermodule, + /datum/design/autolathe/engineering/rcd_ammo, + /datum/design/autolathe/engineering/rcd_ammo_large, + /datum/design/autolathe/engineering/camera_assembly, + /datum/design/autolathe/engineering/transfer_valve, + ) + +/obj/item/stock_parts/computer/hard_drive/portable/design/drinking + name = "Drinking Glass Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/drinkingglass, + /datum/design/autolathe/drinkingglass/rocks, + /datum/design/autolathe/drinkingglass/shake, + /datum/design/autolathe/drinkingglass/cocktail, + /datum/design/autolathe/drinkingglass/shot, + /datum/design/autolathe/drinkingglass/pint, + /datum/design/autolathe/drinkingglass/mug, + /datum/design/autolathe/drinkingglass/wine, + /datum/design/autolathe/drinkingglass/carafe, + /datum/design/autolathe/drinkingglass/flute, + /datum/design/autolathe/drinkingglass/coffeecup, + /datum/design/autolathe/drinkingglass/cognac, + /datum/design/autolathe/drinkingglass/goblet, + /datum/design/autolathe/drinkingglass/coffeecup/glass, + ) + +/obj/item/stock_parts/computer/hard_drive/portable/design/medical + name = "Medical Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/medical, + /datum/design/autolathe/medical/circularsaw, + /datum/design/autolathe/medical/surgicaldrill, + /datum/design/autolathe/medical/retractor, + /datum/design/autolathe/medical/dropper, + /datum/design/autolathe/medical/cautery, + /datum/design/autolathe/medical/hemostat, + /datum/design/autolathe/medical/beaker, + /datum/design/autolathe/medical/beaker_large, + /datum/design/autolathe/medical/beaker_insul, + /datum/design/autolathe/medical/beaker_insul_large, + /datum/design/autolathe/medical/vial, + /datum/design/autolathe/medical/syringe, + /datum/design/autolathe/medical/pill_bottle, + /datum/design/autolathe/medical/hypospray/autoinjector, + /datum/design/autolathe/medical/scalpel, + ) + + +/obj/item/stock_parts/computer/hard_drive/portable/design/tool + name = "Tools Designs" + icon_state = "red" + designs = list( + /datum/design/autolathe/tool/, + /datum/design/autolathe/tool/prybar, + /datum/design/autolathe/tool/rescuetool, + /datum/design/autolathe/tool/int_wirer, + /datum/design/autolathe/tool/int_debugger, + /datum/design/autolathe/tool/int_analyzer, + /datum/design/autolathe/tool/multitool, + /datum/design/autolathe/tool/t_scanner, + /datum/design/autolathe/tool/weldertool, + /datum/design/autolathe/tool/screwdriver, + /datum/design/autolathe/tool/wirecutters, + /datum/design/autolathe/tool/wrench, + /datum/design/autolathe/tool/hatchet, + /datum/design/autolathe/tool/minihoe, + /datum/design/autolathe/tool/welder_industrial, + /datum/design/autolathe/tool/designator + ) diff --git a/mods/RnD/icons/discs.dmi b/mods/RnD/icons/discs.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4adb582304e3c87b96eaeef283ff4531cdf57429 GIT binary patch literal 1942 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 literal 0 HcmV?d00001 diff --git a/mods/dev_mode/maps/dev_map.dmm b/mods/dev_mode/maps/dev_map.dmm index 02af7adec770e..717b70d7ca41b 100644 --- a/mods/dev_mode/maps/dev_map.dmm +++ b/mods/dev_mode/maps/dev_map.dmm @@ -814,6 +814,12 @@ icon_state = "dark" }, /area/tdome/testing) +"pBI" = ( +/obj/item/stock_parts/computer/hard_drive/portable/design/components, +/turf/unsimulated/floor{ + icon_state = "dark" + }, +/area/tdome/testing) "pCq" = ( /obj/item/gun/projectile/pirate, /turf/unsimulated/floor{ @@ -19261,7 +19267,7 @@ aab lCd rkx gqB -gqB +pBI gqB gqB gqB From 40ba9e826edab2f755d11c15904b4c8e62585e3f Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Thu, 23 Jan 2025 02:21:37 +0300 Subject: [PATCH 07/11] 3 --- .../modular_computers/hardware/hard_drive.dm | 28 ------------------- maps/using.dm | 2 +- mods/RnD/code/designs_autolathe/disks.dm | 12 ++++++-- mods/RnD/code/misc.dm | 25 +++++++++++++++++ 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 8d3bfd2bb6acc..e0d78a881926b 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -251,31 +251,3 @@ /obj/item/stock_parts/computer/hard_drive/Destroy() stored_files = null return ..() - -//[SIERRA-ADD] - MODPACK_RND - -/obj/item/stock_parts/computer/hard_drive/ui_data() - var/list/data = list( - "disk_name" = get_disk_name(), - "max_capacity" = max_capacity, - "used_capacity" = used_capacity - ) - - var/list/files = list() - for(var/datum/computer_file/F in stored_files) - files.Add(list(list( - "filename" = F.filename, - "filetype" = F.filetype, - "size" = F.size, - "undeletable" = F.undeletable - ))) - data["files"] = files - return data - -/obj/item/stock_parts/computer/hard_drive/proc/get_disk_name() - var/datum/computer_file/data/D = find_file_by_name("DISK_NAME") - if(!istype(D)) - return null - - return sanitizeSafe(D.stored_data, max_length = MAX_LNAME_LEN) -//[SIERRA-ADD] - MODPACK_RND diff --git a/maps/using.dm b/maps/using.dm index 365a8a23eccdc..ed1676799a660 100644 --- a/maps/using.dm +++ b/maps/using.dm @@ -1,5 +1,5 @@ //Easily change which map to build by uncommenting ONE below. -#define DEV_MODE 1 +#define DEV_MODE 0 #if DEV_MODE == 1 #include "../mods/dev_mode/code/dev_map/dev_map.dm" #warn Режим разработчика активен, не забудь выключить! diff --git a/mods/RnD/code/designs_autolathe/disks.dm b/mods/RnD/code/designs_autolathe/disks.dm index 0d2a189b59667..a8d6387444fc8 100644 --- a/mods/RnD/code/designs_autolathe/disks.dm +++ b/mods/RnD/code/designs_autolathe/disks.dm @@ -1,3 +1,6 @@ +/obj/item/stock_parts/computer/hard_drive/portable/ + var/disk_name + /obj/item/stock_parts/computer/hard_drive/portable/design/ name = "design disk" desc = "Data disk used to store autolathe designs." @@ -8,12 +11,17 @@ matter = list(MATERIAL_STEEL = 100, MATERIAL_PLASTIC = 200, MATERIAL_GOLD = 50) var/list/designs = list() - -/obj/item/stock_parts/computer/hard_drive/portable/design/LateInitialize(mapload) +/obj/item/stock_parts/computer/hard_drive/portable/LateInitialize(mapload) install_default_programs() /obj/item/stock_parts/computer/hard_drive/portable/design/install_default_programs() // Add design files to the disk + if(name) + var/datum/computer_file/data/text/D = new + D.filename = "DISK_NAME" + D.stored_data = name + create_file(D) + for(var/D in designs) var/datum/design/dsgn = D var/build = dsgn.build_path diff --git a/mods/RnD/code/misc.dm b/mods/RnD/code/misc.dm index 0fc2fd8d440dd..60204e4a2442a 100644 --- a/mods/RnD/code/misc.dm +++ b/mods/RnD/code/misc.dm @@ -23,3 +23,28 @@ to_chat(user, "You must hold \the [P] steady to burn \the [src].") else to_chat(user, "You must hold \the [P] steady to burn \the [src].") + +/obj/item/stock_parts/computer/hard_drive/ui_data() + var/list/data = list( + "disk_name" = get_disk_name(), + "max_capacity" = max_capacity, + "used_capacity" = used_capacity + ) + + var/list/files = list() + for(var/datum/computer_file/F in stored_files) + files.Add(list(list( + "filename" = F.filename, + "filetype" = F.filetype, + "size" = F.size, + "undeletable" = F.undeletable + ))) + data["files"] = files + return data + +/obj/item/stock_parts/computer/hard_drive/proc/get_disk_name() + var/datum/computer_file/data/text/D = find_file_by_name("DISK_NAME") + if(!istype(D)) + return null + + return sanitizeSafe(D.stored_data, max_length = MAX_LNAME_LEN) From 83fdef40db938b90e12c53a26ebacd7d323e76c1 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Thu, 23 Jan 2025 02:41:27 +0300 Subject: [PATCH 08/11] 3.1 --- mods/RnD/code/autolathe.dm | 18 +++++++++--------- mods/RnD/code/research.dm | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mods/RnD/code/autolathe.dm b/mods/RnD/code/autolathe.dm index fbc203b2c7fe2..15e82625af17d 100644 --- a/mods/RnD/code/autolathe.dm +++ b/mods/RnD/code/autolathe.dm @@ -199,7 +199,7 @@ var/list/qmats = stored_material.Copy() - for(var/i = 1; i <= queue.len; i++) + for(var/i = 1; i <= LAZYLEN(queue); i++) var/datum/computer_file/binary/design/design_file = queue[i] var/list/QR = design_file.ui_data() @@ -371,19 +371,19 @@ if(href_list["remove_from_queue"]) var/ind = text2num(href_list["remove_from_queue"]) - if(ind >= 1 && ind <= queue.len) + if(ind >= 1 && ind <= LAZYLEN(queue)) queue.Cut(ind, ind + 1) return 1 if(href_list["move_up_queue"]) var/ind = text2num(href_list["move_up_queue"]) - if(ind >= 2 && ind <= queue.len) + if(ind >= 2 && ind <= LAZYLEN(queue)) queue.Swap(ind, ind - 1) return 1 if(href_list["move_down_queue"]) var/ind = text2num(href_list["move_down_queue"]) - if(ind >= 1 && ind <= queue.len-1) + if(ind >= 1 && ind <= LAZYLEN(queue)-1) queue.Swap(ind, ind + 1) return 1 @@ -630,7 +630,7 @@ if(design_file) design_file = design_file.clone() - while(amount && queue.len < queue_max) + while(amount && LAZYLEN(queue) < queue_max) queue.Add(design_file) amount-- @@ -665,7 +665,7 @@ return FALSE /obj/machinery/fabricator/update_icon() - overlays.Cut() + CutOverlays() icon_state = initial(icon_state) @@ -687,7 +687,7 @@ /obj/machinery/fabricator/proc/print_post() flick("[initial(icon_state)]_finish", src) - if(!current_file && !queue.len) + if(!current_file && !LAZYLEN(queue)) playsound(src.loc, 'sound/machines/ping.ogg', 50, 1, -3) visible_message("\The [src] pings, indicating that queue is complete.") @@ -717,7 +717,7 @@ if(stored_material[rmat] < SANITIZE_LATHE_COST(design.materials[rmat])) return ERR_NOMATERIAL - if(design.chemicals.len) + if(LAZYLEN(design.chemicals)) if(!container) return ERR_NOREAGENT @@ -798,7 +798,7 @@ /obj/machinery/fabricator/proc/next_file() current_file = null progress = 0 - if(queue.len) + if(LAZYLEN(queue)) current_file = queue[1] print_pre() working = TRUE diff --git a/mods/RnD/code/research.dm b/mods/RnD/code/research.dm index e4b24a4405f6b..5e17784332ae8 100644 --- a/mods/RnD/code/research.dm +++ b/mods/RnD/code/research.dm @@ -191,7 +191,7 @@ var/global/list/explosion_watcher_list = list() // Unlocks hidden tech trees /datum/research/proc/check_item_for_tech(obj/item/I) var/list/temp_tech = I.origin_tech - if(!temp_tech.len) + if(!LAZYLEN(temp_tech)) return for(var/tree in researched_tech) From 632fe07bacc167f73889dac5d62d421962b61fcf Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Thu, 23 Jan 2025 02:49:59 +0300 Subject: [PATCH 09/11] Update autolathe.dm --- mods/RnD/code/autolathe.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/RnD/code/autolathe.dm b/mods/RnD/code/autolathe.dm index 15e82625af17d..6a148f2f87d60 100644 --- a/mods/RnD/code/autolathe.dm +++ b/mods/RnD/code/autolathe.dm @@ -614,7 +614,7 @@ /obj/machinery/fabricator/proc/can_recycle(obj/O) if(!selectively_recycled_types) return FALSE - if(!selectively_recycled_types.len) + if(!LAZYLEN(selectively_recycled_types)) return FALSE for(var/type in selectively_recycled_types) From 1b2abbeeba264720f5f1837f6bb871b1cee257e1 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Thu, 23 Jan 2025 04:17:39 +0300 Subject: [PATCH 10/11] 3.2 --- mods/RnD/code/autolathe.dm | 17 ++--------------- mods/RnD/code/designs_autolathe/disks.dm | 4 ++-- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/mods/RnD/code/autolathe.dm b/mods/RnD/code/autolathe.dm index 6a148f2f87d60..67d4bef0f7dd2 100644 --- a/mods/RnD/code/autolathe.dm +++ b/mods/RnD/code/autolathe.dm @@ -1,16 +1,3 @@ -/client/proc/browse_queue_flush(timeout = 50) - var/job = ++last_asset_job - var/t = 0 - var/timeout_time = timeout - src << browse({""}, "window=asset_cache_browser&file=asset_cache_send_verify.htm") - - while(!completed_asset_jobs["[job]"] && t < timeout_time) // Reception is handled in Topic() - stoplag(1) // Lock up the caller until this is received. - t++ - if (t < timeout_time) - return TRUE - - //Autolathe defines #define ERR_OK 0 #define ERR_NOTFOUND "not found" @@ -664,7 +651,7 @@ return TRUE return FALSE -/obj/machinery/fabricator/update_icon() +/obj/machinery/fabricator/on_update_icon() CutOverlays() icon_state = initial(icon_state) @@ -935,7 +922,7 @@ return ERR_NOCOMPAT -/obj/machinery/fabricator/micro/update_icon() +/obj/machinery/fabricator/micro/on_update_icon() ClearOverlays() if(panel_open) AddOverlays("[icon_state]_panel") diff --git a/mods/RnD/code/designs_autolathe/disks.dm b/mods/RnD/code/designs_autolathe/disks.dm index a8d6387444fc8..0e5a25c5b2894 100644 --- a/mods/RnD/code/designs_autolathe/disks.dm +++ b/mods/RnD/code/designs_autolathe/disks.dm @@ -246,7 +246,7 @@ name = "Tools Designs" icon_state = "red" designs = list( - /datum/design/autolathe/tool/, + /datum/design/autolathe/tool, /datum/design/autolathe/tool/prybar, /datum/design/autolathe/tool/rescuetool, /datum/design/autolathe/tool/int_wirer, @@ -261,5 +261,5 @@ /datum/design/autolathe/tool/hatchet, /datum/design/autolathe/tool/minihoe, /datum/design/autolathe/tool/welder_industrial, - /datum/design/autolathe/tool/designator + /datum/design/autolathe/tool/designator, ) From ecbfc7d7e26ec55a346e11efe78dd7d7a1c23ed4 Mon Sep 17 00:00:00 2001 From: Lexanx <61974560+Lexanx@users.noreply.github.com> Date: Thu, 23 Jan 2025 05:15:43 +0300 Subject: [PATCH 11/11] Update research.dm --- mods/RnD/code/research.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/RnD/code/research.dm b/mods/RnD/code/research.dm index 5e17784332ae8..bd7a74ff2dd9c 100644 --- a/mods/RnD/code/research.dm +++ b/mods/RnD/code/research.dm @@ -203,7 +203,7 @@ var/global/list/explosion_watcher_list = list() if(item_tech == T.item_tech_req) T.shown = TRUE return -/* + /datum/research/proc/is_research_file_type(datum/computer_file/file) if(istype(file, /datum/computer_file/binary/research_points)) return TRUE @@ -226,7 +226,7 @@ var/global/list/explosion_watcher_list = list() known_research_file_ids += research_points_file.research_id adjust_research_points(research_points_file.size * 1000) return TRUE -*/ + return FALSE /datum/research/proc/AddSciPoints(datum/computer_file/binary/sci/D)