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 += "
| Server | Status | Control | "
- 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 += "
"
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 += "| Entry | Research Name | Cost | Researcher Name | Console Location |
"
- for(var/i=stored_research.research_logs.len, i>0, i--)
+ for(var/i = stored_research.research_logs.len, i>0, i--)
dat += "| [i] | "
for(var/j in stored_research.research_logs[i])
dat += "[j] | "
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;