diff --git a/code/__DEFINES/living.dm b/code/__DEFINES/living.dm
index ef46ae475aa0..d256bb7de448 100644
--- a/code/__DEFINES/living.dm
+++ b/code/__DEFINES/living.dm
@@ -67,3 +67,11 @@
#define TRAIT_ROBOTIC_LIMBATTACHMENT "trait_robotic_limbattachment"
#define COLOR_BLOOD "#c90000"
+
+// Used in ready menu anominity
+/// Hide ckey
+#define CKEY_ANON (1<<0)
+/// Hide character name
+#define NAME_ANON (1<<1)
+/// Hide top job preference
+#define JOB_ANON (1<<2)
diff --git a/code/_onclick/hud/new_player.dm b/code/_onclick/hud/new_player.dm
index 5fa44b7f0542..d0b428560eae 100644
--- a/code/_onclick/hud/new_player.dm
+++ b/code/_onclick/hud/new_player.dm
@@ -211,10 +211,10 @@
var/mob/dead/new_player/new_player = hud.mymob
ready = !ready
if(ready)
- new_player.ready = PLAYER_READY_TO_PLAY
+ new_player.ready()
base_icon_state = "ready"
else
- new_player.ready = PLAYER_NOT_READY
+ new_player.unready()
base_icon_state = "not_ready"
update_appearance(UPDATE_ICON)
SEND_SIGNAL(hud, COMSIG_HUD_PLAYER_READY_TOGGLE)
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 63dd8adbd1bc..605b30ccb7fe 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -666,7 +666,7 @@ SUBSYSTEM_DEF(job)
unassigned -= player
if(!run_divide_occupation_pure)
to_chat(player, "You have failed to qualify for any job you desired.")
- player.ready = PLAYER_NOT_READY
+ player.unready()
/datum/controller/subsystem/job/Recover()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 2e8477907d60..0ae02211af60 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -45,6 +45,8 @@ SUBSYSTEM_DEF(ticker)
var/totalPlayersReady = 0
/// Num of ready admins, used for pregame stats on statpanel (only viewable by admins)
var/total_admins_ready = 0
+ /// List of what everyone is ready up as, assoc new player - string
+ var/list/ready_report = list()
var/queue_delay = 0
var/list/queued_players = list() //used for join queues when the server exceeds the hard population cap
diff --git a/code/modules/client/preferences/middleware/jobs.dm b/code/modules/client/preferences/middleware/jobs.dm
index 201e57668ea6..b5a363c29549 100644
--- a/code/modules/client/preferences/middleware/jobs.dm
+++ b/code/modules/client/preferences/middleware/jobs.dm
@@ -23,6 +23,10 @@
preferences.character_preview_view?.update_body()
+ if(isnewplayer(user))
+ var/mob/dead/new_player/cycle = user
+ cycle.update_ready_report()
+
return TRUE
/datum/preference_middleware/jobs/get_constant_data()
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 15ba900b756a..ad271562e8ec 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -326,6 +326,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
all_quirks = SSquirks.filter_invalid_quirks(SANITIZE_LIST(all_quirks))
validate_quirks()
+ if(isnewplayer(parent?.mob))
+ // Update the report that appears in ready menu if applicable
+ // (Yeah I could signalize this but whatever)
+ var/mob/dead/new_player/cycle = parent?.mob
+ cycle.update_ready_report()
+
return TRUE
/datum/preferences/proc/save_character()
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index 615eb55898c9..695342121b2e 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -41,9 +41,11 @@ INITIALIZE_IMMEDIATE(/mob/dead)
. += "Time To Start: SOON"
. += "Players: [LAZYLEN(GLOB.clients)]"
- if(client.holder)
- . += "Players Ready: [SSticker.totalPlayersReady]"
- . += "Admins Ready: [SSticker.total_admins_ready] / [length(GLOB.admins)]"
+ if(length(SSticker.ready_report))
+ . += ""
+ . += "[SSticker.totalPlayersReady] Readied players:"
+ for(var/readied in SSticker.ready_report)
+ . += "- [SSticker.ready_report[readied]]"
#define SERVER_HOPPER_TRAIT "server_hopper"
diff --git a/code/modules/mob/dead/new_player/logout.dm b/code/modules/mob/dead/new_player/logout.dm
index 45412c994bfe..a4caee535f1b 100644
--- a/code/modules/mob/dead/new_player/logout.dm
+++ b/code/modules/mob/dead/new_player/logout.dm
@@ -1,5 +1,5 @@
/mob/dead/new_player/Logout()
- ready = 0
+ unready()
..()
if(!spawning)//Here so that if they are spawning and log out, the other procs can play out and they will have a mob to come back to.
key = null//We null their key before deleting the mob, so they are properly kicked out.
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 3ece09a7a929..fd27adeab379 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -67,7 +67,7 @@
//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
/mob/dead/new_player/proc/make_me_an_observer()
if(QDELETED(src) || !src.client)
- ready = PLAYER_NOT_READY
+ unready()
return FALSE
var/less_input_message
@@ -76,7 +76,6 @@
// Don't convert this to tgui please, it's way too important
var/this_is_like_playing_right = alert(usr, "Are you sure you wish to observe? You will not be able to play this round![less_input_message]", "Observe", "Yes", "No")
if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
- ready = PLAYER_NOT_READY
return FALSE
var/mob/dead/observer/observer = new()
@@ -320,7 +319,7 @@
if(!ineligible_for_roles)
to_chat(src, span_danger("You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences."))
ineligible_for_roles = TRUE
- ready = PLAYER_NOT_READY
+ unready()
if(has_antags)
log_admin("[src.ckey] has no jobs enabled, return to lobby if job is unavailable enabled and [client.prefs.be_special.len] antag preferences enabled. The player has been forcefully returned to the lobby.")
message_admins("[src.ckey] has no jobs enabled, return to lobby if job is unavailable enabled and [client.prefs.be_special.len] antag preferences enabled. This is an old antag rolling technique. The player has been asked to update their job preferences and has been forcefully returned to the lobby.")
@@ -369,4 +368,50 @@
to_chat(new_player, span_info("Lobby Menu HUD reset. You may reset the HUD again in [DisplayTimeText(RESET_HUD_INTERVAL)]."))
hud_used.show_hud(hud_used.hud_version)
+/mob/dead/new_player/proc/ready()
+ if(ready == PLAYER_READY_TO_PLAY)
+ return
+ ready = PLAYER_READY_TO_PLAY
+ update_ready_report()
+
+/mob/dead/new_player/proc/update_ready_report()
+ if(ready != PLAYER_READY_TO_PLAY)
+ return
+ var/datum/job/my_job = client?.prefs?.get_highest_priority_job()
+ var/my_name
+ var/name_pref = /datum/preference/name/real_name
+ var/datum/preference/choiced/ready_anominity/the_pref = GLOB.preference_entries[/datum/preference/choiced/ready_anominity]
+ var/anominity = the_pref.value_list[client?.prefs?.read_preference(/datum/preference/choiced/ready_anominity)] || NONE
+
+ // This sucks and should be moved to the job datums
+ switch(my_job?.type)
+ if(/datum/job/clown)
+ name_pref = /datum/preference/name/clown
+ if(/datum/job/mime)
+ name_pref = /datum/preference/name/mime
+ if(/datum/job/ai)
+ name_pref = /datum/preference/name/ai
+ if(/datum/job/cyborg)
+ name_pref = /datum/preference/name/cyborg
+ // Spoilers. Also this sucks as well
+ if(my_job.type == /datum/job/stowaway)
+ my_job = null
+
+ my_name += (anominity & CKEY_ANON) ? "Anonymous" : "[ckey]"
+ my_name += " / "
+ my_name += (anominity & NAME_ANON) ? "Anonymous" : "[client?.prefs?.read_preference(name_pref) || "Unknown"]"
+ my_name += " / "
+ my_name += (anominity & JOB_ANON) ? "Anonymous" : "[my_job?.title || "No job"]"
+ SSticker.ready_report[src] = my_name
+
+/mob/dead/new_player/proc/unready()
+ if(ready == PLAYER_NOT_READY)
+ return
+ ready = PLAYER_NOT_READY
+ SSticker.ready_report -= src
+
+/mob/dead/new_player/Destroy()
+ SSticker.ready_report -= src // should be redundant but just in case.
+ return ..()
+
#undef RESET_HUD_INTERVAL
diff --git a/maplestation.dme b/maplestation.dme
index 24ded6fe9583..ac39aab6f039 100644
--- a/maplestation.dme
+++ b/maplestation.dme
@@ -6256,6 +6256,7 @@
#include "maplestation_modules\code\modules\client\preferences\loadout_preference.dm"
#include "maplestation_modules\code\modules\client\preferences\multiline_preferences.dm"
#include "maplestation_modules\code\modules\client\preferences\name_preferences.dm"
+#include "maplestation_modules\code\modules\client\preferences\ready_anominity.dm"
#include "maplestation_modules\code\modules\client\preferences\runechat_color.dm"
#include "maplestation_modules\code\modules\client\preferences\sound_frequency.dm"
#include "maplestation_modules\code\modules\client\preferences\toggle_radio.dm"
diff --git a/maplestation_modules/code/modules/client/preferences/ready_anominity.dm b/maplestation_modules/code/modules/client/preferences/ready_anominity.dm
new file mode 100644
index 000000000000..a0d947e3b398
--- /dev/null
+++ b/maplestation_modules/code/modules/client/preferences/ready_anominity.dm
@@ -0,0 +1,32 @@
+/datum/preference/choiced/ready_anominity
+ category = PREFERENCE_CATEGORY_GAME_PREFERENCES
+ savefile_key = "ready_anominity"
+ savefile_identifier = PREFERENCE_PLAYER
+ /// What values we pass to possible values, keyed to the actual bitflag
+ var/list/value_list = list(
+ "Show All" = NONE,
+ "Show Nothing" = ALL,
+ "Just Show Ckey" = ~CKEY_ANON,
+ "Just Show Character" = ~NAME_ANON,
+ "Just Show Job Title" = ~JOB_ANON,
+ "Don't Show Ckey" = CKEY_ANON,
+ "Don't Show Character" = NAME_ANON,
+ "Don't Show Job Title" = JOB_ANON,
+ )
+
+/datum/preference/choiced/ready_anominity/apply_to_client_updated(client/client, value)
+ if(isnewplayer(client?.mob))
+ var/mob/dead/new_player/cycle = client?.mob
+ cycle.update_ready_report()
+
+/datum/preference/choiced/ready_anominity/create_default_value()
+ return value_list[3]
+
+/datum/preference/choiced/ready_anominity/init_possible_values()
+ return value_list
+
+// This also needs to update anominity
+/datum/preference/name/apply_to_client_updated(client/client, value)
+ if(isnewplayer(client?.mob))
+ var/mob/dead/new_player/cycle = client?.mob
+ cycle.update_ready_report()
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/_ready_anominity.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/_ready_anominity.tsx
new file mode 100644
index 000000000000..17200d230ab6
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/_ready_anominity.tsx
@@ -0,0 +1,8 @@
+import { FeatureChoiced, FeatureDropdownInput } from '../base';
+
+export const ready_anominity: FeatureChoiced = {
+ name: 'Ready Anominity',
+ component: FeatureDropdownInput,
+ category: 'GHOST',
+ description: 'Allows you to anonymously ready up in the lobby.',
+};