diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index cefc4c0d5d2..d9634e5cab9 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -534,7 +534,6 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE)))
#define ANON_DISABLED "" //so it's falsey
#define ANON_RANDOMNAMES "Random Default"
-#define ANON_EMPLOYEENAMES "Employees"
/// Possible value of [/atom/movable/buckle_lying]. If set to a different (positive-or-zero) value than this, the buckling thing will force a lying angle on the buckled.
#define NO_BUCKLE_LYING -1
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index aa22504966b..0729e3e1fba 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -27,8 +27,8 @@ SUBSYSTEM_DEF(ticker)
var/admin_delay_notice = "" //a message to display to anyone who tries to restart the world after a delay
var/ready_for_reboot = FALSE //all roundend preparation done with, all that's left is reboot
- ///If not set to ANON_DISABLED then people spawn with a themed anon name (see anonymousnames.dm)
- var/anonymousnames = ANON_DISABLED
+ ///If set to an anonymous theme datum then people spawn with said themed anon name (see anonymousnames.dm)
+ var/datum/anonymous_theme/anonymousnames
///Boolean to see if the game needs to set up a triumvirate ai (see tripAI.dm)
var/triai = FALSE
diff --git a/code/modules/admin/verbs/anonymousnames.dm b/code/modules/admin/verbs/anonymousnames.dm
index 62c48149af5..34af6d95eb4 100644
--- a/code/modules/admin/verbs/anonymousnames.dm
+++ b/code/modules/admin/verbs/anonymousnames.dm
@@ -1,65 +1,123 @@
+
+/*Anon names! A system to make all players have random names/aliases instead of their static, for admin events/fuckery!
+ contains both the anon names proc and the datums for each.
+
+ this is the setup, it handles announcing crew and other settings for the mode and then creating the datum singleton
+*/
/client/proc/anon_names()
set category = "Admin.Events"
set name = "Setup Anonymous Names"
-
- if(SSticker.current_state > GAME_STATE_PREGAME)
- to_chat(usr, "This option is currently only usable during pregame.")
- return
-
if(SSticker.anonymousnames)
- SSticker.anonymousnames = ANON_DISABLED
- to_chat(usr, "Disabled anonymous names.")
+ var/response = alert(usr, "Anon mode is currently enabled. Disable?", "cold feet", "Disable Anon Names", "Keep it Enabled")
+ if(response != "Disable Anon Names")
+ return
+ QDEL_NULL(SSticker.anonymousnames)
message_admins("[key_name_admin(usr)] has disabled anonymous names.")
+ if(SSticker.current_state < GAME_STATE_PREGAME)
+ return
+ priority_announce("Names and Identities have been restored.", "Identity Restoration", 'sound/ai/attention.ogg')
+ for(var/mob/living/player in GLOB.player_list)
+ if(!player.mind || (!ishuman(player) && !issilicon(player)) || !SSjob.GetJob(player.mind.assigned_role))
+ continue
+ var/old_name = player.real_name //before restoration
+ if(issilicon(player))
+ var/is_AI = isAI(player)
+ player.apply_pref_name("[is_AI ? "ai" : "cyborg"]", player.client)
+ else
+ player.client.prefs.copy_to(player, antagonist = (LAZYLEN(player.mind.antag_datums) > 0), is_latejoiner = FALSE)
+ player.fully_replace_character_name(old_name, player.real_name) //this changes IDs and PDAs and whatnot
return
- var/list/names = list("Cancel", ANON_RANDOMNAMES, ANON_EMPLOYEENAMES)
- var/result = input(usr, "Choose an anonymous theme","going dark") as null|anything in names
+ var/list/input_list = list("Cancel")
+ for(var/_theme in typesof(/datum/anonymous_theme))
+ var/datum/anonymous_theme/theme = _theme
+ input_list[initial(theme.name)] = theme
+ var/result = input(usr, "Choose an anonymous theme","going dark") as null|anything in input_list
if(!usr || !result || result == "Cancel")
return
- if(SSticker.current_state > GAME_STATE_PREGAME)
- to_chat(usr, "You took too long! The game has started.")
- return
+ result = input_list[result]
+ var/alert_players = "No"
+ if(SSticker.current_state > GAME_STATE_PREGAME) //before anonnames is done, for asking a sleep
+ alert_players = alert(usr, "Alert crew? These are IC Themed FROM centcom.", "2016 admins didn't miss roundstart", "Yes", "No")
+ SSticker.anonymousnames = new result()
+ if(alert_players == "Yes")
+ priority_announce(SSticker.anonymousnames.announcement_alert, "Identity Loss", 'sound/ai/attention.ogg')
+ anonymous_all_players()
- SSticker.anonymousnames = result
- to_chat(usr, "Enabled anonymous names. THEME: [SSticker.anonymousnames].")
message_admins("[key_name_admin(usr)] has enabled anonymous names. THEME: [SSticker.anonymousnames].")
/**
- * anonymous_name: generates a corporate random name. used in admin event tool anonymous names
+ * anonymous_all_players: sets all crewmembers on station anonymous.
*
- * first letter is always a letter
- * Example name = "Employee Q5460Z"
+ * why is this a proc instead of just part of above? events use this as well.
+ */
+/proc/anonymous_all_players()
+ var/datum/anonymous_theme/theme = SSticker.anonymousnames
+ for(var/mob/living/player in GLOB.player_list)
+ if(!player.mind || (!ishuman(player) && !issilicon(player)) || !SSjob.GetJob(player.mind.assigned_role))
+ continue
+ if(issilicon(player))
+ player.fully_replace_character_name(player.real_name, theme.anonymous_ai_name(isAI(player)))
+ else
+ randomize_human(player) //do this first so the special name can be given
+ player.fully_replace_character_name(player.real_name, theme.anonymous_name(player))
+
+/* Datum singleton initialized by the client proc to hold the naming generation */
+/datum/anonymous_theme
+ var/name = "Randomized Names"
+ var/announcement_alert = "A recent bureaucratic error in the Organic Resources Department has resulted in a necessary full recall of all identities and names until further notice."
+
+/**
+ * anonymous_name: generates a random name, based off of whatever the round's anonymousnames is set to.
+ *
+ * examples:
+ * Employee = "Employee Q5460Z"
+ * Wizards = "Gulstaff of Void"
* Arguments:
* * M - mob for preferences and gender
*/
-/proc/anonymous_name(mob/M)
- switch(SSticker.anonymousnames)
- if(ANON_RANDOMNAMES)
- return M.client.prefs.pref_species.random_name(M.gender,1)
- if(ANON_EMPLOYEENAMES)
- var/name = "Employee "
-
- for(var/i in 1 to 6)
- if(prob(30) || i == 1)
- name += ascii2text(rand(65, 90)) //A - Z
- else
- name += ascii2text(rand(48, 57)) //0 - 9
- return name
+/datum/anonymous_theme/proc/anonymous_name(mob/M)
+ return M.client.prefs.pref_species.random_name(M.gender,1)
/**
- * anonymous_ai_name: generates a corporate random name (but for sillycones). used in admin event tool anonymous names
+ * anonymous_ai_name: generates a random name, based off of whatever the round's anonymousnames is set to (but for sillycones).
*
- * first letter is always a letter
- * Example name = "Employee Assistant Assuming Delta"
+ * examples:
+ * Employee = "Employee Assistant Assuming Delta"
+ * Wizards = "Crystallized Knowledge Nexus +23"
* Arguments:
* * is_ai - boolean to decide whether the name has "Core" (AI) or "Assistant" (Cyborg)
*/
-/proc/anonymous_ai_name(is_ai = FALSE)
- switch(SSticker.anonymousnames)
- if(ANON_RANDOMNAMES)
- return pick(GLOB.ai_names)
- if(ANON_EMPLOYEENAMES)
- var/verbs = capitalize(pick(GLOB.ing_verbs))
- var/phonetic = pick(GLOB.phonetic_alphabet)
+/datum/anonymous_theme/proc/anonymous_ai_name(is_ai = FALSE)
+ return pick(GLOB.ai_names)
- return "Employee [is_ai ? "Core" : "Assistant"] [verbs] [phonetic]"
+/datum/anonymous_theme/employees
+ name = "Employees"
+ announcement_alert = "As punishment for this station's poor productivity when compared to neighbor stations, names and identities will be restricted until further notice."
+
+/datum/anonymous_theme/employees/anonymous_name(mob/M)
+ var/is_head_of_staff = (M.mind.assigned_role in GLOB.command_positions)
+ var/name = "[is_head_of_staff ? "Manager" : "Employee"] "
+ for(var/i in 1 to 6)
+ if(prob(30) || i == 1)
+ name += ascii2text(rand(65, 90)) //A - Z
+ else
+ name += ascii2text(rand(48, 57)) //0 - 9
+ return name
+
+/datum/anonymous_theme/employees/anonymous_ai_name(is_ai = FALSE)
+ var/verbs = capitalize(pick(GLOB.ing_verbs))
+ var/phonetic = pick(GLOB.phonetic_alphabet)
+ return "Employee [is_ai ? "Core" : "Assistant"] [verbs] [phonetic]"
+
+/datum/anonymous_theme/wizards
+ name = "Wizard Academy"
+ announcement_alert = "Your station has been caught by a Wizard Federation Memetic Hazard. You are not y0urself, and yo% a2E 34!NOT4--- Welcome to the Academy, apprentices!"
+
+/datum/anonymous_theme/wizards/anonymous_name(mob/M)
+ var/wizard_name_first = pick(GLOB.wizard_first)
+ var/wizard_name_second = pick(GLOB.wizard_second)
+ return "[wizard_name_first] [wizard_name_second]"
+
+/datum/anonymous_theme/wizards/anonymous_ai_name(is_ai = FALSE)
+ return "Crystallized Knowledge [is_ai ? "Nexus" : "Sliver"] +[rand(1,99)]" //Could two people roll the same number? Yeah, probably. Do I CARE? Nawww
diff --git a/code/modules/events/wizard/identity_spoof.dm b/code/modules/events/wizard/identity_spoof.dm
new file mode 100644
index 00000000000..0e5f990b598
--- /dev/null
+++ b/code/modules/events/wizard/identity_spoof.dm
@@ -0,0 +1,18 @@
+/datum/round_event_control/wizard/identity_spoof //now EVERYONE is the wizard!
+ name = "Mass Identity Spoof"
+ weight = 5
+ typepath = /datum/round_event/wizard/identity_spoof
+ max_occurrences = 1
+
+/datum/round_event_control/wizard/identity_spoof/canSpawnEvent(players_amt, gamemode)
+ . = ..()
+ if(.)
+ return FALSE
+ if(SSticker.anonymousnames) //already anonymous, ABORT ABORT
+ return FALSE
+
+/datum/round_event/wizard/identity_spoof/start()
+ if(SSticker.anonymousnames)
+ QDEL_NULL(SSticker.anonymousnames)
+ SSticker.anonymousnames = new /datum/anonymous_theme/wizards()
+ anonymous_all_players()
diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm
index 9e43f7d19cb..e29e44e4f46 100644
--- a/code/modules/jobs/job_types/ai.dm
+++ b/code/modules/jobs/job_types/ai.dm
@@ -35,7 +35,7 @@
qdel(lateJoinCore)
var/mob/living/silicon/ai/AI = H
if(SSticker.anonymousnames)
- AI.fully_replace_character_name(AI.real_name, anonymous_ai_name(is_ai = TRUE))
+ AI.fully_replace_character_name(AI.real_name, SSticker.anonymousnames.anonymous_ai_name(TRUE))
else
AI.apply_pref_name("ai", M.client) //If this runtimes oh well jobcode is fucked. //what is this no energy attitude man
AI.set_core_display_icon(null, M.client)
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index da456082488..7da1a7c6882 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -459,16 +459,16 @@
client.prefs.random_character()
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
- if(admin_anon_names)//overrides random name because it achieves the same effect and is an admin enabled event tool
- client.prefs.random_character()
- client.prefs.real_name = anonymous_name(src)
-
var/is_antag
if(mind in GLOB.pre_setup_antags)
is_antag = TRUE
client.prefs.copy_to(H, antagonist = is_antag, is_latejoiner = transfer_after)
+ if(admin_anon_names)//overrides random name because it achieves the same effect and is an admin enabled event tool
+ randomize_human(H)
+ H.fully_replace_character_name(null, SSticker.anonymousnames.anonymous_name(H))
+
H.dna.update_dna_identity()
if(mind)
if(transfer_after)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 667e3cad669..a01f690ff23 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -271,7 +271,7 @@
if(custom_name)
changed_name = custom_name
if(SSticker.anonymousnames) //only robotic renames will allow for anything other than the anonymous one
- changed_name = anonymous_ai_name(is_ai = FALSE)
+ changed_name = SSticker.anonymousnames.anonymous_ai_name(FALSE)
if(!changed_name && C && C.prefs.custom_names["cyborg"] != DEFAULT_CYBORG_NAME)
apply_pref_name("cyborg", C)
return //built in camera handled in proc
diff --git a/strings/names/wizardfirst.txt b/strings/names/wizardfirst.txt
index 13dc68c6bd2..eb48e8261cc 100644
--- a/strings/names/wizardfirst.txt
+++ b/strings/names/wizardfirst.txt
@@ -1,37 +1,97 @@
+Aberforth
+Ad
+Aganemnom
Alatar
+Aluneth
+Arbiter
+Arcano
Archchancellor
+Asriel
+Aurora
+Baldric
+Barachiel
+Blasto
+Bob
Boccob
+Boldwort
+Bona
+Carl
+Channeler
Circe
+Curley
+Dickel
Dumbledor
+Dumblroar
+Dumblrorber
+Edison
Elminister
+Eric
+Fenty
+Fernando
+Fizban
+Fumblemoar
+Gabriel
Gandalf
Grimm
Gulstaff
+Hagrid
Houdini
+Jegudiel
Jim
+Judge
Kaschei
+Kazuo
Khelben
+Koschei
Kreol
+Larry
+Ley
Lina
+Magier
Merlin
+Micheal
+Mitarbeiter
+Mo
Mogan
Mordenkainen
Morgan
+Mortimer
+Munstrum
Mystryl
Nihilus
+Nikola
+Odysseus
+Othello
Palando
+Pixel
+Ponder
Prospero
Radagast
Raistlin
+Raphael
Rasputin
+Rihanna
Rincewind
+Roduct
Saruman
+Selaphiel
+Sigmund
+Supreme
+Tabula
+Temporus
Tenser
Terefi
+Tim
+Tom
Tzeentch
+Ulysses
+Uriel
Urza
Vaarsuvius
Vecna
+Vlad
+Wizardman
Yoda
Zagyg
+Zifnab
Zul
\ No newline at end of file
diff --git a/strings/names/wizardsecond.txt b/strings/names/wizardsecond.txt
index 6daff0f3e7f..4e9bd10e04b 100644
--- a/strings/names/wizardsecond.txt
+++ b/strings/names/wizardsecond.txt
@@ -1,27 +1,85 @@
+Among-many
+Azurepelt
+Borealis
Dark
Darkmagic
Darko
+Deathbringer
+Doomancer
+Evergreen
+Evilton
+Fide
Gray
Honko
+Infinitum
Inverse
+Lifereaper
+Meatsmith
+Midnight
+Mother-of-dragons
+Mountain-Mother
+Namekeeper
+Nauseam
+Rasa
+Runespear
+Sequitur
+Shado
+Shadowdancer
+Shorekeeper
+Smith
+Snape
+Spellstone
+Starfall
+Starlightking
+Starlightqueen
+Stormcaller
+Suneater
+Truenamer
+Unseen
+Voidfall
+Voidstabber
+Volente
+Weatherwax
+Who-was-blood
+Who-was-light
+Who-was-stone
+Windshearer
+Worldshaker
+Yagg
le Fay
of Void
-Shado
-Smith
+the Alchemist
the All Knowing
the Amazing
+the Annoyed
+the Annoying
the Bandit Killer
the Benevolent
the Blue
the Brown
+the Colourless
the Conquerer
+the Dappled
the Deathless
the Destroyer
the Dragon Spooker
+the Dragoncaller
+the Drunk
the Emperor
+the Empty
+the Ethereal
+the Excoherent
the Gray
the Great
+the Herb
+the Impaler
+the Incoherent
+the Jaunter
the Magician
+the Manual
+the Moldywarp
+the Necromancer
+the Obscure
the Powerful
the Raven
the Red
@@ -30,11 +88,12 @@ the Seething
the Sorcelator
the Spiral King
the Unending
+the Unseen
the Unstoppable
+the Wandsmith
+the Waxmancer
the Weeping
the White
+the Wife
the Wise
-the Wizzard
-Unseen
-Weatherwax
-Yagg
\ No newline at end of file
+the Wizzard
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index 6579bc43ceb..89e63a719a5 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2008,6 +2008,7 @@
#include "code\modules\events\wizard\fakeexplosion.dm"
#include "code\modules\events\wizard\ghost.dm"
#include "code\modules\events\wizard\greentext.dm"
+#include "code\modules\events\wizard\identity_spoof.dm"
#include "code\modules\events\wizard\imposter.dm"
#include "code\modules\events\wizard\invincible.dm"
#include "code\modules\events\wizard\lava.dm"