From 75c8e0126e2af026158933ea3688cc02216048e9 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 22 Nov 2022 17:47:40 +0100 Subject: [PATCH] [MIRROR] Adds support for non-science techwebs (+Config) [MDB IGNORE] (#17596) * Adds support for non-science techwebs (+Config) (#71070) ## About The Pull Request This is an expanding of https://github.com/tgstation/tgstation/pull/69708 Adds a config to not connect machines to a techweb at the start of a round Adds the ability to multitool a server to get its techweb in its buffer, which can then be used on machines to sync them. Adds support for some machines to not cry when they don't have a techweb linked to it, in case they actually don't. If the config to not have machines connected to the science server is enabled, research servers will make their own techwebs instead. This is barebones though and would need more work if this option is used. For misc stuff: - I replaced checking ``GLOB.machines`` for research servers, to instead check ``SSresearch.servers``, where we can use ``as anything``. - Removed unused vars on the RD server control - I renamed the operating computer's .dm file to remove the capitalized letter from it. It's now operating_computer instead of Operations. ## Why It's Good For The Game This is adding support for 2 different cases that can be used in the future: 1. Off-station roles, we can make roles like Oldstation have their own techweb so they don't ruin science's efforts, or use their advanced research to get things we don't want, or even possibly have some blacklist webs for ghost roles (like teleporters) so that way we don't need to have this dance where we have to give them a very specific amount of materials for them to do things while not being able to get a teleporter and leaving. I heard discussions that people wanted this a while back, and one of the main things preventing this from happening is the lack of support. Hopefully this is encouragement to make it a reality, because I think it would be a really cool expansion of ghost roles and a good way to prevent them from messing with the round in progress. 2. Downstreams who want to do different things with Science. Personally I made this PR with voidcrew(shiptest) in mind and think this would make their lives easier. I didn't expand too much on this because I'm leaving up mostly to the downstreams to figure out what they want to do with these systems. ## Changelog This generally isn't really player facing, since most of the changes would only come into effect if the config is enabled?? :cl: fix: Research servers now only show servers connected to their techweb. /:cl: * Adds support for non-science techwebs (+Config) Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> --- .../configuration/entries/general.dm | 2 + code/controllers/subsystem/research.dm | 13 +- code/game/machinery/computer/dna_console.dm | 10 +- .../{Operating.dm => operating_computer.dm} | 12 +- code/modules/events/ghost_role/pirates.dm | 6 +- .../experiment/handlers/experiment_handler.dm | 2 + .../mob/living/simple_animal/bot/medbot.dm | 11 +- .../computers/item/computer.dm | 2 +- .../computers/item/tablet.dm | 2 +- .../file_system/computer_file.dm | 4 +- .../file_system/programs/airestorer.dm | 2 +- .../file_system/programs/frontier.dm | 151 ++++++++++-------- .../file_system/programs/ntmessenger.dm | 2 +- .../file_system/programs/techweb.dm | 19 ++- .../modules/research/machinery/_production.dm | 24 ++- code/modules/research/rdconsole.dm | 45 ++++-- code/modules/research/rdmachines.dm | 12 +- code/modules/research/server.dm | 35 ++-- .../modules/vehicles/mecha/mech_fabricator.dm | 20 ++- .../modules/wiremod/core/component_printer.dm | 25 ++- config/config.txt | 3 + tgstation.dme | 2 +- tgui/packages/tgui/interfaces/NtosScipaper.js | 7 +- tgui/packages/tgui/interfaces/Techweb.js | 41 +++-- 24 files changed, 302 insertions(+), 150 deletions(-) rename code/game/machinery/computer/{Operating.dm => operating_computer.dm} (94%) diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 7914e332275..263201b6846 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -357,6 +357,8 @@ /datum/config_entry/flag/show_irc_name +/datum/config_entry/flag/no_default_techweb_link + /datum/config_entry/flag/see_own_notes //Can players see their own admin notes /datum/config_entry/number/note_fresh_days diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index d55cb242f1b..3fda820c314 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -13,6 +13,9 @@ SUBSYSTEM_DEF(research) var/datum/techweb_node/error_node/error_node //These two are what you get if a node/design is deleted and somehow still stored in a console. var/datum/design/error_design/error_design + ///List of all research servers. + var/list/obj/machinery/rnd/server/servers = list() + //ERROR LOGGING ///associative id = number of times var/list/invalid_design_ids = list() @@ -21,8 +24,6 @@ SUBSYSTEM_DEF(research) ///associative id = error message var/list/invalid_node_boost = list() - var/list/obj/machinery/rnd/server/servers = list() - ///associative id = TRUE var/list/techweb_nodes_starting = list() ///category name = list(node.id = TRUE) @@ -68,9 +69,9 @@ SUBSYSTEM_DEF(research) ) /// Lookup list for ordnance briefers. - var/list/ordnance_experiments + var/list/ordnance_experiments = list() /// Lookup list for scipaper partners. - var/list/scientific_partners + var/list/scientific_partners = list() /datum/controller/subsystem/research/Initialize() point_types = TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES @@ -306,12 +307,10 @@ SUBSYSTEM_DEF(research) CHECK_TICK /datum/controller/subsystem/research/proc/populate_ordnance_experiments() - ordnance_experiments = list() - scientific_partners = list() - for (var/datum/experiment/ordnance/experiment_path as anything in subtypesof(/datum/experiment/ordnance)) if (initial(experiment_path.experiment_proper)) ordnance_experiments += new experiment_path() + for(var/partner_path in subtypesof(/datum/scientific_partner)) var/datum/scientific_partner/partner = new partner_path if(!partner.accepted_experiments.len) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 3c5b998b888..8f29918644c 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -205,6 +205,11 @@ return return ..() +/obj/machinery/computer/scan_consolenew/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + stored_research = tool.buffer + return TRUE + /obj/machinery/computer/scan_consolenew/AltClick(mob/user) // Make sure the user can interact with the machine. . = ..() @@ -231,8 +236,9 @@ set_default_state() // Link machine with research techweb. Used for discovering and accessing - // already discovered mutations - stored_research = SSresearch.science_tech + // already discovered mutations + if(!CONFIG_GET(flag/no_default_techweb_link)) + stored_research = SSresearch.science_tech /obj/machinery/computer/scan_consolenew/ui_interact(mob/user, datum/tgui/ui) . = ..() diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/operating_computer.dm similarity index 94% rename from code/game/machinery/computer/Operating.dm rename to code/game/machinery/computer/operating_computer.dm index f1ada284754..876f61db97d 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/operating_computer.dm @@ -17,7 +17,8 @@ /obj/machinery/computer/operating/Initialize(mapload) ..() - linked_techweb = SSresearch.science_tech + if(!CONFIG_GET(flag/no_default_techweb_link)) + linked_techweb = SSresearch.science_tech find_table() return INITIALIZE_HINT_LATELOAD @@ -37,7 +38,12 @@ if(table && table.computer == src) table.computer = null QDEL_NULL(experiment_handler) - . = ..() + return ..() + +/obj/machinery/computer/operating/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + linked_techweb = tool.buffer + return TRUE /obj/machinery/computer/operating/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/disk/surgery)) @@ -51,6 +57,8 @@ return ..() /obj/machinery/computer/operating/proc/sync_surgeries() + if(!linked_techweb) + return for(var/i in linked_techweb.researched_designs) var/datum/design/surgery/D = SSresearch.techweb_design_by_id(i) if(!istype(D)) diff --git a/code/modules/events/ghost_role/pirates.dm b/code/modules/events/ghost_role/pirates.dm index cfc391ad4dc..f1bf7bc669d 100644 --- a/code/modules/events/ghost_role/pirates.dm +++ b/code/modules/events/ghost_role/pirates.dm @@ -238,10 +238,12 @@ //interrupt_research /obj/machinery/shuttle_scrambler/proc/interrupt_research() - for(var/obj/machinery/rnd/server/S in GLOB.machines) + for(var/obj/machinery/rnd/server/S as anything in SSresearch.servers) if(S.machine_stat & (NOPOWER|BROKEN)) continue - S.emp_act(1) + if(S.stored_research != SSresearch.science_tech) //only target the station + continue + S.emp_act() new /obj/effect/temp_visual/emp(get_turf(S)) /obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user) diff --git a/code/modules/experisci/experiment/handlers/experiment_handler.dm b/code/modules/experisci/experiment/handlers/experiment_handler.dm index 888b252f7e6..38628678882 100644 --- a/code/modules/experisci/experiment/handlers/experiment_handler.dm +++ b/code/modules/experisci/experiment/handlers/experiment_handler.dm @@ -110,6 +110,8 @@ // Check that there is actually an experiment selected if (selected_experiment == null && !(config_flags & EXPERIMENT_CONFIG_ALWAYS_ACTIVE)) return + if (!linked_web) + return // Determine if this experiment is actionable with this target var/list/arguments = list(src) diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index c415cfbc9da..86bc44ed71c 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -137,7 +137,8 @@ skin = new_skin update_appearance() - linked_techweb = SSresearch.science_tech + if(!CONFIG_GET(flag/no_default_techweb_link)) + linked_techweb = SSresearch.science_tech AddComponent(/datum/component/tippable, \ tip_time = 3 SECONDS, \ @@ -164,6 +165,11 @@ /mob/living/simple_animal/bot/medbot/attack_paw(mob/user, list/modifiers) return attack_hand(user, modifiers) +/mob/living/simple_animal/bot/medbot/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + linked_techweb = tool.buffer + return TRUE + // Variables sent to TGUI /mob/living/simple_animal/bot/medbot/ui_data(mob/user) var/list/data = ..() @@ -197,6 +203,9 @@ medical_mode_flags ^= MEDBOT_STATIONARY_MODE path = list() if("sync_tech") + if(!linked_techweb) + to_chat(usr, span_notice("No research techweb connected.")) + return var/oldheal_amount = heal_amount var/tech_boosters for(var/index in linked_techweb.researched_designs) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 219204f9b57..b0c474f3e0d 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -735,7 +735,7 @@ GLOBAL_LIST_EMPTY(TabletMessengers) // a list of all active messengers, similar // Check if any Applications need it for(var/datum/computer_file/item_holding_app as anything in stored_files) - if(item_holding_app.try_insert(attacking_item, user)) + if(item_holding_app.application_attackby(attacking_item, user)) return if(istype(attacking_item, /obj/item/paper)) diff --git a/code/modules/modular_computers/computers/item/tablet.dm b/code/modules/modular_computers/computers/item/tablet.dm index ec83ef998b7..d3da7142566 100644 --- a/code/modules/modular_computers/computers/item/tablet.dm +++ b/code/modules/modular_computers/computers/item/tablet.dm @@ -1,4 +1,4 @@ -/obj/item/modular_computer/tablet //Its called tablet for theme of 90ies but actually its a "big smartphone" sized +/obj/item/modular_computer/tablet //Its called tablet for theme of 90ies but actually its a "big smartphone" sized name = "tablet computer" icon = 'icons/obj/modular_tablet.dmi' icon_state = "tablet-red" diff --git a/code/modules/modular_computers/file_system/computer_file.dm b/code/modules/modular_computers/file_system/computer_file.dm index e711693a6e6..d34124045ba 100644 --- a/code/modules/modular_computers/file_system/computer_file.dm +++ b/code/modules/modular_computers/file_system/computer_file.dm @@ -47,8 +47,8 @@ /datum/computer_file/proc/on_examine(obj/item/modular_computer/source, mob/user) return null -/// Called when someone tries to insert something one of your applications needs, like an Intellicard for AI restoration. Return TRUE to cancel attackby chain. -/datum/computer_file/proc/try_insert(obj/item/attacking_item, mob/living/user) +/// Called when attacking a tablet with an item, checking if any application uses it. Return TRUE to cancel the attack chain. +/datum/computer_file/proc/application_attackby(obj/item/attacking_item, mob/living/user) return FALSE /** diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm index 276470f8f6e..ef2f7d07d16 100644 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -58,7 +58,7 @@ return TRUE -/datum/computer_file/program/ai_restorer/try_insert(obj/item/attacking_item, mob/living/user) +/datum/computer_file/program/ai_restorer/application_attackby(obj/item/attacking_item, mob/living/user) if(!computer) return FALSE if(!istype(attacking_item, /obj/item/aicard)) diff --git a/code/modules/modular_computers/file_system/programs/frontier.dm b/code/modules/modular_computers/file_system/programs/frontier.dm index d475b661604..b5ff07af803 100644 --- a/code/modules/modular_computers/file_system/programs/frontier.dm +++ b/code/modules/modular_computers/file_system/programs/frontier.dm @@ -24,7 +24,16 @@ /datum/computer_file/program/scipaper_program/on_start(mob/living/user) . = ..() - linked_techweb = SSresearch.science_tech + if(!CONFIG_GET(flag/no_default_techweb_link)) + linked_techweb = SSresearch.science_tech + +/datum/computer_file/program/scipaper_program/application_attackby(obj/item/attacking_item, mob/living/user) + if(!istype(attacking_item, /obj/item/multitool)) + return FALSE + var/obj/item/multitool/attacking_tool = attacking_item + if(!QDELETED(attacking_tool.buffer) && istype(attacking_tool.buffer, /datum/techweb)) + linked_techweb = attacking_tool.buffer + return TRUE /datum/computer_file/program/scipaper_program/proc/recheck_file_presence() if(selected_file in computer.stored_files) @@ -75,78 +84,84 @@ /datum/computer_file/program/scipaper_program/ui_data() // Program Headers: var/list/data = get_header_data() - data["currentTab"] = current_tab + data["currentTab"] = current_tab + data["has_techweb"] = !!linked_techweb - // First page. Form submission. - if(current_tab == 1) - data["fileList"] = list() - data["expList"] = list() - data["allowedTiers"] = list() - data["allowedPartners"] = list() - // Both the file and experiment list are assoc lists. ID as value, display name as keys. - for(var/datum/computer_file/data/ordnance/ordnance_file in computer.stored_files) - data["fileList"] += list(ordnance_file.filename = ordnance_file.uid) - if(selected_file) - for (var/possible_experiment in selected_file.possible_experiments) - var/datum/experiment/ordnance/experiment = possible_experiment - data["expList"] += list(initial(experiment.name) = experiment) - data["allowedTiers"] = paper_to_be.calculate_tier() - for (var/partner in SSresearch.scientific_partners) - var/datum/scientific_partner/scientific_partner = partner - if(paper_to_be.experiment_path in scientific_partner.accepted_experiments) - data["allowedPartners"] += list(scientific_partner.name = scientific_partner.type) + switch(current_tab) + // First page. Form submission. + if(1) + data["fileList"] = list() + data["expList"] = list() + data["allowedTiers"] = list() + data["allowedPartners"] = list() + // Both the file and experiment list are assoc lists. ID as value, display name as keys. + for(var/datum/computer_file/data/ordnance/ordnance_file in computer.stored_files) + data["fileList"] += list(ordnance_file.filename = ordnance_file.uid) + if(selected_file) + for (var/possible_experiment in selected_file.possible_experiments) + var/datum/experiment/ordnance/experiment = possible_experiment + data["expList"] += list(initial(experiment.name) = experiment) + data["allowedTiers"] = paper_to_be.calculate_tier() + for (var/partner in SSresearch.scientific_partners) + var/datum/scientific_partner/scientific_partner = partner + if(paper_to_be.experiment_path in scientific_partner.accepted_experiments) + data["allowedPartners"] += list(scientific_partner.name = scientific_partner.type) - data += paper_to_be.return_gist() - data["selectedFile"] = selected_file?.filename - // Renamed both of these to be more topical. - data["selectedExperiment"] = data["experimentName"] - data -= "experimentName" - data["selectedPartner"] = data["partner"] - data -= "partner" + data += paper_to_be.return_gist() + data["selectedFile"] = selected_file?.filename + // Renamed both of these to be more topical. + data["selectedExperiment"] = data["experimentName"] + data -= "experimentName" + data["selectedPartner"] = data["partner"] + data -= "partner" - // Second page. View previous - if(current_tab == 2) - data["publishedPapers"] = list() - for (var/experiment_types in linked_techweb.published_papers) - for (var/datum/scientific_paper/paper in linked_techweb.published_papers[experiment_types]) - data["publishedPapers"] += list(paper.return_gist()) + // Second page. View previous + if(2) + data["publishedPapers"] = list() + if(!linked_techweb) + return data + for (var/experiment_types in linked_techweb.published_papers) + for (var/datum/scientific_paper/paper in linked_techweb.published_papers[experiment_types]) + data["publishedPapers"] += list(paper.return_gist()) - if(current_tab == 4) - data["purchaseableBoosts"] = list() - data["relations"] = list() - var/list/visible_nodes = list() - visible_nodes += linked_techweb.get_available_nodes() - visible_nodes += linked_techweb.get_researched_nodes() - data["visibleNodes"] = list() - for (var/id in visible_nodes) - if(visible_nodes[id]) - data["visibleNodes"] += id + if(4) + data["purchaseableBoosts"] = list() + data["relations"] = list() + data["visibleNodes"] = list() + if(!linked_techweb) + return data + var/list/visible_nodes = list() + visible_nodes += linked_techweb.get_available_nodes() + visible_nodes += linked_techweb.get_researched_nodes() + for (var/id in visible_nodes) + if(visible_nodes[id]) + data["visibleNodes"] += id - for (var/datum/scientific_partner/partner as anything in SSresearch.scientific_partners) - var/relations = linked_techweb.scientific_cooperation[partner.type] - switch (round(relations / SCIENTIFIC_COOPERATION_PURCHASE_MULTIPLIER)) // We use points to determine these - if(-INFINITY to 0) - data["relations"][partner.type] = "Nonexistant" - if(1 to 2499) - data["relations"][partner.type] = "Negligible" - if(2500 to 4999) - data["relations"][partner.type] = "Limited" - if(5000 to 9999) - data["relations"][partner.type] = "Cordial" - if(10000 to 19999) - data["relations"][partner.type] = "Partners" - if(20000 to INFINITY) - data["relations"][partner.type] = "Devoted" - else - data["relations"][partner.type] = "Undefined" - data["purchaseableBoosts"][partner.type] = list() - for(var/node_id in linked_techweb.get_available_nodes()) - // Not from our partner - if(!(node_id in partner.boosted_nodes)) - continue - if(!partner.allowed_to_boost(linked_techweb, node_id)) - continue - data["purchaseableBoosts"][partner.type] += node_id + for (var/datum/scientific_partner/partner as anything in SSresearch.scientific_partners) + var/relations = linked_techweb.scientific_cooperation[partner.type] + switch (round(relations / SCIENTIFIC_COOPERATION_PURCHASE_MULTIPLIER)) // We use points to determine these + if(-INFINITY to 0) + data["relations"][partner.type] = "Nonexistant" + if(1 to 2499) + data["relations"][partner.type] = "Negligible" + if(2500 to 4999) + data["relations"][partner.type] = "Limited" + if(5000 to 9999) + data["relations"][partner.type] = "Cordial" + if(10000 to 19999) + data["relations"][partner.type] = "Partners" + if(20000 to INFINITY) + data["relations"][partner.type] = "Devoted" + else + data["relations"][partner.type] = "Undefined" + data["purchaseableBoosts"][partner.type] = list() + for(var/node_id in linked_techweb.get_available_nodes()) + // Not from our partner + if(!(node_id in partner.boosted_nodes)) + continue + if(!partner.allowed_to_boost(linked_techweb, node_id)) + continue + data["purchaseableBoosts"][partner.type] += node_id return data /datum/computer_file/program/scipaper_program/ui_act(action, params) diff --git a/code/modules/modular_computers/file_system/programs/ntmessenger.dm b/code/modules/modular_computers/file_system/programs/ntmessenger.dm index 389bc302108..29394ef2b77 100644 --- a/code/modules/modular_computers/file_system/programs/ntmessenger.dm +++ b/code/modules/modular_computers/file_system/programs/ntmessenger.dm @@ -47,7 +47,7 @@ /// Whether this app can send messages to all. var/spam_mode = FALSE -/datum/computer_file/program/messenger/try_insert(obj/item/attacking_item, mob/living/user) +/datum/computer_file/program/messenger/application_attackby(obj/item/attacking_item, mob/living/user) if(!istype(attacking_item, /obj/item/photo)) return FALSE var/obj/item/photo/pic = attacking_item diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm index 34b26479933..b8c0d0b1a66 100644 --- a/code/modules/modular_computers/file_system/programs/techweb.dm +++ b/code/modules/modular_computers/file_system/programs/techweb.dm @@ -23,8 +23,16 @@ /datum/computer_file/program/science/on_start(mob/living/user) . = ..() - stored_research = SSresearch.science_tech + if(!CONFIG_GET(flag/no_default_techweb_link)) + stored_research = SSresearch.science_tech +/datum/computer_file/program/science/application_attackby(obj/item/attacking_item, mob/living/user) + if(!istype(attacking_item, /obj/item/multitool)) + return FALSE + var/obj/item/multitool/attacking_tool = attacking_item + if(!QDELETED(attacking_tool.buffer) && istype(attacking_tool.buffer, /datum/techweb)) + stored_research = attacking_tool.buffer + return TRUE /datum/computer_file/program/science/ui_assets(mob/user) return list( @@ -34,6 +42,9 @@ // heavy data from this proc should be moved to static data when possible /datum/computer_file/program/science/ui_data(mob/user) var/list/data = get_header_data() + data["stored_research"] = !!stored_research + if(!stored_research) //lack of a research node is all we care about. + return data data += list( "nodes" = list(), "experiments" = list(), @@ -44,7 +55,7 @@ "sec_protocols" = !(computer.obj_flags & EMAGGED), "t_disk" = null, //Not doing disk operations on the app, use the console for that. "d_disk" = null, //See above. - "locked" = locked + "locked" = locked, ) // Serialize all nodes to display @@ -179,8 +190,8 @@ return id_cache[id] /datum/computer_file/program/science/proc/research_node(id, mob/user) - if(!stored_research.available_nodes[id] || stored_research.researched_nodes[id]) - computer.say("Node unlock failed: Either already researched or not available!") + if(!stored_research || !stored_research.available_nodes[id] || stored_research.researched_nodes[id]) + computer.say("Node unlock failed: Either no techweb is found, node is already researched or is not available!") return FALSE var/datum/techweb_node/tech_node = SSresearch.techweb_node_by_id(id) if(!istype(tech_node)) diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index 1b9e93580b5..0720bb0b228 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -35,14 +35,32 @@ . = ..() cached_designs = list() - materials = AddComponent(/datum/component/remote_materials, "lathe", mapload, mat_container_flags=BREAKDOWN_FLAGS_LATHE) - AddComponent(/datum/component/payment, 0, SSeconomy.get_dep_account(payment_department), PAYMENT_CLINICAL, TRUE) + materials = AddComponent( + /datum/component/remote_materials, \ + "lathe", \ + mapload, \ + mat_container_flags = BREAKDOWN_FLAGS_LATHE, \ + ) + AddComponent( + /datum/component/payment, \ + 0, \ + SSeconomy.get_dep_account(payment_department), \ + PAYMENT_CLINICAL, \ + TRUE, \ + ) create_reagents(0, OPENCONTAINER) - update_designs() + if(stored_research) + update_designs() RefreshParts() update_icon(UPDATE_OVERLAYS) +/obj/machinery/rnd/production/connect_techweb(datum/techweb/new_techweb) + if(stored_research) + UnregisterSignal(stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN)) + + . = ..() + RegisterSignal( stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN), diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 840968ddd9b..7fab447eabe 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -47,12 +47,14 @@ Nothing else in the console has ID requirements. /obj/machinery/computer/rdconsole/Initialize(mapload) . = ..() - stored_research = SSresearch.science_tech - stored_research.consoles_accessing[src] = TRUE + if(!CONFIG_GET(flag/no_default_techweb_link)) + stored_research = SSresearch.science_tech + stored_research.consoles_accessing[src] = TRUE /obj/machinery/computer/rdconsole/Destroy() if(stored_research) stored_research.consoles_accessing -= src + stored_research = null if(t_disk) t_disk.forceMove(get_turf(src)) t_disk = null @@ -87,9 +89,15 @@ Nothing else in the console has ID requirements. return return ..() +/obj/machinery/computer/rdconsole/multitool_act(mob/living/user, obj/item/multitool/tool) + . = ..() + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + stored_research = tool.buffer + return TRUE + /obj/machinery/computer/rdconsole/proc/research_node(id, mob/user) - if(!stored_research.available_nodes[id] || stored_research.researched_nodes[id]) - say("Node unlock failed: Either already researched or not available!") + if(!stored_research || !stored_research.available_nodes[id] || stored_research.researched_nodes[id]) + say("Node unlock failed: Either no techweb is found, node is already researched or is not available!") return FALSE var/datum/techweb_node/TN = SSresearch.techweb_node_by_id(id) if(!istype(TN)) @@ -150,7 +158,11 @@ Nothing else in the console has ID requirements. // heavy data from this proc should be moved to static data when possible /obj/machinery/computer/rdconsole/ui_data(mob/user) - . = list( + var/list/data = list() + data["stored_research"] = !!stored_research + if(!stored_research) //lack of a research node is all we care about. + return data + data += list( "nodes" = list(), "experiments" = list(), "researched_designs" = stored_research.researched_designs, @@ -160,24 +172,24 @@ Nothing else in the console has ID requirements. "sec_protocols" = !(obj_flags & EMAGGED), "t_disk" = null, "d_disk" = null, - "locked" = locked + "locked" = locked, ) if (t_disk) - .["t_disk"] = list ( - "stored_research" = t_disk.stored_research.researched_nodes + data["t_disk"] = list ( + "stored_research" = t_disk.stored_research.researched_nodes, ) if (d_disk) - .["d_disk"] = list ( + data["d_disk"] = list ( "max_blueprints" = d_disk.max_blueprints, - "blueprints" = list() + "blueprints" = list(), ) for (var/i in 1 to d_disk.max_blueprints) if (d_disk.blueprints[i]) var/datum/design/D = d_disk.blueprints[i] - .["d_disk"]["blueprints"] += D.id + data["d_disk"]["blueprints"] += D.id else - .["d_disk"]["blueprints"] += null + data["d_disk"]["blueprints"] += null // Serialize all nodes to display @@ -188,10 +200,10 @@ Nothing else in the console has ID requirements. if (stored_research.hidden_nodes[v]) continue - .["nodes"] += list(list( + data["nodes"] += list(list( "id" = n.id, "can_unlock" = stored_research.can_unlock_node(n), - "tier" = stored_research.tiers[n.id] + "tier" = stored_research.tiers[n.id], )) // Get experiments and serialize them @@ -200,14 +212,15 @@ Nothing else in the console has ID requirements. exp_to_process += stored_research.completed_experiments[e] for (var/e in exp_to_process) var/datum/experiment/ex = e - .["experiments"][ex.type] = list( + data["experiments"][ex.type] = list( "name" = ex.name, "description" = ex.description, "tag" = ex.exp_tag, "progress" = ex.check_progress(), "completed" = ex.completed, - "performance_hint" = ex.performance_hint + "performance_hint" = ex.performance_hint, ) + return data /** * Compresses an ID to an integer representation using the id_cache, used for deduplication diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index 7e535f10261..a26b9cd7e97 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -20,9 +20,13 @@ /obj/machinery/rnd/Initialize(mapload) . = ..() - stored_research = SSresearch.science_tech + if(!CONFIG_GET(flag/no_default_techweb_link)) + stored_research = SSresearch.science_tech wires = new /datum/wires/rnd(src) +/obj/machinery/rnd/proc/connect_techweb(datum/techweb/new_techweb) + stored_research = new_techweb + /obj/machinery/rnd/Destroy() stored_research = null QDEL_NULL(wires) @@ -59,10 +63,14 @@ /obj/machinery/rnd/screwdriver_act_secondary(mob/living/user, obj/item/tool) return default_deconstruction_screwdriver(user, "[initial(icon_state)]_t", initial(icon_state), tool) -/obj/machinery/rnd/multitool_act(mob/living/user, obj/item/tool) +/obj/machinery/rnd/multitool_act(mob/living/user, obj/item/multitool/tool) if(panel_open) wires.interact(user) return TRUE + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + connect_techweb(tool.buffer) + return TRUE + return FALSE /obj/machinery/rnd/multitool_act_secondary(mob/living/user, obj/item/tool) if(panel_open) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 0206c4b35ed..54589658f3b 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -27,8 +27,10 @@ /obj/machinery/rnd/server/Initialize(mapload) . = ..() - name += " [num2hex(rand(1,65535), -1)]" //gives us a random four-digit hex number as part of the name. Y'know, for fluff. + if(CONFIG_GET(flag/no_default_techweb_link)) + stored_research = new /datum/techweb SSresearch.servers |= src + name += " [num2hex(rand(1,65535), -1)]" //gives us a random four-digit hex number as part of the name. Y'know, for fluff. /obj/machinery/rnd/server/Destroy() SSresearch.servers -= src @@ -94,18 +96,28 @@ return SERVER_NOMINAL_TEXT +/obj/machinery/rnd/server/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!stored_research) + return + tool.buffer = stored_research + to_chat(user, span_notice("Stored [src]'s techweb information in [tool].")) + return TRUE + /obj/machinery/computer/rdservercontrol name = "R&D Server Controller" desc = "Used to manage access to research and manufacturing databases." icon_screen = "rdcomp" icon_keyboard = "rd_key" - var/screen = 0 - var/obj/machinery/rnd/server/temp_server - var/list/servers = list() - var/list/consoles = list() - req_access = list(ACCESS_RD) - var/badmin = 0 circuit = /obj/item/circuitboard/computer/rdservercontrol + req_access = list(ACCESS_RD) + var/list/servers = list() + ///Connected techweb node the server is connected to. + var/datum/techweb/stored_research + +/obj/machinery/computer/rdservercontrol/Initialize(mapload, obj/item/circuitboard/C) + . = ..() + if(!CONFIG_GET(flag/no_default_techweb_link)) + stored_research = SSresearch.science_tech /obj/machinery/computer/rdservercontrol/Topic(href, href_list) if(..()) @@ -128,7 +140,9 @@ dat += "Connected Servers:" dat += "" - for(var/obj/machinery/rnd/server/server in GLOB.machines) + for(var/obj/machinery/rnd/server/server as anything in SSresearch.servers) + if(server.stored_research != stored_research) //not on our servers + continue var/server_info = "" var/status_text = server.get_status_text() @@ -143,11 +157,10 @@ dat += "
ServerStatusControl

" dat += "Research Log
" - var/datum/techweb/stored_research = SSresearch.science_tech - if(length(stored_research.research_logs)) + if(stored_research && length(stored_research.research_logs)) dat += "" dat += "" - for(var/i=stored_research.research_logs.len, i>0, i--) + for(var/i = stored_research.research_logs.len, i>0, i--) dat += "" for(var/j in stored_research.research_logs[i]) dat += "" diff --git a/code/modules/vehicles/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm index 8836b133690..fe7f2083369 100644 --- a/code/modules/vehicles/mecha/mech_fabricator.dm +++ b/code/modules/vehicles/mecha/mech_fabricator.dm @@ -53,17 +53,30 @@ var/list/datum/design/cached_designs /obj/machinery/mecha_part_fabricator/Initialize(mapload) - stored_research = SSresearch.science_tech + if(!CONFIG_GET(flag/no_default_techweb_link)) + connect_techweb(SSresearch.science_tech) rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init, mat_container_flags=BREAKDOWN_FLAGS_LATHE) cached_designs = list() RefreshParts() //Recalculating local material sizes if the fab isn't linked - update_menu_tech() + if(stored_research) + update_menu_tech() + return ..() + +/obj/machinery/mecha_part_fabricator/proc/connect_techweb(datum/techweb/new_techweb) + if(stored_research) + UnregisterSignal(stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN)) + + stored_research = new_techweb RegisterSignal( stored_research, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN), PROC_REF(on_techweb_update) ) - return ..() + +/obj/machinery/mecha_part_fabricator/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + connect_techweb(tool.buffer) + return TRUE /obj/machinery/mecha_part_fabricator/proc/on_techweb_update() SIGNAL_HANDLER @@ -126,7 +139,6 @@ var/previous_design_count = cached_designs.len cached_designs.Cut() - for(var/v in stored_research.researched_designs) var/datum/design/design = SSresearch.techweb_design_by_id(v) diff --git a/code/modules/wiremod/core/component_printer.dm b/code/modules/wiremod/core/component_printer.dm index 139d3b91779..29d64ce79a6 100644 --- a/code/modules/wiremod/core/component_printer.dm +++ b/code/modules/wiremod/core/component_printer.dm @@ -19,8 +19,21 @@ /obj/machinery/component_printer/Initialize(mapload) . = ..() + if(!CONFIG_GET(flag/no_default_techweb_link)) + connect_techweb(SSresearch.science_tech) - techweb = SSresearch.science_tech + materials = AddComponent( \ + /datum/component/remote_materials, \ + "component_printer", \ + mapload, \ + mat_container_flags = BREAKDOWN_FLAGS_LATHE, \ + ) + +/obj/machinery/component_printer/proc/connect_techweb(datum/techweb/new_techweb) + if(techweb) + UnregisterSignal(techweb, list(COMSIG_TECHWEB_ADD_DESIGN, COMSIG_TECHWEB_REMOVE_DESIGN)) + + techweb = new_techweb for (var/researched_design_id in techweb.researched_designs) var/datum/design/design = SSresearch.techweb_design_by_id(researched_design_id) @@ -32,12 +45,10 @@ RegisterSignal(techweb, COMSIG_TECHWEB_ADD_DESIGN, PROC_REF(on_research)) RegisterSignal(techweb, COMSIG_TECHWEB_REMOVE_DESIGN, PROC_REF(on_removed)) - materials = AddComponent( \ - /datum/component/remote_materials, \ - "component_printer", \ - mapload, \ - mat_container_flags = BREAKDOWN_FLAGS_LATHE, \ - ) +/obj/machinery/component_printer/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + connect_techweb(tool.buffer) + return TRUE /obj/machinery/component_printer/proc/on_research(datum/source, datum/design/added_design, custom) SIGNAL_HANDLER diff --git a/config/config.txt b/config/config.txt index c246b86f019..2f57ba97810 100644 --- a/config/config.txt +++ b/config/config.txt @@ -329,6 +329,9 @@ ALLOW_HOLIDAYS ## Uncomment to show the names of the admin sending a pm from IRC instead of showing as a stealthmin. #SHOW_IRC_NAME +## Uncomment to prevent machines syncing to the Science techweb by default. +#NO_DEFAULT_TECHWEB_LINK + ##Defines the ticklag for the world. Ticklag is the amount of time between game ticks (aka byond ticks) (in 1/10ths of a second). ## This also controls the client network update rate, as well as the default client fps TICKLAG 0.5 diff --git a/tgstation.dme b/tgstation.dme index 39a23c1b1f6..07856bd7beb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1505,7 +1505,7 @@ #include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\mechlaunchpad.dm" #include "code\game\machinery\computer\medical.dm" -#include "code\game\machinery\computer\Operating.dm" +#include "code\game\machinery\computer\operating_computer.dm" #include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\robot.dm" #include "code\game\machinery\computer\security.dm" diff --git a/tgui/packages/tgui/interfaces/NtosScipaper.js b/tgui/packages/tgui/interfaces/NtosScipaper.js index aa457625db7..e2f26f1a7c3 100644 --- a/tgui/packages/tgui/interfaces/NtosScipaper.js +++ b/tgui/packages/tgui/interfaces/NtosScipaper.js @@ -335,9 +335,14 @@ const PartnersBrowser = (props, context) => { export const NtosScipaperContent = (props, context) => { const { act, data } = useBackend(context); - const { currentTab } = data; + const { currentTab, has_techweb } = data; return ( <> + {!has_techweb && ( +
+ Please sync this application to a valid techweb to upload progress! +
+ )} abbreviations[name] ?? name; // Actual Components export const Techweb = (props, context) => { - const { act, data } = useRemappedBackend(context); - const { locked } = data; return ( - {!!locked && ( - -
- Console Locked -
- -
- )} - +
); }; +const TechwebStart = (props, context) => { + const { act, data } = useRemappedBackend(context); + const { locked, stored_research } = data; + return ( + <> + {!!locked && ( + +
+ Console Locked +
+ +
+ )} + {!stored_research && ( + +
+ No research techweb found, please synchronize the console. +
+
+ )} + + + ); +}; + export const AppTechweb = (props, context) => { const { act, data } = useRemappedBackend(context); const { locked } = data;
EntryResearch NameCostResearcher NameConsole Location
[i][j]