[RDSCREEN_NOBREAK]"
if (stored_research.researched_nodes[N.id]) // already researched
@@ -639,7 +639,7 @@ Nothing else in the console has ID requirements.
var/list/columns = list()
var/max_tier = 0
for (var/node_ in stored_research.tiers)
- var/datum/techweb_node/node = node_
+ var/datum/techweb_node/node = SSresearch.techweb_node_by_id(node_)
var/tier = stored_research.tiers[node]
LAZYINITLIST(columns["[tier]"]) // String hackery to make the numbers associative
columns["[tier]"] += ui_techweb_single_node(node, minimal=(tier != 1))
@@ -656,15 +656,15 @@ Nothing else in the console has ID requirements.
var/list/unavail = list()
var/list/res = list()
for(var/v in stored_research.researched_nodes)
- res += stored_research.researched_nodes[v]
+ res += SSresearch.techweb_node_by_id(v)
for(var/v in stored_research.available_nodes)
if(stored_research.researched_nodes[v])
continue
- avail += stored_research.available_nodes[v]
+ avail += SSresearch.techweb_node_by_id(v)
for(var/v in stored_research.visible_nodes)
if(stored_research.available_nodes[v])
continue
- unavail += stored_research.visible_nodes[v]
+ unavail += SSresearch.techweb_node_by_id(v)
l += "
[RDSCREEN_NOBREAK]"
return l
/obj/machinery/computer/rdconsole/proc/ui_techweb_nodeview()
+ var/datum/techweb_node/selected_node = SSresearch.techweb_node_by_id(selected_node_id)
RDSCREEN_UI_SNODE_CHECK
var/list/l = list()
if(stored_research.hidden_nodes[selected_node.id])
@@ -720,64 +721,64 @@ Nothing else in the console has ID requirements.
return
l += "
[RDSCREEN_NOBREAK]"
return l
/obj/machinery/computer/rdconsole/proc/ui_techweb_designview() //Legacy code
+ var/datum/design/selected_design = SSresearch.techweb_design_by_id(selected_design_id)
RDSCREEN_UI_SDESIGN_CHECK
var/list/l = list()
- var/datum/design/D = selected_design
- l += "
| [D.icon_html(usr)] | [D.name] |
[RDSCREEN_NOBREAK]"
- if(D.build_type)
+ l += "
| [selected_design.icon_html(usr)] | [selected_design.name] |
[RDSCREEN_NOBREAK]"
+ if(selected_design.build_type)
var/lathes = list()
- if(D.build_type & IMPRINTER)
+ if(selected_design.build_type & IMPRINTER)
lathes += "
[machine_icon(/obj/machinery/rnd/production/circuit_imprinter)][RDSCREEN_NOBREAK]"
- if (linked_imprinter && D.id in stored_research.researched_designs)
- l += "
Imprint"
- if(D.build_type & PROTOLATHE)
+ if (linked_imprinter && stored_research.researched_designs[selected_design.id])
+ l += "
Imprint"
+ if(selected_design.build_type & PROTOLATHE)
lathes += "
[machine_icon(/obj/machinery/rnd/production/protolathe)][RDSCREEN_NOBREAK]"
- if (linked_lathe && D.id in stored_research.researched_designs)
- l += "
Construct"
- if(D.build_type & AUTOLATHE)
+ if (linked_lathe && stored_research.researched_designs[selected_design.id])
+ l += "
Construct"
+ if(selected_design.build_type & AUTOLATHE)
lathes += "
[machine_icon(/obj/machinery/autolathe)][RDSCREEN_NOBREAK]"
- if(D.build_type & MECHFAB)
+ if(selected_design.build_type & MECHFAB)
lathes += "
[machine_icon(/obj/machinery/mecha_part_fabricator)][RDSCREEN_NOBREAK]"
- if(D.build_type & BIOGENERATOR)
+ if(selected_design.build_type & BIOGENERATOR)
lathes += "
[machine_icon(/obj/machinery/biogenerator)][RDSCREEN_NOBREAK]"
- if(D.build_type & LIMBGROWER)
+ if(selected_design.build_type & LIMBGROWER)
lathes += "
[machine_icon(/obj/machinery/limbgrower)][RDSCREEN_NOBREAK]"
- if(D.build_type & SMELTER)
+ if(selected_design.build_type & SMELTER)
lathes += "
[machine_icon(/obj/machinery/mineral/processing_unit)][RDSCREEN_NOBREAK]"
l += "Construction types:"
l += lathes
l += ""
l += "Required materials:"
- var/all_mats = D.materials + D.reagents_list
+ var/all_mats = selected_design.materials + selected_design.reagents_list
for(var/M in all_mats)
l += "* [CallMaterialName(M)] x [all_mats[M]]"
l += "Unlocked by:"
- for (var/node in D.unlocked_by)
+ for (var/node in selected_design.unlocked_by)
l += ui_techweb_single_node(node)
l += "[RDSCREEN_NOBREAK]
"
return l
@@ -1003,12 +1004,12 @@ Nothing else in the console has ID requirements.
return
say("Uploading technology disk.")
t_disk.stored_research.copy_research_to(stored_research)
- if(ls["copy_design"]) //Copy design la from the research holder to the design disk.
+ if(ls["copy_design"]) //Copy design from the research holder to the design disk.
if(QDELETED(d_disk))
say("No Design Disk Inserted!")
return
var/slot = text2num(ls["copy_design"])
- var/datum/design/D = stored_research.researched_designs[ls["copy_design_ID"]]
+ var/datum/design/D = SSresearch.techweb_design_by_id(ls["copy_design_ID"])
if(D)
var/autolathe_friendly = TRUE
if(D.reagents_list.len)
@@ -1035,12 +1036,12 @@ Nothing else in the console has ID requirements.
linked_destroy.unload_item()
screen = RDSCREEN_MENU
if(ls["view_node"])
- selected_node = SSresearch.techweb_nodes[ls["view_node"]]
+ selected_node_id = ls["view_node"]
screen = RDSCREEN_TECHWEB_NODEVIEW
if(ls["view_design"])
- selected_design = SSresearch.techweb_designs[ls["view_design"]]
+ selected_design_id = ls["view_design"]
screen = RDSCREEN_TECHWEB_DESIGNVIEW
- if(ls["updt_design"]) //Uples the research holder with design la from the design disk.
+ if(ls["updt_design"]) //Uploads a design from disk to the techweb.
if(QDELETED(d_disk))
say("No design disk found.")
return
@@ -1048,9 +1049,9 @@ Nothing else in the console has ID requirements.
if(!n)
for(var/D in d_disk.blueprints)
if(D)
- stored_research.add_design(D)
+ stored_research.add_design(D, TRUE)
else
- stored_research.add_design(d_disk.blueprints[n])
+ stored_research.add_design(d_disk.blueprints[n], TRUE)
updateUsrDialog()
@@ -1079,17 +1080,17 @@ Nothing else in the console has ID requirements.
/obj/machinery/computer/rdconsole/proc/rescan_views()
var/compare
- matching_designs.Cut()
+ matching_design_ids.Cut()
if(searchtype == "proto")
compare = PROTOLATHE
else if(searchtype == "imprint")
compare = IMPRINTER
for(var/v in stored_research.researched_designs)
- var/datum/design/D = stored_research.researched_designs[v]
+ var/datum/design/D = SSresearch.techweb_design_by_id(v)
if(!(D.build_type & compare))
continue
if(findtext(D.name,searchstring))
- matching_designs.Add(D)
+ matching_design_ids.Add(D.id)
/obj/machinery/computer/rdconsole/proc/check_canprint(datum/design/D, buildtype)
var/amount = 50
diff --git a/code/modules/research/techweb/__techweb_helpers.dm b/code/modules/research/techweb/__techweb_helpers.dm
index 1e90f0f28d92..6c967c09245b 100644
--- a/code/modules/research/techweb/__techweb_helpers.dm
+++ b/code/modules/research/techweb/__techweb_helpers.dm
@@ -1,48 +1,3 @@
-
-/proc/initialize_all_techweb_nodes(clearall = FALSE)
- if(islist(SSresearch.techweb_nodes) && clearall)
- QDEL_LIST(SSresearch.techweb_nodes)
- if(islist(SSresearch.techweb_nodes_starting && clearall))
- QDEL_LIST(SSresearch.techweb_nodes_starting)
- var/list/returned = list()
- for(var/path in subtypesof(/datum/techweb_node))
- var/datum/techweb_node/TN = path
- if(isnull(initial(TN.id)))
- continue
- TN = new path
- if(returned[initial(TN.id)])
- stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected!")
- SSresearch.errored_datums[TN] = initial(TN.id)
- continue
- returned[initial(TN.id)] = TN
- if(TN.starting_node)
- SSresearch.techweb_nodes_starting[TN.id] = TN
- SSresearch.techweb_nodes = returned
- verify_techweb_nodes() //Verify all nodes have ids and such.
- calculate_techweb_nodes()
- calculate_techweb_boost_list()
- verify_techweb_nodes() //Verify nodes and designs have been crosslinked properly.
-
-/proc/initialize_all_techweb_designs(clearall = FALSE)
- if(islist(SSresearch.techweb_designs) && clearall)
- QDEL_LIST(SSresearch.techweb_designs)
- var/list/returned = list()
- for(var/path in subtypesof(/datum/design))
- var/datum/design/DN = path
- if(isnull(initial(DN.id)))
- stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]")
- continue
- else if(initial(DN.id) == DESIGN_ID_IGNORE)
- continue
- DN = new path
- if(returned[initial(DN.id)])
- stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected!")
- SSresearch.errored_datums[DN] = initial(DN.id)
- continue
- returned[initial(DN.id)] = DN
- SSresearch.techweb_designs = returned
- verify_techweb_designs()
-
/proc/count_unique_techweb_nodes()
var/static/list/L = typesof(/datum/techweb_node)
return L.len
@@ -51,135 +6,10 @@
var/static/list/L = typesof(/datum/design)
return L.len
-/proc/get_techweb_node_by_id(id)
- if(SSresearch.techweb_nodes[id])
- return SSresearch.techweb_nodes[id]
-
-/proc/get_techweb_design_by_id(id)
- if(SSresearch.techweb_designs[id])
- return SSresearch.techweb_designs[id]
-
-/proc/research_node_id_error(id)
- if(SSresearch.invalid_node_ids[id])
- SSresearch.invalid_node_ids[id]++
- else
- SSresearch.invalid_node_ids[id] = 1
-
-/proc/design_id_error(id)
- if(SSresearch.invalid_design_ids[id])
- SSresearch.invalid_design_ids[id]++
- else
- SSresearch.invalid_design_ids[id] = 1
-
/proc/node_boost_error(id, message)
WARNING("Invalid boost information for node \[[id]\]: [message]")
SSresearch.invalid_node_boost[id] = message
-/proc/verify_techweb_nodes()
- for(var/n in SSresearch.techweb_nodes)
- var/datum/techweb_node/N = SSresearch.techweb_nodes[n]
- if(!istype(N))
- WARNING("Invalid research node with ID [n] detected and removed.")
- SSresearch.techweb_nodes -= n
- research_node_id_error(n)
- for(var/p in N.prereq_ids)
- var/datum/techweb_node/P = SSresearch.techweb_nodes[p]
- if(!istype(P))
- WARNING("Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.")
- N.prereq_ids -= p
- research_node_id_error(p)
- for(var/d in N.design_ids)
- var/datum/design/D = SSresearch.techweb_designs[d]
- if(!istype(D))
- WARNING("Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.")
- N.designs -= d
- design_id_error(d)
- for(var/p in N.prerequisites)
- var/datum/techweb_node/P = N.prerequisites[p]
- if(!istype(P))
- WARNING("Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.")
- N.prerequisites -= p
- research_node_id_error(p)
- for(var/u in N.unlocks)
- var/datum/techweb_node/U = N.unlocks[u]
- if(!istype(U))
- WARNING("Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.")
- N.unlocks -= u
- research_node_id_error(u)
- for(var/d in N.designs)
- var/datum/design/D = N.designs[d]
- if(!istype(D))
- WARNING("Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.")
- N.designs -= d
- design_id_error(d)
- for(var/p in N.boost_item_paths)
- if(!ispath(p))
- N.boost_item_paths -= p
- node_boost_error(N.id, "[p] is not a valid path.")
- var/list/points = N.boost_item_paths[p]
- if(islist(points))
- for(var/i in points)
- if(!isnum(points[i]))
- node_boost_error(N.id, "[points[i]] is not a valid number.")
- else if(!SSresearch.point_types[i])
- node_boost_error(N.id, "[i] is not a valid point type.")
- else if(!isnull(points))
- N.boost_item_paths -= p
- node_boost_error(N.id, "No valid list.")
- CHECK_TICK
-
-/proc/verify_techweb_designs()
- for(var/d in SSresearch.techweb_designs)
- var/datum/design/D = SSresearch.techweb_designs[d]
- if(!istype(D))
- stack_trace("WARNING: Invalid research design with ID [d] detected and removed.")
- SSresearch.techweb_designs -= d
- CHECK_TICK
-
-/proc/calculate_techweb_nodes()
- for(var/design_id in SSresearch.techweb_designs)
- var/datum/design/D = SSresearch.techweb_designs[design_id]
- D.unlocked_by.Cut()
- for(var/node_id in SSresearch.techweb_nodes)
- var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id]
- node.prerequisites = list()
- node.unlocks = list()
- node.designs = list()
- for(var/i in node.prereq_ids)
- node.prerequisites[i] = SSresearch.techweb_nodes[i]
- for(var/i in node.design_ids)
- var/datum/design/D = SSresearch.techweb_designs[i]
- node.designs[i] = D
- D.unlocked_by += node
- if(node.hidden)
- SSresearch.techweb_nodes_hidden[node.id] = node
- CHECK_TICK
- generate_techweb_unlock_linking()
-
-/proc/generate_techweb_unlock_linking()
- for(var/node_id in SSresearch.techweb_nodes) //Clear all unlock links to avoid duplication.
- var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id]
- node.unlocks = list()
- for(var/node_id in SSresearch.techweb_nodes)
- var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id]
- for(var/prereq_id in node.prerequisites)
- var/datum/techweb_node/prereq_node = node.prerequisites[prereq_id]
- prereq_node.unlocks[node.id] = node
-
-/proc/calculate_techweb_boost_list(clearall = FALSE)
- if(clearall)
- SSresearch.techweb_boost_items = list()
- for(var/node_id in SSresearch.techweb_nodes)
- var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id]
- for(var/path in node.boost_item_paths)
- if(!ispath(path))
- continue
- if(length(SSresearch.techweb_boost_items[path]))
- SSresearch.techweb_boost_items[path][node.id] = node.boost_item_paths[path]
- else
- SSresearch.techweb_boost_items[path] = list(node.id = node.boost_item_paths[path])
- CHECK_TICK
-
/proc/techweb_item_boost_check(obj/item/I) //Returns an associative list of techweb node datums with values of the boost it gives. var/list/returned = list()
if(SSresearch.techweb_boost_items[I.type])
return SSresearch.techweb_boost_items[I.type] //It should already be formatted in node datum = list(point type = value)
diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm
index c910f3c8964a..a5d3afd3fb52 100644
--- a/code/modules/research/techweb/_techweb.dm
+++ b/code/modules/research/techweb/_techweb.dm
@@ -5,12 +5,13 @@
//Techweb datums are meant to store unlocked research, being able to be stored on research consoles, servers, and disks. They are NOT global.
/datum/techweb
- var/list/datum/techweb_node/researched_nodes = list() //Already unlocked and all designs are now available. Assoc list, id = datum
- var/list/datum/techweb_node/visible_nodes = list() //Visible nodes, doesn't mean it can be researched. Assoc list, id = datum
- var/list/datum/techweb_node/available_nodes = list() //Nodes that can immediately be researched, all reqs met. assoc list, id = datum
- var/list/datum/design/researched_designs = list() //Designs that are available for use. Assoc list, id = datum
- var/list/datum/techweb_node/boosted_nodes = list() //Already boosted nodes that can't be boosted again. node datum = path of boost object.
- var/list/datum/techweb_node/hidden_nodes = list() //Hidden nodes. id = datum. Used for unhiding nodes when requirements are met by removing the entry of the node.
+ var/list/researched_nodes = list() //Already unlocked and all designs are now available. Assoc list, id = TRUE
+ var/list/visible_nodes = list() //Visible nodes, doesn't mean it can be researched. Assoc list, id = TRUE
+ var/list/available_nodes = list() //Nodes that can immediately be researched, all reqs met. assoc list, id = TRUE
+ var/list/researched_designs = list() //Designs that are available for use. Assoc list, id = TRUE
+ var/list/custom_designs = list() //Custom inserted designs like from disks that should survive recalculation.
+ var/list/boosted_nodes = list() //Already boosted nodes that can't be boosted again. node id = path of boost object.
+ var/list/hidden_nodes = list() //Hidden nodes. id = TRUE. Used for unhiding nodes when requirements are met by removing the entry of the node.
var/list/deconstructed_items = list() //items already deconstructed for a generic point boost. path = list(point_type = points)
var/list/research_points = list() //Available research points. type = number
var/list/obj/machinery/computer/rdconsole/consoles_accessing = list()
@@ -19,13 +20,14 @@
var/largest_bomb_value = 0
var/organization = "Third-Party" //Organization name, used for display.
var/list/last_bitcoins = list() //Current per-second production, used for display only.
- var/list/tiers = list() //Assoc list, datum = number, 1 is available, 2 is all reqs are 1, so on
+ var/list/tiers = list() //Assoc list, id = number, 1 is available, 2 is all reqs are 1, so on
/datum/techweb/New()
+ SSresearch.techwebs += src
for(var/i in SSresearch.techweb_nodes_starting)
- var/datum/techweb_node/DN = SSresearch.techweb_nodes_starting[i]
+ var/datum/techweb_node/DN = SSresearch.techweb_node_by_id(i)
research_node(DN, TRUE, FALSE)
- hidden_nodes = SSresearch.techweb_nodes_hidden
+ hidden_nodes = SSresearch.techweb_nodes_hidden.Copy()
return ..()
/datum/techweb/admin
@@ -50,23 +52,24 @@
researched_designs = null
available_nodes = null
visible_nodes = null
+ custom_designs = null
+ SSresearch.techwebs -= src
return ..()
-/datum/techweb/proc/recalculate_nodes(recalculate_designs = FALSE)
+/datum/techweb/proc/recalculate_nodes(recalculate_designs = FALSE, wipe_custom_designs = FALSE)
var/list/datum/techweb_node/processing = list()
- for(var/i in researched_nodes)
- processing[i] = researched_nodes[i]
- for(var/i in visible_nodes)
- processing[i] = visible_nodes[i]
- for(var/i in available_nodes)
- processing[i] = available_nodes[i]
- for(var/i in processing)
- update_node_status(processing[i])
- if(recalculate_designs) //Wipes custom added designs like from design disks or anything like that!
- researched_designs = list()
- for(var/i in processing)
- var/datum/techweb_node/TN = processing[i]
- update_node_status(TN, FALSE)
+ for(var/id in researched_nodes)
+ processing[id] = TRUE
+ for(var/id in visible_nodes)
+ processing[id] = TRUE
+ for(var/id in available_nodes)
+ processing[id] = TRUE
+ if(recalculate_designs)
+ researched_designs = custom_designs.Copy()
+ if(wipe_custom_designs)
+ custom_designs = list()
+ for(var/id in processing)
+ update_node_status(SSresearch.techweb_node_by_id(id), FALSE)
CHECK_TICK
for(var/v in consoles_accessing)
var/obj/machinery/computer/rdconsole/V = v
@@ -155,21 +158,27 @@
return FALSE
research_points[type] = max(0, research_points[type] - amount)
return TRUE
-/datum/techweb/proc/add_design_by_id(id)
- return add_design(get_techweb_design_by_id(id))
-/datum/techweb/proc/add_design(datum/design/design)
+/datum/techweb/proc/add_design_by_id(id, custom = FALSE)
+ return add_design(SSresearch.techweb_design_by_id(id), custom)
+
+/datum/techweb/proc/add_design(datum/design/design, custom = FALSE)
if(!istype(design))
return FALSE
- researched_designs[design.id] = design
+ researched_designs[design.id] = TRUE
+ if(custom)
+ custom_designs[design.id] = TRUE
return TRUE
-/datum/techweb/proc/remove_design_by_id(id)
- return remove_design(get_techweb_design_by_id(id))
+/datum/techweb/proc/remove_design_by_id(id, custom = FALSE)
+ return remove_design(SSresearch.techweb_design_by_id(id), custom)
-/datum/techweb/proc/remove_design(datum/design/design)
+/datum/techweb/proc/remove_design(datum/design/design, custom = FALSE)
if(!istype(design))
return FALSE
+ if(custom_designs[design.id] && !custom)
+ return FALSE
+ custom_designs -= design.id
researched_designs -= design.id
return TRUE
@@ -187,7 +196,7 @@
return techweb_point_display_generic(research_points)
/datum/techweb/proc/research_node_id(id, force, auto_update_points)
- return research_node(get_techweb_node_by_id(id), force, auto_update_points)
+ return research_node(SSresearch.techweb_node_by_id(id), force, auto_update_points)
/datum/techweb/proc/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE)
if(!istype(node))
@@ -198,12 +207,12 @@
return FALSE
if(auto_adjust_cost)
remove_point_list(node.get_price(src))
- researched_nodes[node.id] = node //Add to our researched list
- for(var/i in node.unlocks)
- visible_nodes[i] = node.unlocks[i]
- update_node_status(node.unlocks[i])
- for(var/i in node.designs)
- add_design(node.designs[i])
+ researched_nodes[node.id] = TRUE //Add to our researched list
+ for(var/id in node.unlock_ids)
+ visible_nodes[id] = TRUE
+ update_node_status(SSresearch.techweb_node_by_id(id))
+ for(var/id in node.design_ids)
+ add_design_by_id(id)
update_node_status(node)
if(!istype(src, /datum/techweb/admin))
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_SCI)
@@ -212,7 +221,7 @@
return TRUE
/datum/techweb/proc/unresearch_node_id(id)
- return unresearch_node(get_techweb_node_by_id(id))
+ return unresearch_node(SSresearch.techweb_node_by_id(id))
/datum/techweb/proc/unresearch_node(datum/techweb_node/node)
if(!istype(node))
@@ -223,9 +232,9 @@
/datum/techweb/proc/boost_with_path(datum/techweb_node/N, itempath)
if(!istype(N) || !ispath(itempath))
return FALSE
- LAZYINITLIST(boosted_nodes[N])
+ LAZYINITLIST(boosted_nodes[N.id])
for(var/i in N.boost_item_paths[itempath])
- boosted_nodes[N][i] = max(boosted_nodes[N][i], N.boost_item_paths[itempath][i])
+ boosted_nodes[N.id][i] = max(boosted_nodes[N.id][i], N.boost_item_paths[itempath][i])
if(N.autounlock_by_boost)
hidden_nodes -= N.id
update_node_status(N)
@@ -240,13 +249,13 @@
var/tier = 0
if (!researched_nodes[node.id]) // researched is tier 0
for (var/id in node.prereq_ids)
- var/prereq_tier = tiers[node.prerequisites[id]]
+ var/prereq_tier = tiers[id]
tier = max(tier, prereq_tier + 1)
- if (tier != tiers[node])
- tiers[node] = tier
- for (var/id in node.unlocks)
- next += node.unlocks[id]
+ if (tier != tiers[node.id])
+ tiers[node.id] = tier
+ for (var/id in node.unlock_ids)
+ next += SSresearch.techweb_node_by_id(id)
current = next
/datum/techweb/proc/update_node_status(datum/techweb_node/node, autoupdate_consoles = TRUE)
@@ -256,8 +265,8 @@
if(researched_nodes[node.id])
researched = TRUE
var/needed = node.prereq_ids.len
- for(var/i in node.prereq_ids)
- if(researched_nodes[i])
+ for(var/id in node.prereq_ids)
+ if(researched_nodes[id])
visible = TRUE
needed--
if(!needed)
@@ -268,15 +277,15 @@
if(hidden_nodes[node.id]) //Hidden.
return
if(researched)
- researched_nodes[node.id] = node
- for(var/i in node.designs)
- add_design(node.designs[i])
+ researched_nodes[node.id] = TRUE
+ for(var/id in node.design_ids)
+ add_design(SSresearch.techweb_design_by_id(id))
else
if(available)
- available_nodes[node.id] = node
+ available_nodes[node.id] = TRUE
else
if(visible)
- visible_nodes[node.id] = node
+ visible_nodes[node.id] = TRUE
update_tiers(node)
if(autoupdate_consoles)
for(var/v in consoles_accessing)
@@ -287,35 +296,34 @@
//Laggy procs to do specific checks, just in case. Don't use them if you can just use the vars that already store all this!
/datum/techweb/proc/designHasReqs(datum/design/D)
for(var/i in researched_nodes)
- var/datum/techweb_node/N = researched_nodes[i]
- for(var/I in N.designs)
- if(D == N.designs[I])
- return TRUE
+ var/datum/techweb_node/N = SSresearch.techweb_node_by_id(i)
+ if(N.design_ids[D.id])
+ return TRUE
return FALSE
/datum/techweb/proc/isDesignResearched(datum/design/D)
return isDesignResearchedID(D.id)
/datum/techweb/proc/isDesignResearchedID(id)
- return researched_designs[id]
+ return researched_designs[id]? SSresearch.techweb_design_by_id(id) : FALSE
/datum/techweb/proc/isNodeResearched(datum/techweb_node/N)
return isNodeResearchedID(N.id)
/datum/techweb/proc/isNodeResearchedID(id)
- return researched_nodes[id]
+ return researched_nodes[id]? SSresearch.techweb_node_by_id(id) : FALSE
/datum/techweb/proc/isNodeVisible(datum/techweb_node/N)
return isNodeResearchedID(N.id)
/datum/techweb/proc/isNodeVisibleID(id)
- return visible_nodes[id]
+ return visible_nodes[id]? SSresearch.techweb_node_by_id(id) : FALSE
/datum/techweb/proc/isNodeAvailable(datum/techweb_node/N)
return isNodeAvailableID(N.id)
/datum/techweb/proc/isNodeAvailableID(id)
- return available_nodes[id]
+ return available_nodes[id]? SSresearch.techweb_node_by_id(id) : FALSE
/datum/techweb/specialized
var/allowed_buildtypes = ALL
@@ -338,11 +346,11 @@
for(var/id in node_autounlock_ids)
research_node_id(id, TRUE, FALSE)
for(var/id in SSresearch.techweb_designs)
- var/datum/design/D = SSresearch.techweb_designs[id]
+ var/datum/design/D = SSresearch.techweb_design_by_id(id)
if(D.build_type & design_autounlock_buildtypes)
for(var/i in D.category)
if(i in design_autounlock_categories)
- add_design(D)
+ add_design_by_id(D.id)
break
/datum/techweb/specialized/autounlocking/autolathe
diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm
index 875329a89c28..bd6aea0a3301 100644
--- a/code/modules/research/techweb/_techweb_node.dm
+++ b/code/modules/research/techweb/_techweb_node.dm
@@ -1,5 +1,6 @@
//Techweb nodes are GLOBAL, there should only be one instance of them in the game. Persistant changes should never be made to them in-game.
+//USE SSRESEARCH PROCS TO OBTAIN REFERENCES. DO NOT REFERENCE OUTSIDE OF SSRESEARCH OR YOU WILL FUCK UP GC.
/datum/techweb_node
var/id
@@ -9,20 +10,82 @@
var/starting_node = FALSE //Whether it's available without any research.
var/list/prereq_ids = list()
var/list/design_ids = list()
- var/list/datum/techweb_node/prerequisites = list() //Assoc list id = datum
- var/list/datum/techweb_node/unlocks = list() //CALCULATED FROM OTHER NODE'S PREREQUISITES. Assoc list id = datum.
- var/list/datum/design/designs = list() //Assoc list id = datum
+ var/list/unlock_ids = list() //CALCULATED FROM OTHER NODE'S PREREQUISITES. Assoc list id = TRUE.
var/list/boost_item_paths = list() //Associative list, path = list(point type = point_value).
var/autounlock_by_boost = TRUE //boosting this will autounlock this node.
var/export_price = 0 //Cargo export price.
- var/list/research_costs = 0 //Point cost to research. type = amount
+ var/list/research_costs = list() //Point cost to research. type = amount
var/category = "Misc" //Category
+/datum/techweb_node/error_node
+ id = "ERROR"
+ display_name = "ERROR"
+ description = "This usually means something in the database has corrupted. If it doesn't go away automatically, inform Central Command for their techs to fix it ASAP(tm)"
+
+/datum/techweb_node/proc/Initialize()
+ //Make lists associative for lookup
+ for(var/id in prereq_ids)
+ prereq_ids[id] = TRUE
+ for(var/id in design_ids)
+ design_ids[id] = TRUE
+ for(var/id in unlock_ids)
+ unlock_ids[id] = TRUE
+
+/datum/techweb_node/Destroy()
+ SSresearch.techweb_nodes -= id
+ return ..()
+
+/datum/techweb_node/serialize_list(list/options)
+ . = list()
+ VARSET_TO_LIST(., id)
+ VARSET_TO_LIST(., display_name)
+ VARSET_TO_LIST(., hidden)
+ VARSET_TO_LIST(., starting_node)
+ VARSET_TO_LIST(., assoc_list_strip_value(prereq_ids))
+ VARSET_TO_LIST(., assoc_list_strip_value(design_ids))
+ VARSET_TO_LIST(., assoc_list_strip_value(unlock_ids))
+ VARSET_TO_LIST(., boost_item_paths)
+ VARSET_TO_LIST(., autounlock_by_boost)
+ VARSET_TO_LIST(., export_price)
+ VARSET_TO_LIST(., research_costs)
+ VARSET_TO_LIST(., category)
+
+/datum/techweb_node/deserialize_list(list/input, list/options)
+ if(!input["id"])
+ return
+ VARSET_FROM_LIST(input, id)
+ VARSET_FROM_LIST(input, display_name)
+ VARSET_FROM_LIST(input, hidden)
+ VARSET_FROM_LIST(input, starting_node)
+ VARSET_FROM_LIST(input, prereq_ids)
+ VARSET_FROM_LIST(input, design_ids)
+ VARSET_FROM_LIST(input, unlock_ids)
+ VARSET_FROM_LIST(input, boost_item_paths)
+ VARSET_FROM_LIST(input, autounlock_by_boost)
+ VARSET_FROM_LIST(input, export_price)
+ VARSET_FROM_LIST(input, research_costs)
+ VARSET_FROM_LIST(input, category)
+ Initialize()
+ return src
+
+/datum/techweb_node/proc/on_design_deletion(datum/design/D)
+ prune_design_id(D.id)
+
+/datum/techweb_node/proc/on_node_deletion(datum/techweb_node/TN)
+ prune_node_id(TN.id)
+
+/datum/techweb_node/proc/prune_design_id(design_id)
+ design_ids -= design_id
+
+/datum/techweb_node/proc/prune_node_id(node_id)
+ prereq_ids -= node_id
+ unlock_ids -= node_id
+
/datum/techweb_node/proc/get_price(datum/techweb/host)
if(host)
var/list/actual_costs = research_costs
- if(host.boosted_nodes[src])
- var/list/L = host.boosted_nodes[src]
+ if(host.boosted_nodes[id])
+ var/list/L = host.boosted_nodes[id]
for(var/i in L)
if(actual_costs[i])
actual_costs[i] -= L[i]