Job estimation refactor (#4544)

## About The Pull Request
This PR moves the job estimation panel to SSticker, reducing its
performance impact.

No player-facing changes, it'll work exactly the same

## Why It's Good For The Game
The server will hopefully crash less

## Proof Of Testing
<img width="242" height="85" alt="image"
src="https://github.com/user-attachments/assets/535f8e6d-e175-440c-a0d4-1fac5e4d5a51"
/>

## Changelog

🆑 ReturnToZender
refactor: Job estimation now performs better
/🆑
This commit is contained in:
Return
2025-08-26 11:44:28 -07:00
committed by GitHub
parent 08cbc290bd
commit eff9523da9
4 changed files with 50 additions and 50 deletions
+3
View File
@@ -196,12 +196,15 @@ SUBSYSTEM_DEF(ticker)
totalPlayers = LAZYLEN(GLOB.new_player_list)
totalPlayersReady = 0
total_admins_ready = 0
var/list/readied_players = list() //BUBBER EDIT ADDITION
for(var/mob/dead/new_player/player as anything in GLOB.new_player_list)
if(player.ready == PLAYER_READY_TO_PLAY)
readied_players[player.key] = player //BUBBER EDIT: job estimation, filling the readied list we use later
++totalPlayersReady
if(player.client?.holder)
++total_admins_ready
job_estimation_list = get_job_estimation(readied_players) //BUBBER EDIT ADDITION
if(start_immediately)
timeLeft = 0
@@ -0,0 +1,45 @@
/datum/controller/subsystem/ticker
var/list/job_estimation_list = list()
/datum/controller/subsystem/ticker/proc/get_job_estimation(list/players)
var/list/player_ready_data = list()
sortTim(players, GLOBAL_PROC_REF(cmp_text_asc))
for(var/ckey in players)
var/mob/dead/new_player/player = players[ckey]
var/datum/preferences/prefs = player.client?.prefs
var/display = null
var/datum/job/J = prefs?.get_highest_priority_job()
var/title = J?.title
//If a player does not have preferences (for some reason) or they don't want to be shown on the panel, continue
if(!J || !(prefs.read_preference(/datum/preference/toggle/ready_job)))
continue
//If the readied player has selected a miscellaneous job (Assistant, or Prisoner), they shouldn't be displayed
if(title == JOB_ASSISTANT || title == JOB_PRISONER)
continue
//If the job the player is selecting has a special name, that name should be displayed in the menu, otherwise it should use the normal name
switch(title)
if(JOB_AI)
display = prefs.read_preference(/datum/preference/name/ai)
if(JOB_CLOWN)
display = prefs.read_preference(/datum/preference/name/clown)
if(JOB_CYBORG)
display = prefs.read_preference(/datum/preference/name/cyborg)
if(JOB_MIME)
display = prefs.read_preference(/datum/preference/name/mime)
else
display = prefs.read_preference(/datum/preference/name/real_name)
//If our player is a member of Command or a Silicon, we want to sort them to the top of the list. Otherwise, just add them to the end of the list.
if(J.departments_bitflags & (DEPARTMENT_BITFLAG_COMMAND | DEPARTMENT_BITFLAG_SILICON))
player_ready_data.Insert(1, "* [display] as [title]")
else
player_ready_data += "* [display] as [title]"
//The title line for the job estimation panel, obviously needs to be at the top
if(length(player_ready_data))
player_ready_data.Insert(1, "------------------")
player_ready_data.Insert(1, "Job Estimation:")
player_ready_data.Insert(1, "")
return player_ready_data
//BUBBER EDIT END
@@ -17,53 +17,4 @@
.=..()
//Adds the Job Estimation panel to the end of the Statpanel.
if(CONFIG_GET(flag/show_job_estimation))
. += get_job_estimation()
/mob/dead/proc/get_job_estimation()
var/list/player_ready_data = list()
var/list/players = list()
//This fills the readied players list that the job estimation panel uses.
for(var/mob/dead/new_player/player as anything in GLOB.new_player_list)
if(player.ready == PLAYER_READY_TO_PLAY)
players[player.key] = player
sortTim(players, GLOBAL_PROC_REF(cmp_text_asc))
for(var/ckey in players)
var/mob/dead/new_player/player = players[ckey]
var/datum/preferences/prefs = player.client?.prefs
var/display = null
var/datum/job/J = prefs?.get_highest_priority_job()
var/title = J?.title
//If a player does not have preferences (for some reason) or they don't want to be shown on the panel, continue
if(!J || !(prefs.read_preference(/datum/preference/toggle/ready_job)))
continue
//If the readied player has selected a miscellaneous job (Assistant, or Prisoner), they shouldn't be displayed
if(title == JOB_ASSISTANT || title == JOB_PRISONER)
continue
//If the job the player is selecting has a special name, that name should be displayed in the menu, otherwise it should use the normal name
switch(title)
if(JOB_AI)
display = prefs.read_preference(/datum/preference/name/ai)
if(JOB_CLOWN)
display = prefs.read_preference(/datum/preference/name/clown)
if(JOB_CYBORG)
display = prefs.read_preference(/datum/preference/name/cyborg)
if(JOB_MIME)
display = prefs.read_preference(/datum/preference/name/mime)
else
display = prefs.read_preference(/datum/preference/name/real_name)
//If our player is a member of Command or a Silicon, we want to sort them to the top of the list. Otherwise, just add them to the end of the list.
if(J.departments_bitflags & (DEPARTMENT_BITFLAG_COMMAND | DEPARTMENT_BITFLAG_SILICON))
player_ready_data.Insert(1, "* [display] as [title]")
else
player_ready_data += "* [display] as [title]"
//The title line for the job estimation panel, obviously needs to be at the top
if(length(player_ready_data))
player_ready_data.Insert(1, "------------------")
player_ready_data.Insert(1, "Job Estimation:")
player_ready_data.Insert(1, "")
return player_ready_data
. += SSticker.job_estimation_list
+1
View File
@@ -8826,6 +8826,7 @@
#include "modular_zubbers\code\controllers\subsystem\mapping.dm"
#include "modular_zubbers\code\controllers\subsystem\research.dm"
#include "modular_zubbers\code\controllers\subsystem\security_level.dm"
#include "modular_zubbers\code\controllers\subsystem\ticker.dm"
#include "modular_zubbers\code\controllers\subsystem\vote.dm"
#include "modular_zubbers\code\controllers\subsystem\dynamic\dynamic_ruleset_latejoin.dm"
#include "modular_zubbers\code\controllers\subsystem\dynamic\dynamic_ruleset_midround.dm"