Research queue (#84731)

## About The Pull Request

<img alt="2dZbpr8MK1"
src="https://github.com/tgstation/tgstation/assets/3625094/dd78feba-224a-41a1-8d4a-83af3a8b68df">


Added an ability to queue up to one node per player in a techweb for an
automatic research.

You can queue up a node only when all requirements are met, but there
are not enough points.

People can't research when there is something in the queue, only add
things to the queue. So a 40 points node can't be researched if someone
queued up a 200 points node ahead of it.

When a node is enqueued by RD, it is placed in front of the queue.

The research button is available when the queue is empty.

TODO:

- [x] Bypass queue when the node cost is zero

## Why It's Good For The Game

No need to stay at the console to wait for the points. No "Research"
button spamming.

## Changelog

🆑
qol: Research nodes can be queued, one per player. RDs can place their
node at the beginning of the queue.
/🆑
This commit is contained in:
Andrew
2024-07-15 14:03:24 +12:00
committed by GitHub
parent bb79c3859f
commit 41ff0fbb40
6 changed files with 195 additions and 33 deletions
+28
View File
@@ -96,6 +96,20 @@ Nothing else in the console has ID requirements.
stored_research = tool.buffer
return TRUE
/obj/machinery/computer/rdconsole/proc/enqueue_node(id, mob/user)
if(!stored_research || !stored_research.available_nodes[id] || stored_research.researched_nodes[id])
say("Node enqueue failed: Either no techweb is found, node is already researched or is not available!")
return FALSE
stored_research.enqueue_node(id, user)
return TRUE
/obj/machinery/computer/rdconsole/proc/dequeue_node(id, mob/user)
if(!stored_research || !stored_research.available_nodes[id] || stored_research.researched_nodes[id])
say("Node dequeue failed: Either no techweb is found, node is already researched or is not available!")
return FALSE
stored_research.dequeue_node(id, user)
return TRUE
/obj/machinery/computer/rdconsole/proc/research_node(id, mob/user)
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!")
@@ -171,6 +185,7 @@ Nothing else in the console has ID requirements.
return data
data += list(
"nodes" = list(),
"queue_nodes" = stored_research.research_queue_nodes,
"experiments" = list(),
"researched_designs" = stored_research.researched_designs,
"points" = stored_research.research_points,
@@ -194,6 +209,10 @@ Nothing else in the console has ID requirements.
// Serialize all nodes to display
for(var/v in stored_research.tiers)
var/datum/techweb_node/n = SSresearch.techweb_node_by_id(v)
var/enqueued_by_user = FALSE
if((v in stored_research.research_queue_nodes) && stored_research.research_queue_nodes[v] == user)
enqueued_by_user = TRUE
// Ensure node is supposed to be visible
if (stored_research.hidden_nodes[v])
@@ -201,8 +220,11 @@ Nothing else in the console has ID requirements.
data["nodes"] += list(list(
"id" = n.id,
"is_free" = n.is_free(stored_research),
"can_unlock" = stored_research.can_unlock_node(n),
"have_experiments_done" = stored_research.have_experiments_for_node(n),
"tier" = stored_research.tiers[n.id],
"enqueued_by_user" = enqueued_by_user
))
// Get experiments and serialize them
@@ -322,6 +344,12 @@ Nothing else in the console has ID requirements.
if ("researchNode")
research_node(params["node_id"], usr)
return TRUE
if ("enqueueNode")
enqueue_node(params["node_id"], usr)
return TRUE
if ("dequeueNode")
dequeue_node(params["node_id"], usr)
return TRUE
if ("ejectDisk")
eject_disk(params["type"])
return TRUE
+44
View File
@@ -70,6 +70,12 @@
* Filled with nulls on init, populated only on publication.
*/
var/list/published_papers
/**
* Assoc list of nodes queued for automatic research when there are enough points available
* research_queue_nodes[node_id] = user_enqueued
*/
var/list/research_queue_nodes = list()
/datum/techweb/New()
SSresearch.techwebs += src
@@ -325,6 +331,40 @@
/datum/techweb/proc/printout_points()
return techweb_point_display_generic(research_points)
/datum/techweb/proc/enqueue_node(id, mob/user)
var/mob/living/carbon/human/human_user = user
var/is_rd = FALSE
if(human_user.wear_id)
var/list/access = human_user.wear_id.GetAccess()
if(ACCESS_RD in access)
is_rd = TRUE
if(id in research_queue_nodes)
if(is_rd)
research_queue_nodes.Remove(id)
else
return FALSE
for(var/node_id in research_queue_nodes)
if(research_queue_nodes[node_id] == user)
research_queue_nodes.Remove(node_id)
if (is_rd)
research_queue_nodes.Insert(1, id)
research_queue_nodes[id] = user
return TRUE
/datum/techweb/proc/dequeue_node(id, mob/user)
if(!(id in research_queue_nodes))
return FALSE
if(research_queue_nodes[id] != user)
return FALSE
research_queue_nodes.Remove(id)
return TRUE
/datum/techweb/proc/research_node_id(id, force, auto_update_points, get_that_dosh_id)
return research_node(SSresearch.techweb_node_by_id(id), force, auto_update_points, get_that_dosh_id)
@@ -377,6 +417,10 @@
if (MC_RUNNING())
log_research(log_message)
// Dequeue
if(node.id in research_queue_nodes)
research_queue_nodes.Remove(node.id)
return TRUE
/datum/techweb/proc/unresearch_node_id(id)
@@ -95,6 +95,17 @@
return actual_costs
/datum/techweb_node/proc/is_free(datum/techweb/host)
var/list/costs = get_price(host)
var/total_points = 0
for(var/point_type in costs)
total_points += costs[point_type]
if(total_points == 0)
return TRUE
return FALSE
/datum/techweb_node/proc/price_display(datum/techweb/TN)
return techweb_point_display_generic(get_price(TN))