GLOBAL_LIST_EMPTY(preferences_datums) /datum/preferences var/client/parent //doohickeys for savefiles var/path var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used var/max_save_slots = 3 //non-preference stuff var/muted = 0 var/last_ip var/last_id //game-preferences var/lastchangelog = "" //Saved changlog filesize to detect if there was a change var/ooccolor = "#c43b23" var/asaycolor = "#ff4500" //This won't change the color for current admins, only incoming ones. /// If we spawn an ERT as an admin and choose to spawn as the briefing officer, we'll be given this outfit var/brief_outfit = /datum/outfit/centcom/commander var/enable_tips = TRUE var/tip_delay = 500 //tip delay in milliseconds //Antag preferences var/list/be_special = list() //Special role selection var/tmp/old_be_special = 0 //Bitflag version of be_special, used to update old savefiles and nothing more //If it's 0, that's good, if it's anything but 0, the owner of this prefs file's antag choices were, //autocorrected this round, not that you'd need to check that. var/UI_style = null var/buttons_locked = FALSE var/hotkeys = TRUE ///Runechat preference. If true, certain messages will be displayed on the map, not ust on the chat area. Boolean. var/chat_on_map = TRUE ///Limit preference on the size of the message. Requires chat_on_map to have effect. var/max_chat_length = CHAT_MESSAGE_MAX_LENGTH ///Whether non-mob messages will be displayed, such as machine vendor announcements. Requires chat_on_map to have effect. Boolean. var/see_chat_non_mob = TRUE ///Whether emotes will be displayed on runechat. Requires chat_on_map to have effect. Boolean. var/see_rc_emotes = TRUE // Custom Keybindings var/list/key_bindings = list() var/tgui_fancy = TRUE var/tgui_lock = FALSE var/windowflashing = TRUE var/toggles = TOGGLES_DEFAULT var/db_flags var/chat_toggles = TOGGLES_DEFAULT_CHAT var/ghost_form = "ghost" var/ghost_orbit = GHOST_ORBIT_CIRCLE var/ghost_accs = GHOST_ACCS_DEFAULT_OPTION var/ghost_others = GHOST_OTHERS_DEFAULT_OPTION var/ghost_hud = 1 var/inquisitive_ghost = 1 var/allow_midround_antag = 1 var/preferred_map = null var/pda_style = MONO var/pda_color = "#808000" var/uses_glasses_colour = 0 //character preferences var/slot_randomized //keeps track of round-to-round randomization of the character slot, prevents overwriting var/real_name //our character's name var/gender = MALE //gender of character (well duh) var/age = 30 //age of character var/underwear = "Nude" //underwear type var/underwear_color = "000" //underwear color var/undershirt = "Nude" //undershirt type var/socks = "Nude" //socks type var/backpack = DBACKPACK //backpack type var/jumpsuit_style = PREF_SUIT //suit/skirt var/hairstyle = "Bald" //Hair type var/hair_color = "000" //Hair color var/facial_hairstyle = "Shaved" //Face hair type var/facial_hair_color = "000" //Facial hair color var/skin_tone = "caucasian1" //Skin color var/eye_color = "000" //Eye color var/datum/species/pref_species = new /datum/species/human() //Mutant race var/list/features = list("mcolor" = "FFF", "ethcolor" = "9c3030", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs", "moth_wings" = "Plain", "moth_antennae" = "Plain", "moth_markings" = "None") var/list/randomise = list(RANDOM_UNDERWEAR = TRUE, RANDOM_UNDERWEAR_COLOR = TRUE, RANDOM_UNDERSHIRT = TRUE, RANDOM_SOCKS = TRUE, RANDOM_BACKPACK = TRUE, RANDOM_JUMPSUIT_STYLE = TRUE, RANDOM_HAIRSTYLE = TRUE, RANDOM_HAIR_COLOR = TRUE, RANDOM_FACIAL_HAIRSTYLE = TRUE, RANDOM_FACIAL_HAIR_COLOR = TRUE, RANDOM_SKIN_TONE = TRUE, RANDOM_EYE_COLOR = TRUE) var/phobia = "spiders" var/list/custom_names = list() var/preferred_ai_core_display = "Blue" var/prefered_security_department = SEC_DEPT_NONE //Quirk list var/list/all_quirks = list() //Job preferences 2.0 - indexed by job title , no key or value implies never var/list/job_preferences = list() // Want randomjob if preferences already filled - Donkie var/joblessrole = BERANDOMJOB //defaults to 1 for fewer assistants // 0 = character settings, 1 = game preferences var/current_tab = 0 var/unlock_content = 0 var/list/ignoring = list() var/clientfps = -1 var/parallax ///Do we show screentips, if so, how big? var/screentip_pref = TRUE ///Color of screentips at top of screen var/screentip_color = "#ffd391" ///Do we show item hover outlines? var/itemoutline_pref = TRUE var/ambientocclusion = TRUE ///Should we automatically fit the viewport? var/auto_fit_viewport = FALSE ///Should we be in the widescreen mode set by the config? var/widescreenpref = TRUE ///What size should pixels be displayed as? 0 is strech to fit var/pixel_size = 0 ///What scaling method should we use? Distort means nearest neighbor var/scaling_method = SCALING_METHOD_DISTORT var/uplink_spawn_loc = UPLINK_PDA ///The playtime_reward_cloak variable can be set to TRUE from the prefs menu only once the user has gained over 5K playtime hours. If true, it allows the user to get a cool looking roundstart cloak. var/playtime_reward_cloak = FALSE var/list/exp = list() var/list/menuoptions var/action_buttons_screen_locs = list() ///This var stores the amount of points the owner will get for making it out alive. var/hardcore_survival_score = 0 ///Someone thought we were nice! We get a little heart in OOC until we join the server past the below time (we can keep it until the end of the round otherwise) var/hearted ///If we have a hearted commendations, we honor it every time the player loads preferences until this time has been passed var/hearted_until /// Agendered spessmen can choose whether to have a male or female bodytype var/body_type /// If we have persistent scars enabled var/persistent_scars = TRUE ///If we want to broadcast deadchat connect/disconnect messages var/broadcast_login_logout = TRUE ///What outfit typepaths we've favorited in the SelectEquipment menu var/list/favorite_outfits = list() /datum/preferences/New(client/C) parent = C for(var/custom_name_id in GLOB.preferences_custom_names) custom_names[custom_name_id] = get_default_name(custom_name_id) UI_style = GLOB.available_ui_styles[1] if(istype(C)) if(!IsGuestKey(C.key)) load_path(C.ckey) unlock_content = C.IsByondMember() if(unlock_content) max_save_slots = 8 var/loaded_preferences_successfully = load_preferences() if(loaded_preferences_successfully) if(load_character()) return //we couldn't load character data so just randomize the character appearance + name random_character() //let's create a random character then - rather than a fat, bald and naked man. key_bindings = deepCopyList(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys C?.set_macros() real_name = pref_species.random_name(gender,1) if(!loaded_preferences_successfully) save_preferences() save_character() //let's save this new random character so it doesn't keep generating new ones. menuoptions = list() return #define APPEARANCE_CATEGORY_COLUMN "" #define MAX_MUTANT_ROWS 4 /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return if(slot_randomized) load_character(default_slot) // Reloads the character slot. Prevents random features from overwriting the slot if saved. slot_randomized = FALSE update_preview_icon() var/list/dat = list("
") dat += "Character Settings" dat += "Game Preferences" dat += "OOC Preferences" dat += "Custom Keybindings" if(!path) dat += "
Please create an account to save your preferences
" dat += "
" dat += "
" switch(current_tab) if (0) // Character Settings# if(path) var/savefile/S = new /savefile(path) if(S) dat += "
" var/name var/unspaced_slots = 0 for(var/i=1, i<=max_save_slots, i++) unspaced_slots++ if(unspaced_slots > 4) dat += "
" unspaced_slots = 0 S.cd = "/character[i]" S["real_name"] >> name if(!name) name = "Character[i]" dat += "[name] " dat += "
" dat += "

Occupation Choices

" dat += "Set Occupation Preferences
" if(CONFIG_GET(flag/roundstart_traits)) dat += "

Quirk Setup

" dat += "Configure Quirks
" dat += "
Current Quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"]
" dat += "

Identity

" dat += "" dat += "
" if(is_banned_from(user.ckey, "Appearance")) dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.
" dat += "Random Name " dat += "Always Random Name: [(randomise[RANDOM_NAME]) ? "Yes" : "No"]" dat += "When Antagonist: [(randomise[RANDOM_NAME_ANTAG]) ? "Yes" : "No"]" if(user.client.get_exp_living(TRUE) >= PLAYTIME_HARDCORE_RANDOM) dat += "Hardcore Random: [(randomise[RANDOM_HARDCORE]) ? "Yes" : "No"]" dat += "
Name: " dat += "[real_name]
" if(!(AGENDER in pref_species.species_traits)) var/dispGender if(gender == MALE) dispGender = "Male" else if(gender == FEMALE) dispGender = "Female" else dispGender = "Other" dat += "Gender: [dispGender]" if(gender == PLURAL || gender == NEUTER) dat += "
Body Type: [body_type == MALE ? "Male" : "Female"]" if(randomise[RANDOM_BODY] || randomise[RANDOM_BODY_ANTAG]) //doesn't work unless random body dat += "Always Random Gender: [(randomise[RANDOM_GENDER]) ? "Yes" : "No"]" dat += "When Antagonist: [(randomise[RANDOM_GENDER_ANTAG]) ? "Yes" : "No"]" dat += "
Age: [age]" if(randomise[RANDOM_BODY] || randomise[RANDOM_BODY_ANTAG]) //doesn't work unless random body dat += "Always Random Age: [(randomise[RANDOM_AGE]) ? "Yes" : "No"]" dat += "When Antagonist: [(randomise[RANDOM_AGE_ANTAG]) ? "Yes" : "No"]" dat += "

Special Names:
" var/old_group for(var/custom_name_id in GLOB.preferences_custom_names) var/namedata = GLOB.preferences_custom_names[custom_name_id] if(!old_group) old_group = namedata["group"] else if(old_group != namedata["group"]) old_group = namedata["group"] dat += "
" dat += "[namedata["pref_name"]]: [custom_names[custom_name_id]] " dat += "

" dat += "Custom Job Preferences:
" dat += "Preferred AI Core Display: [preferred_ai_core_display]
" dat += "Preferred Security Department: [prefered_security_department]
" dat += "

Body

" dat += "Random Body " dat += "Always Random Body: [(randomise[RANDOM_BODY]) ? "Yes" : "No"]" dat += "When Antagonist: [(randomise[RANDOM_BODY_ANTAG]) ? "Yes" : "No"]
" dat += "" if (user.client.get_exp_living(TRUE) >= PLAYTIME_VETERAN) dat += "
Don The Ultimate Gamer Cloak?:
[(playtime_reward_cloak) ? "Enabled" : "Disabled"]
" var/use_skintones = pref_species.use_skintones if(use_skintones) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Skin Tone

" dat += "[skin_tone]" dat += "[(randomise[RANDOM_SKIN_TONE]) ? "Lock" : "Unlock"]" dat += "
" var/mutant_colors if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) if(!use_skintones) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Mutant Color

" dat += "   Change
" mutant_colors = TRUE if(istype(pref_species, /datum/species/ethereal)) //not the best thing to do tbf but I dont know whats better. if(!use_skintones) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Ethereal Color

" dat += "   Change
" if((EYECOLOR in pref_species.species_traits) && !(NOEYESPRITES in pref_species.species_traits)) if(!use_skintones && !mutant_colors) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Eye Color

" dat += "   Change" dat += "[(randomise[RANDOM_EYE_COLOR]) ? "Lock" : "Unlock"]" dat += "
" else if(use_skintones || mutant_colors) dat += "" if(HAIR in pref_species.species_traits) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Hairstyle

" dat += "[hairstyle]" dat += "<>" dat += "[(randomise[RANDOM_HAIRSTYLE]) ? "Lock" : "Unlock"]" dat += "
   Change" dat += "[(randomise[RANDOM_HAIR_COLOR]) ? "Lock" : "Unlock"]" dat += "

Facial Hairstyle

" dat += "[facial_hairstyle]" dat += "<>" dat += "[(randomise[RANDOM_FACIAL_HAIRSTYLE]) ? "Lock" : "Unlock"]" dat += "
   Change" dat += "[(randomise[RANDOM_FACIAL_HAIR_COLOR]) ? "Lock" : "Unlock"]" dat += "
" //Mutant stuff var/mutant_category = 0 if(pref_species.mutant_bodyparts["tail_lizard"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Tail

" dat += "[features["tail_lizard"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["snout"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Snout

" dat += "[features["snout"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["horns"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Horns

" dat += "[features["horns"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["frills"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Frills

" dat += "[features["frills"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["spines"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Spines

" dat += "[features["spines"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["body_markings"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Body Markings

" dat += "[features["body_markings"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["legs"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Legs

" dat += "[features["legs"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["moth_wings"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Moth wings

" dat += "[features["moth_wings"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["moth_antennae"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Moth antennae

" dat += "[features["moth_antennae"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["moth_markings"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Moth markings

" dat += "[features["moth_markings"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["tail_human"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Tail

" dat += "[features["tail_human"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(pref_species.mutant_bodyparts["ears"]) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Ears

" dat += "[features["ears"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 //Adds a thing to select which phobia because I can't be assed to put that in the quirks window if("Phobia" in all_quirks) dat += "

Phobia

" dat += "[phobia]
" if(CONFIG_GET(flag/join_with_mutant_humans)) if(pref_species.mutant_bodyparts["wings"] && GLOB.r_wings_list.len >1) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Wings

" dat += "[features["wings"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(mutant_category) dat += "" mutant_category = 0 dat += "
" dat += "Species:
[pref_species.name]
" dat += "Random Species " dat += "Always Random Species: [(randomise[RANDOM_SPECIES]) ? "Yes" : "No"]
" dat += "Underwear:
[underwear]" dat += "[(randomise[RANDOM_UNDERWEAR]) ? "Lock" : "Unlock"]" dat += "
Underwear Color:
    Change" dat += "[(randomise[RANDOM_UNDERWEAR_COLOR]) ? "Lock" : "Unlock"]" dat += "
Undershirt:
[undershirt]" dat += "[(randomise[RANDOM_UNDERSHIRT]) ? "Lock" : "Unlock"]" dat += "
Socks:
[socks]" dat += "[(randomise[RANDOM_SOCKS]) ? "Lock" : "Unlock"]" dat += "
Jumpsuit Style:
[jumpsuit_style]" dat += "[(randomise[RANDOM_JUMPSUIT_STYLE]) ? "Lock" : "Unlock"]" dat += "
Backpack:
[backpack]" dat += "[(randomise[RANDOM_BACKPACK]) ? "Lock" : "Unlock"]" if((HAS_FLESH in pref_species.species_traits) || (HAS_BONE in pref_species.species_traits)) dat += "
Temporal Scarring:
[(persistent_scars) ? "Enabled" : "Disabled"]" dat += "Clear scar slots" dat += "
Uplink Spawn Location:
[uplink_spawn_loc == UPLINK_IMPLANT ? UPLINK_IMPLANT_WITH_PRICE : uplink_spawn_loc]
" if (1) // Game Preferences dat += "
" dat += "

General Settings

" dat += "UI Style: [UI_style]
" dat += "tgui Window Mode: [(tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]
" dat += "tgui Window Placement: [(tgui_lock) ? "Primary monitor" : "Free (default)"]
" dat += "Show Runechat Chat Bubbles: [chat_on_map ? "Enabled" : "Disabled"]
" dat += "Runechat message char limit: [max_chat_length]
" dat += "See Runechat for non-mobs: [see_chat_non_mob ? "Enabled" : "Disabled"]
" dat += "See Runechat emotes: [see_rc_emotes ? "Enabled" : "Disabled"]
" dat += "
" dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
" dat += "Hotkey mode: [(hotkeys) ? "Hotkeys" : "Default"]
" dat += "
" dat += "PDA Color:     Change
" dat += "PDA Style: [pda_style]
" dat += "
" dat += "Ghost Ears: [(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost Radio: [(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]
" dat += "Ghost Sight: [(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
" dat += "Ghost Whispers: [(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost PDA: [(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]
" dat += "Ghost Law Changes: [(chat_toggles & CHAT_GHOSTLAWS) ? "All Law Changes" : "No Law Changes"]
" if(unlock_content) dat += "Ghost Form: [ghost_form]
" dat += "Ghost Orbit: [ghost_orbit]
" var/button_name = "If you see this something went wrong." switch(ghost_accs) if(GHOST_ACCS_FULL) button_name = GHOST_ACCS_FULL_NAME if(GHOST_ACCS_DIR) button_name = GHOST_ACCS_DIR_NAME if(GHOST_ACCS_NONE) button_name = GHOST_ACCS_NONE_NAME dat += "Ghost Accessories: [button_name]
" switch(ghost_others) if(GHOST_OTHERS_THEIR_SETTING) button_name = GHOST_OTHERS_THEIR_SETTING_NAME if(GHOST_OTHERS_DEFAULT_SPRITE) button_name = GHOST_OTHERS_DEFAULT_SPRITE_NAME if(GHOST_OTHERS_SIMPLE) button_name = GHOST_OTHERS_SIMPLE_NAME dat += "Ghosts of Others: [button_name]
" dat += "
" dat += "Broadcast Login/Logout: [broadcast_login_logout ? "Broadcast" : "Silent"]
" dat += "See Login/Logout Messages: [(chat_toggles & CHAT_LOGIN_LOGOUT) ? "Allowed" : "Muted"]
" dat += "
" dat += "Income Updates: [(chat_toggles & CHAT_BANKCARD) ? "Allowed" : "Muted"]
" dat += "
" dat += "FPS: [clientfps]
" dat += "Parallax (Fancy Space): " switch (parallax) if (PARALLAX_LOW) dat += "Low" if (PARALLAX_MED) dat += "Medium" if (PARALLAX_INSANE) dat += "Insane" if (PARALLAX_DISABLE) dat += "Disabled" else dat += "High" dat += "
" dat += "Set screentip mode: [screentip_pref ? "Enabled" : "Disabled"]
" dat += "Screentip color:    Change
" dat += "Item Hover Outlines: [itemoutline_pref ? "Enabled" : "Disabled"]
" dat += "Ambient Occlusion: [ambientocclusion ? "Enabled" : "Disabled"]
" dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
" if (CONFIG_GET(string/default_view) != CONFIG_GET(string/default_view_square)) dat += "Widescreen: [widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled ([CONFIG_GET(string/default_view_square)])"]
" button_name = pixel_size dat += "Pixel Scaling: [(button_name) ? "Pixel Perfect [button_name]x" : "Stretch to fit"]
" switch(scaling_method) if(SCALING_METHOD_DISTORT) button_name = "Nearest Neighbor" if(SCALING_METHOD_NORMAL) button_name = "Point Sampling" if(SCALING_METHOD_BLUR) button_name = "Bilinear" dat += "Scaling Method: [button_name]
" if (CONFIG_GET(flag/maprotation)) var/p_map = preferred_map if (!p_map) p_map = "Default" if (config.defaultmap) p_map += " ([config.defaultmap.map_name])" else if (p_map in config.maplist) var/datum/map_config/VM = config.maplist[p_map] if (!VM) p_map += " (No longer exists)" else p_map = VM.map_name else p_map += " (No longer exists)" if(CONFIG_GET(flag/preference_map_voting)) dat += "Preferred Map: [p_map]
" dat += "
" dat += "

Special Role Settings

" if(is_banned_from(user.ckey, ROLE_SYNDICATE)) dat += "You are banned from antagonist roles.
" src.be_special = list() for (var/special_role in GLOB.special_roles) if(is_banned_from(user.ckey, special_role)) dat += "Be [capitalize(special_role)]: BANNED
" else var/days_remaining = null if(CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age var/days_needed = GLOB.special_roles[special_role] days_remaining = user.client?.get_remaining_days(days_needed) if(days_remaining) dat += "Be [capitalize(special_role)]: \[IN [days_remaining] DAYS]
" else dat += "Be [capitalize(special_role)]: [(special_role in be_special) ? "Enabled" : "Disabled"]
" dat += "
" dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]
" dat += "
" if(2) //OOC Preferences dat += "" if(user.client.holder) dat +="" dat += "
" dat += "

OOC Settings

" dat += "Window Flashing: [(windowflashing) ? "Enabled":"Disabled"]
" dat += "
" dat += "Play Admin MIDIs: [(toggles & SOUND_MIDI) ? "Enabled":"Disabled"]
" dat += "Play Lobby Music: [(toggles & SOUND_LOBBY) ? "Enabled":"Disabled"]
" dat += "Play End of Round Sounds: [(toggles & SOUND_ENDOFROUND) ? "Enabled":"Disabled"]
" dat += "Play Combat Mode Sounds: [(toggles & SOUND_COMBATMODE) ? "Enabled":"Disabled"]
" dat += "See Pull Requests: [(chat_toggles & CHAT_PULLR) ? "Enabled":"Disabled"]
" dat += "
" if(user.client) if(unlock_content) dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
" if(unlock_content || check_rights_for(user.client, R_ADMIN)) dat += "OOC Color:     Change
" if(hearted_until) dat += "Clear OOC Commend Heart
" dat += "
" dat += "

Admin Settings

" dat += "Adminhelp Sounds: [(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
" dat += "Prayer Sounds: [(toggles & SOUND_PRAYERS)?"Enabled":"Disabled"]
" dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
" dat += "
" dat += "Combo HUD Lighting: [(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]
" dat += "
" dat += "Hide Dead Chat: [(chat_toggles & CHAT_DEAD)?"Shown":"Hidden"]
" dat += "Hide Radio Messages: [(chat_toggles & CHAT_RADIO)?"Shown":"Hidden"]
" dat += "Hide Prayers: [(chat_toggles & CHAT_PRAYER)?"Shown":"Hidden"]
" dat += "Split Admin Tabs: [(toggles & SPLIT_ADMIN_TABS)?"Enabled":"Disabled"]
" dat += "Ignore Being Summoned as Cult Ghost: [(toggles & ADMIN_IGNORE_CULT_GHOST)?"Don't Allow Being Summoned":"Allow Being Summoned"]
" dat += "Briefing Officer Outfit: [brief_outfit]
" if(CONFIG_GET(flag/allow_admin_asaycolor)) dat += "
" dat += "ASAY Color:     Change
" //deadmin dat += "

Deadmin While Playing

" var/timegate = CONFIG_GET(number/auto_deadmin_timegate) if(timegate) dat += "Noted roles will automatically deadmin during the first [FLOOR(timegate / 600, 1)] minutes of the round, and will defer to individual preferences after.
" if(CONFIG_GET(flag/auto_deadmin_players) && !timegate) dat += "Always Deadmin: FORCED
" else dat += "Always Deadmin: [timegate ? "(Time Locked) " : ""][(toggles & DEADMIN_ALWAYS)?"Enabled":"Disabled"]
" if(!(toggles & DEADMIN_ALWAYS)) dat += "
" if(!CONFIG_GET(flag/auto_deadmin_antagonists) || (CONFIG_GET(flag/auto_deadmin_antagonists) && !timegate)) dat += "As Antag: [timegate ? "(Time Locked) " : ""][(toggles & DEADMIN_ANTAGONIST)?"Deadmin":"Keep Admin"]
" else dat += "As Antag: FORCED
" if(!CONFIG_GET(flag/auto_deadmin_heads) || (CONFIG_GET(flag/auto_deadmin_heads) && !timegate)) dat += "As Command: [timegate ? "(Time Locked) " : ""][(toggles & DEADMIN_POSITION_HEAD)?"Deadmin":"Keep Admin"]
" else dat += "As Command: FORCED
" if(!CONFIG_GET(flag/auto_deadmin_security) || (CONFIG_GET(flag/auto_deadmin_security) && !timegate)) dat += "As Security: [timegate ? "(Time Locked) " : ""][(toggles & DEADMIN_POSITION_SECURITY)?"Deadmin":"Keep Admin"]
" else dat += "As Security: FORCED
" if(!CONFIG_GET(flag/auto_deadmin_silicons) || (CONFIG_GET(flag/auto_deadmin_silicons) && !timegate)) dat += "As Silicon: [timegate ? "(Time Locked) " : ""][(toggles & DEADMIN_POSITION_SILICON)?"Deadmin":"Keep Admin"]
" else dat += "As Silicon: FORCED
" dat += "
" if(3) // Custom keybindings // Create an inverted list of keybindings -> key var/list/user_binds = list() for (var/key in key_bindings) for(var/kb_name in key_bindings[key]) user_binds[kb_name] += list(key) var/list/kb_categories = list() // Group keybinds by category for (var/name in GLOB.keybindings_by_name) var/datum/keybinding/kb = GLOB.keybindings_by_name[name] kb_categories[kb.category] += list(kb) dat += "" for (var/category in kb_categories) dat += "

[category]

" for (var/i in kb_categories[category]) var/datum/keybinding/kb = i if(!length(user_binds[kb.name]) || user_binds[kb.name][1] == "Unbound") dat += " Unbound" var/list/default_keys = hotkeys ? kb.hotkey_keys : kb.classic_keys if(LAZYLEN(default_keys)) dat += "| Default: [default_keys.Join(", ")]" dat += "
" else var/bound_key = user_binds[kb.name][1] dat += " [bound_key]" for(var/bound_key_index in 2 to length(user_binds[kb.name])) bound_key = user_binds[kb.name][bound_key_index] dat += " | [bound_key]" if(length(user_binds[kb.name]) < MAX_KEYS_PER_KEYBIND) dat += "| Add Secondary" var/list/default_keys = hotkeys ? kb.classic_keys : kb.hotkey_keys if(LAZYLEN(default_keys)) dat += "| Default: [default_keys.Join(", ")]" dat += "
" dat += "

" dat += "\[Reset to default\]" dat += "" dat += "
" if(!IsGuestKey(user.key)) dat += "Undo " dat += "Save Setup " dat += "Reset Setup" dat += "
" winshow(user, "preferences_window", TRUE) var/datum/browser/popup = new(user, "preferences_browser", "
Character Setup
", 640, 770) popup.set_content(dat.Join()) popup.open(FALSE) onclose(user, "preferences_window", src) #undef APPEARANCE_CATEGORY_COLUMN #undef MAX_MUTANT_ROWS /datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, old_key) var/HTML = {"
Keybinding: [kb.full_name]
[kb.description]

Press any key to change
Press ESC to clear
"} winshow(user, "capturekeypress", TRUE) var/datum/browser/popup = new(user, "capturekeypress", "
Keybindings
", 350, 300) popup.set_content(HTML) popup.open(FALSE) onclose(user, "capturekeypress", src) /datum/preferences/proc/SetChoices(mob/user, limit = 15, widthPerColumn = 295, height = 620) if(!SSjob) return //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice. //widthPerColumn - Screen's width for every column. //height - Screen's height. var/width = widthPerColumn var/HTML = "
" if(SSjob.occupations.len <= 0) HTML += "The job SSticker is not yet finished creating jobs, please try again later" HTML += "
Done

" // Easier to press up here. else HTML += "Choose occupation chances
" HTML += "
Left-click to raise an occupation preference, right-click to lower it.
" HTML += "
Done

" // Easier to press up here. HTML += "" HTML += "
" // Table within a table for alignment, also allows you to easily add more colomns. HTML += "" var/index = -1 //The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows. var/datum/job/lastJob for(var/datum/job/job in sortList(SSjob.occupations, /proc/cmp_job_display_asc)) index += 1 if(index >= limit) width += widthPerColumn if((index < limit) && (lastJob != null)) // Fills the rest of the cells with the last job's selection color. for(var/i = 0, i < (limit - index), i += 1) HTML += "" HTML += "
  
" index = 0 HTML += "" continue var/required_playtime_remaining = job.required_playtime_remaining(user.client) if(required_playtime_remaining) HTML += "[rank]" continue if(!job.player_old_enough(user.client)) var/available_in_days = job.available_in_days(user.client) HTML += "[rank]" continue if((job_preferences[SSjob.overflow_role] == JP_LOW) && (rank != SSjob.overflow_role) && !is_banned_from(user.ckey, SSjob.overflow_role)) HTML += "[rank]" continue if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs HTML += "[rank]" else HTML += "[rank]" HTML += "" continue HTML += "[prefLevelLabel]" HTML += "" for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even HTML += "" HTML += "
" var/rank = job.title lastJob = job if(is_banned_from(user.ckey, rank)) HTML += "[rank] BANNED
\[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \]
\[IN [(available_in_days)] DAYS\]
" var/prefLevelLabel = "ERROR" var/prefLevelColor = "pink" var/prefUpperLevel = -1 // level to assign on left click var/prefLowerLevel = -1 // level to assign on right click switch(job_preferences[job.title]) if(JP_HIGH) prefLevelLabel = "High" prefLevelColor = "slateblue" prefUpperLevel = 4 prefLowerLevel = 2 if(JP_MEDIUM) prefLevelLabel = "Medium" prefLevelColor = "green" prefUpperLevel = 1 prefLowerLevel = 3 if(JP_LOW) prefLevelLabel = "Low" prefLevelColor = "orange" prefUpperLevel = 2 prefLowerLevel = 4 else prefLevelLabel = "NEVER" prefLevelColor = "red" prefUpperLevel = 3 prefLowerLevel = 1 HTML += "" if(rank == SSjob.overflow_role)//Overflow is special if(job_preferences[SSjob.overflow_role] == JP_LOW) HTML += "Yes" else HTML += "No" HTML += "
  
" HTML += "
" var/message = "Be an [SSjob.overflow_role] if preferences unavailable" if(joblessrole == BERANDOMJOB) message = "Get random job if preferences unavailable" else if(joblessrole == RETURNTOLOBBY) message = "Return to lobby if preferences unavailable" HTML += "

[message]
" HTML += "
Reset Preferences
" var/datum/browser/popup = new(user, "mob_occupation", "
Occupation Preferences
", width, height) popup.set_window_options("can_close=0") popup.set_content(HTML) popup.open(FALSE) /datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level) if (!job) return FALSE if (level == JP_HIGH) // to high //Set all other high to medium for(var/j in job_preferences) if(job_preferences[j] == JP_HIGH) job_preferences[j] = JP_MEDIUM //technically break here job_preferences[job.title] = level return TRUE /datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl) if(!SSjob || SSjob.occupations.len <= 0) return var/datum/job/job = SSjob.GetJob(role) if(!job) user << browse(null, "window=mob_occupation") ShowChoices(user) return if (!isnum(desiredLvl)) to_chat(user, span_danger("UpdateJobPreference - desired level was not a number. Please notify coders!")) ShowChoices(user) return var/jpval = null switch(desiredLvl) if(3) jpval = JP_LOW if(2) jpval = JP_MEDIUM if(1) jpval = JP_HIGH if(role == SSjob.overflow_role) if(job_preferences[job.title] == JP_LOW) jpval = null else jpval = JP_LOW SetJobPreferenceLevel(job, jpval) SetChoices(user) return 1 /datum/preferences/proc/ResetJobs() job_preferences = list() /datum/preferences/proc/SetQuirks(mob/user) if(!SSquirks) to_chat(user, span_danger("The quirk subsystem is still initializing! Try again in a minute.")) return var/list/dat = list() if(!SSquirks.quirks.len) dat += "The quirk subsystem hasn't finished initializing, please hold..." dat += "
Done

" else dat += "
Choose quirk setup

" dat += "
Left-click to add or remove quirks. You need negative quirks to have positive ones.
\ Quirks are applied at roundstart and cannot normally be removed.
" dat += "
Done
" dat += "
" dat += "
Current quirks: [all_quirks.len ? all_quirks.Join(", ") : "None"]
" dat += "
[GetPositiveQuirkCount()] / [MAX_QUIRKS] max positive quirks
\ Quirk balance remaining: [GetQuirkBalance()]

" for(var/V in SSquirks.quirks) var/datum/quirk/T = SSquirks.quirks[V] var/quirk_name = initial(T.name) var/has_quirk var/quirk_cost = initial(T.value) * -1 var/lock_reason = "This trait is unavailable." var/quirk_conflict = FALSE for(var/_V in all_quirks) if(_V == quirk_name) has_quirk = TRUE if(initial(T.mood_quirk) && CONFIG_GET(flag/disable_human_mood)) lock_reason = "Mood is disabled." quirk_conflict = TRUE if(has_quirk) if(quirk_conflict) all_quirks -= quirk_name has_quirk = FALSE else quirk_cost *= -1 //invert it back, since we'd be regaining this amount if(quirk_cost > 0) quirk_cost = "+[quirk_cost]" var/font_color = "#AAAAFF" if(initial(T.value) != 0) font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA" if(quirk_conflict) dat += "[quirk_name] - [initial(T.desc)] \ LOCKED: [lock_reason]
" else if(has_quirk) dat += "[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.) \ [quirk_name] - [initial(T.desc)]
" else dat += "[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.) \ [quirk_name] - [initial(T.desc)]
" dat += "
Reset Quirks
" var/datum/browser/popup = new(user, "mob_occupation", "
Quirk Preferences
", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way popup.set_window_options("can_close=0") popup.set_content(dat.Join()) popup.open(FALSE) /datum/preferences/proc/GetQuirkBalance() var/bal = 0 for(var/V in all_quirks) var/datum/quirk/T = SSquirks.quirks[V] bal -= initial(T.value) return bal /datum/preferences/proc/GetPositiveQuirkCount() . = 0 for(var/q in all_quirks) if(SSquirks.quirk_points[q] > 0) .++ /datum/preferences/proc/validate_quirks() if(GetQuirkBalance() < 0) all_quirks = list() /datum/preferences/Topic(href, href_list, hsrc) //yeah, gotta do this I guess.. . = ..() if(href_list["close"]) var/client/C = usr.client if(C) C.clear_character_previews() /datum/preferences/proc/process_link(mob/user, list/href_list) if(href_list["bancheck"]) var/list/ban_details = is_banned_from_with_details(user.ckey, user.client.address, user.client.computer_id, href_list["bancheck"]) var/admin = FALSE if(GLOB.admin_datums[user.ckey] || GLOB.deadmins[user.ckey]) admin = TRUE for(var/i in ban_details) if(admin && !text2num(i["applies_to_admins"])) continue ban_details = i break //we only want to get the most recent ban's details if(ban_details?.len) var/expires = "This is a permanent ban." if(ban_details["expiration_time"]) expires = " The ban is for [DisplayTimeText(text2num(ban_details["duration"]) MINUTES)] and expires on [ban_details["expiration_time"]] (server time)." to_chat(user, span_danger("You, or another user of this computer or connection ([ban_details["key"]]) is banned from playing [href_list["bancheck"]].
The ban reason is: [ban_details["reason"]]
This ban (BanID #[ban_details["id"]]) was applied by [ban_details["admin_key"]] on [ban_details["bantime"]] during round ID [ban_details["round_id"]].
[expires]")) return if(href_list["preference"] == "job") switch(href_list["task"]) if("close") user << browse(null, "window=mob_occupation") ShowChoices(user) if("reset") ResetJobs() SetChoices(user) if("random") switch(joblessrole) if(RETURNTOLOBBY) if(is_banned_from(user.ckey, SSjob.overflow_role)) joblessrole = BERANDOMJOB else joblessrole = BEOVERFLOW if(BEOVERFLOW) joblessrole = BERANDOMJOB if(BERANDOMJOB) joblessrole = RETURNTOLOBBY SetChoices(user) if("setJobLevel") UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) else SetChoices(user) return 1 else if(href_list["preference"] == "trait") switch(href_list["task"]) if("close") user << browse(null, "window=mob_occupation") ShowChoices(user) if("update") var/quirk = href_list["trait"] if(!SSquirks.quirks[quirk]) return for(var/V in SSquirks.quirk_blacklist) //V is a list var/list/L = V if(!(quirk in L)) continue for(var/Q in all_quirks) if((Q in L) && !(Q == quirk)) //two quirks have lined up in the list of the list of quirks that conflict with each other, so return (see quirks.dm for more details) to_chat(user, span_danger("[quirk] is incompatible with [Q].")) return var/value = SSquirks.quirk_points[quirk] var/balance = GetQuirkBalance() if(quirk in all_quirks) if(balance + value < 0) to_chat(user, span_warning("Refunding this would cause you to go below your balance!")) return all_quirks -= quirk else var/is_positive_quirk = SSquirks.quirk_points[quirk] > 0 if(is_positive_quirk && GetPositiveQuirkCount() >= MAX_QUIRKS) to_chat(user, span_warning("You can't have more than [MAX_QUIRKS] positive quirks!")) return if(balance - value < 0) to_chat(user, span_warning("You don't have enough balance to gain this quirk!")) return all_quirks += quirk SetQuirks(user) if("reset") all_quirks = list() SetQuirks(user) else SetQuirks(user) return TRUE switch(href_list["task"]) if("random") switch(href_list["preference"]) if("name") real_name = pref_species.random_name(gender,1) if("age") age = rand(AGE_MIN, AGE_MAX) if("hair") hair_color = random_short_color() if("hairstyle") hairstyle = random_hairstyle(gender) if("facial") facial_hair_color = random_short_color() if("facial_hairstyle") facial_hairstyle = random_facial_hairstyle(gender) if("underwear") underwear = random_underwear(gender) if("underwear_color") underwear_color = random_short_color() if("undershirt") undershirt = random_undershirt(gender) if("socks") socks = random_socks() if(BODY_ZONE_PRECISE_EYES) eye_color = random_eye_color() if("s_tone") skin_tone = random_skin_tone() if("species") random_species() if("bag") backpack = pick(GLOB.backpacklist) if("suit") jumpsuit_style = pick(GLOB.jumpsuitlist) if("all") random_character(gender) if("input") if(href_list["preference"] in GLOB.preferences_custom_names) ask_for_custom_name(user,href_list["preference"]) switch(href_list["preference"]) if("ghostform") if(unlock_content) var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in GLOB.ghost_forms if(new_form) ghost_form = new_form if("ghostorbit") if(unlock_content) var/new_orbit = input(user, "Thanks for supporting BYOND - Choose your ghostly orbit:","Thanks for supporting BYOND", null) as null|anything in GLOB.ghost_orbits if(new_orbit) ghost_orbit = new_orbit if("ghostaccs") var/new_ghost_accs = tgui_alert(usr,"Do you want your ghost to show full accessories where possible, hide accessories but still use the directional sprites where possible, or also ignore the directions and stick to the default sprites?",,list(GHOST_ACCS_FULL_NAME, GHOST_ACCS_DIR_NAME, GHOST_ACCS_NONE_NAME)) switch(new_ghost_accs) if(GHOST_ACCS_FULL_NAME) ghost_accs = GHOST_ACCS_FULL if(GHOST_ACCS_DIR_NAME) ghost_accs = GHOST_ACCS_DIR if(GHOST_ACCS_NONE_NAME) ghost_accs = GHOST_ACCS_NONE if("ghostothers") var/new_ghost_others = tgui_alert(usr,"Do you want the ghosts of others to show up as their own setting, as their default sprites or always as the default white ghost?",,list(GHOST_OTHERS_THEIR_SETTING_NAME, GHOST_OTHERS_DEFAULT_SPRITE_NAME, GHOST_OTHERS_SIMPLE_NAME)) switch(new_ghost_others) if(GHOST_OTHERS_THEIR_SETTING_NAME) ghost_others = GHOST_OTHERS_THEIR_SETTING if(GHOST_OTHERS_DEFAULT_SPRITE_NAME) ghost_others = GHOST_OTHERS_DEFAULT_SPRITE if(GHOST_OTHERS_SIMPLE_NAME) ghost_others = GHOST_OTHERS_SIMPLE if("name") var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null if(new_name) new_name = reject_bad_name(new_name) if(new_name) real_name = new_name else to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and . It must not contain any words restricted by IC chat and name filters.") if("age") var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null if(new_age) age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) if("hair") var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null if(new_hair) hair_color = sanitize_hexcolor(new_hair) if("hairstyle") var/new_hairstyle = input(user, "Choose your character's hairstyle:", "Character Preference") as null|anything in GLOB.hairstyles_list if(new_hairstyle) hairstyle = new_hairstyle if("next_hairstyle") hairstyle = next_list_item(hairstyle, GLOB.hairstyles_list) if("previous_hairstyle") hairstyle = previous_list_item(hairstyle, GLOB.hairstyles_list) if("facial") var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference","#"+facial_hair_color) as color|null if(new_facial) facial_hair_color = sanitize_hexcolor(new_facial) if("facial_hairstyle") var/new_facial_hairstyle = input(user, "Choose your character's facial-hairstyle:", "Character Preference") as null|anything in GLOB.facial_hairstyles_list if(new_facial_hairstyle) facial_hairstyle = new_facial_hairstyle if("next_facehairstyle") facial_hairstyle = next_list_item(facial_hairstyle, GLOB.facial_hairstyles_list) if("previous_facehairstyle") facial_hairstyle = previous_list_item(facial_hairstyle, GLOB.facial_hairstyles_list) if("underwear") var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_list if(new_underwear) underwear = new_underwear if("underwear_color") var/new_underwear_color = input(user, "Choose your character's underwear color:", "Character Preference","#"+underwear_color) as color|null if(new_underwear_color) underwear_color = sanitize_hexcolor(new_underwear_color) if("undershirt") var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_list if(new_undershirt) undershirt = new_undershirt if("socks") var/new_socks new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list if(new_socks) socks = new_socks if("eyes") var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null if(new_eyes) eye_color = sanitize_hexcolor(new_eyes) if("species") var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_races if(result) var/newtype = GLOB.species_list[result] pref_species = new newtype() //Now that we changed our species, we must verify that the mutant colour is still allowed. var/temp_hsv = RGBtoHSV(features["mcolor"]) if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#7F7F7F")[3])) features["mcolor"] = pref_species.default_color if(randomise[RANDOM_NAME]) real_name = pref_species.random_name(gender) if("mutant_color") var/new_mutantcolor = input(user, "Choose your character's alien/mutant color:", "Character Preference","#"+features["mcolor"]) as color|null if(new_mutantcolor) var/temp_hsv = RGBtoHSV(new_mutantcolor) if(new_mutantcolor == "#000000") features["mcolor"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright, but only if they affect the skin features["mcolor"] = sanitize_hexcolor(new_mutantcolor) else to_chat(user, span_danger("Invalid color. Your color is not bright enough.")) if("color_ethereal") var/new_etherealcolor = input(user, "Choose your ethereal color", "Character Preference") as null|anything in GLOB.color_list_ethereal if(new_etherealcolor) features["ethcolor"] = GLOB.color_list_ethereal[new_etherealcolor] if("tail_lizard") var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_lizard if(new_tail) features["tail_lizard"] = new_tail if("tail_human") var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_human if(new_tail) features["tail_human"] = new_tail if("snout") var/new_snout new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.snouts_list if(new_snout) features["snout"] = new_snout if("horns") var/new_horns new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list if(new_horns) features["horns"] = new_horns if("ears") var/new_ears new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.ears_list if(new_ears) features["ears"] = new_ears if("wings") var/new_wings new_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.r_wings_list if(new_wings) features["wings"] = new_wings if("frills") var/new_frills new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list if(new_frills) features["frills"] = new_frills if("spines") var/new_spines new_spines = input(user, "Choose your character's spines:", "Character Preference") as null|anything in GLOB.spines_list if(new_spines) features["spines"] = new_spines if("body_markings") var/new_body_markings new_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.body_markings_list if(new_body_markings) features["body_markings"] = new_body_markings if("legs") var/new_legs new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in GLOB.legs_list if(new_legs) features["legs"] = new_legs if("moth_wings") var/new_moth_wings new_moth_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.moth_wings_list if(new_moth_wings) features["moth_wings"] = new_moth_wings if("moth_antennae") var/new_moth_antennae new_moth_antennae = input(user, "Choose your character's antennae:", "Character Preference") as null|anything in GLOB.moth_antennae_list if(new_moth_antennae) features["moth_antennae"] = new_moth_antennae if("moth_markings") var/new_moth_markings new_moth_markings = input(user, "Choose your character's markings:", "Character Preference") as null|anything in GLOB.moth_markings_list if(new_moth_markings) features["moth_markings"] = new_moth_markings if("s_tone") var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in GLOB.skin_tones if(new_s_tone) skin_tone = new_s_tone if("ooccolor") var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null if(new_ooccolor) ooccolor = sanitize_ooccolor(new_ooccolor) if("asaycolor") var/new_asaycolor = input(user, "Choose your ASAY color:", "Game Preference",asaycolor) as color|null if(new_asaycolor) asaycolor = sanitize_ooccolor(new_asaycolor) if("briefoutfit") var/list/valid_paths = list() for(var/datum/outfit/outfit_path as anything in subtypesof(/datum/outfit)) valid_paths[initial(outfit_path.name)] = outfit_path var/new_outfit = input(user, "Choose your briefing officer outfit:", "Game Preference") as null|anything in valid_paths new_outfit = valid_paths[new_outfit] if(new_outfit) brief_outfit = new_outfit if("bag") var/new_backpack = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backpacklist if(new_backpack) backpack = new_backpack if("suit") if(jumpsuit_style == PREF_SUIT) jumpsuit_style = PREF_SKIRT else jumpsuit_style = PREF_SUIT if("uplink_loc") var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in GLOB.uplink_spawn_loc_list if(new_loc) // This is done to prevent affecting saves uplink_spawn_loc = new_loc == UPLINK_IMPLANT_WITH_PRICE ? UPLINK_IMPLANT : new_loc if("playtime_reward_cloak") if (user.client.get_exp_living(TRUE) >= PLAYTIME_VETERAN) playtime_reward_cloak = !playtime_reward_cloak if("ai_core_icon") var/ai_core_icon = input(user, "Choose your preferred AI core display screen:", "AI Core Display Screen Selection") as null|anything in GLOB.ai_core_display_screens - "Portrait" if(ai_core_icon) preferred_ai_core_display = ai_core_icon if("sec_dept") var/department = input(user, "Choose your preferred security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs if(department) prefered_security_department = department if ("preferred_map") var/maplist = list() var/default = "Default" if (config.defaultmap) default += " ([config.defaultmap.map_name])" for (var/M in config.maplist) var/datum/map_config/VM = config.maplist[M] if(!VM.votable) continue var/friendlyname = "[VM.map_name] " if (VM.voteweight <= 0) friendlyname += " (disabled)" maplist[friendlyname] = VM.map_name maplist[default] = null var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in sortList(maplist) if (pickedmap) preferred_map = maplist[pickedmap] if ("clientfps") var/desiredfps = input(user, "Choose your desired fps.\n-1 means recommended value (currently:[RECOMMENDED_FPS])\n0 means world fps (currently:[world.fps])", "Character Preference", clientfps) as null|num if (!isnull(desiredfps)) clientfps = sanitize_integer(desiredfps, -1, 1000, clientfps) parent.fps = (clientfps < 0) ? RECOMMENDED_FPS : clientfps if("ui") var/pickedui = input(user, "Choose your UI style.", "Character Preference", UI_style) as null|anything in sortList(GLOB.available_ui_styles) if(pickedui) UI_style = pickedui if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_ui_style(ui_style2icon(UI_style)) if("pda_style") var/pickedPDAStyle = input(user, "Choose your PDA style.", "Character Preference", pda_style) as null|anything in GLOB.pda_styles if(pickedPDAStyle) pda_style = pickedPDAStyle if("pda_color") var/pickedPDAColor = input(user, "Choose your PDA Interface color.", "Character Preference", pda_color) as color|null if(pickedPDAColor) pda_color = pickedPDAColor if("phobia") var/phobiaType = input(user, "What are you scared of?", "Character Preference", phobia) as null|anything in SStraumas.phobia_types if(phobiaType) phobia = phobiaType if ("max_chat_length") var/desiredlength = input(user, "Choose the max character length of shown Runechat messages. Valid range is 1 to [CHAT_MESSAGE_MAX_LENGTH] (default: [initial(max_chat_length)]))", "Character Preference", max_chat_length) as null|num if (!isnull(desiredlength)) max_chat_length = clamp(desiredlength, 1, CHAT_MESSAGE_MAX_LENGTH) else switch(href_list["preference"]) if("publicity") if(unlock_content) toggles ^= MEMBER_PUBLIC if("gender") var/list/friendlyGenders = list("Male" = "male", "Female" = "female", "Other" = "plural") var/pickedGender = input(user, "Choose your gender.", "Character Preference", gender) as null|anything in friendlyGenders if(pickedGender && friendlyGenders[pickedGender] != gender) gender = friendlyGenders[pickedGender] underwear = random_underwear(gender) undershirt = random_undershirt(gender) socks = random_socks() facial_hairstyle = random_facial_hairstyle(gender) hairstyle = random_hairstyle(gender) if("body_type") if(body_type == MALE) body_type = FEMALE else body_type = MALE if("hotkeys") hotkeys = !hotkeys if(hotkeys) winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED]") else winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_DISABLED]") if("keybindings_capture") var/datum/keybinding/kb = GLOB.keybindings_by_name[href_list["keybinding"]] var/old_key = href_list["old_key"] CaptureKeybinding(user, kb, old_key) return if("keybindings_set") var/kb_name = href_list["keybinding"] if(!kb_name) user << browse(null, "window=capturekeypress") ShowChoices(user) return var/clear_key = text2num(href_list["clear_key"]) var/old_key = href_list["old_key"] if(clear_key) if(key_bindings[old_key]) key_bindings[old_key] -= kb_name LAZYADD(key_bindings["Unbound"], kb_name) if(!length(key_bindings[old_key])) key_bindings -= old_key user << browse(null, "window=capturekeypress") user.client.set_macros() save_preferences() ShowChoices(user) return var/new_key = uppertext(href_list["key"]) var/AltMod = text2num(href_list["alt"]) ? "Alt" : "" var/CtrlMod = text2num(href_list["ctrl"]) ? "Ctrl" : "" var/ShiftMod = text2num(href_list["shift"]) ? "Shift" : "" var/numpad = text2num(href_list["numpad"]) ? "Numpad" : "" // var/key_code = text2num(href_list["key_code"]) if(GLOB._kbMap[new_key]) new_key = GLOB._kbMap[new_key] var/full_key switch(new_key) if("Alt") full_key = "[new_key][CtrlMod][ShiftMod]" if("Ctrl") full_key = "[AltMod][new_key][ShiftMod]" if("Shift") full_key = "[AltMod][CtrlMod][new_key]" else full_key = "[AltMod][CtrlMod][ShiftMod][numpad][new_key]" if(kb_name in key_bindings[full_key]) //We pressed the same key combination that was already bound here, so let's remove to re-add and re-sort. key_bindings[full_key] -= kb_name if(key_bindings[old_key]) key_bindings[old_key] -= kb_name if(!length(key_bindings[old_key])) key_bindings -= old_key key_bindings[full_key] += list(kb_name) key_bindings[full_key] = sortList(key_bindings[full_key]) user << browse(null, "window=capturekeypress") user.client.set_macros() save_preferences() if("keybindings_reset") var/choice = tgui_alert(user, "Would you prefer 'hotkey' or 'classic' defaults?", "Setup keybindings", list("Hotkey", "Classic", "Cancel"), 60 SECONDS) if(choice == "Cancel") ShowChoices(user) return hotkeys = (choice == "Hotkey") key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key) user.client.set_macros() if("chat_on_map") chat_on_map = !chat_on_map if("see_chat_non_mob") see_chat_non_mob = !see_chat_non_mob if("see_rc_emotes") see_rc_emotes = !see_rc_emotes if("action_buttons") buttons_locked = !buttons_locked if("tgui_fancy") tgui_fancy = !tgui_fancy if("tgui_lock") tgui_lock = !tgui_lock if("winflash") windowflashing = !windowflashing //here lies the badmins if("hear_adminhelps") user.client.toggleadminhelpsound() if("hear_prayers") user.client.toggle_prayer_sound() if("announce_login") user.client.toggleannouncelogin() if("combohud_lighting") toggles ^= COMBOHUD_LIGHTING if("toggle_dead_chat") user.client.deadchat() if("toggle_radio_chatter") user.client.toggle_hear_radio() if("toggle_split_admin_tabs") toggles ^= SPLIT_ADMIN_TABS if("toggle_prayers") user.client.toggleprayers() if("toggle_deadmin_always") toggles ^= DEADMIN_ALWAYS if("toggle_deadmin_antag") toggles ^= DEADMIN_ANTAGONIST if("toggle_deadmin_head") toggles ^= DEADMIN_POSITION_HEAD if("toggle_deadmin_security") toggles ^= DEADMIN_POSITION_SECURITY if("toggle_deadmin_silicon") toggles ^= DEADMIN_POSITION_SILICON if("toggle_ignore_cult_ghost") toggles ^= ADMIN_IGNORE_CULT_GHOST if("be_special") var/be_special_type = href_list["be_special_type"] if(be_special_type in be_special) be_special -= be_special_type else be_special += be_special_type if("toggle_random") var/random_type = href_list["random_type"] if(randomise[random_type]) randomise -= random_type else randomise[random_type] = TRUE if("persistent_scars") persistent_scars = !persistent_scars if("clear_scars") var/path = "data/player_saves/[user.ckey[1]]/[user.ckey]/scars.sav" fdel(path) to_chat(user, span_notice("All scar slots cleared.")) if("hear_midis") toggles ^= SOUND_MIDI if("lobby_music") toggles ^= SOUND_LOBBY if((toggles & SOUND_LOBBY) && user.client && isnewplayer(user)) user.client.playtitlemusic() else user.stop_sound_channel(CHANNEL_LOBBYMUSIC) if("endofround_sounds") toggles ^= SOUND_ENDOFROUND if("combat_mode_sound") toggles ^= SOUND_COMBATMODE if("ghost_ears") chat_toggles ^= CHAT_GHOSTEARS if("ghost_sight") chat_toggles ^= CHAT_GHOSTSIGHT if("ghost_whispers") chat_toggles ^= CHAT_GHOSTWHISPER if("ghost_radio") chat_toggles ^= CHAT_GHOSTRADIO if("ghost_pda") chat_toggles ^= CHAT_GHOSTPDA if("ghost_laws") chat_toggles ^= CHAT_GHOSTLAWS if("hear_login_logout") chat_toggles ^= CHAT_LOGIN_LOGOUT if("broadcast_login_logout") broadcast_login_logout = !broadcast_login_logout if("income_pings") chat_toggles ^= CHAT_BANKCARD if("pull_requests") chat_toggles ^= CHAT_PULLR if("allow_midround_antag") toggles ^= MIDROUND_ANTAG if("parallaxup") parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_parallax_pref(parent.mob) if("parallaxdown") parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) if (parent && parent.mob && parent.mob.hud_used) parent.mob.hud_used.update_parallax_pref(parent.mob) if("screentipmode") screentip_pref = !screentip_pref if("screentipcolor") var/new_screentipcolor = input(user, "Choose your screentip color:", "Character Preference", screentip_color) as color|null if(new_screentipcolor) screentip_color = sanitize_ooccolor(new_screentipcolor) if("itemoutline_pref") itemoutline_pref = !itemoutline_pref if("ambientocclusion") ambientocclusion = !ambientocclusion if(parent?.screen && parent.screen.len) var/atom/movable/screen/plane_master/game_world/PM = locate(/atom/movable/screen/plane_master/game_world) in parent.screen PM.backdrop(parent.mob) if("auto_fit_viewport") auto_fit_viewport = !auto_fit_viewport if(auto_fit_viewport && parent) parent.fit_viewport() if("widescreenpref") widescreenpref = !widescreenpref user.client.view_size.setDefault(getScreenSize(widescreenpref)) if("pixel_size") switch(pixel_size) if(PIXEL_SCALING_AUTO) pixel_size = PIXEL_SCALING_1X if(PIXEL_SCALING_1X) pixel_size = PIXEL_SCALING_1_2X if(PIXEL_SCALING_1_2X) pixel_size = PIXEL_SCALING_2X if(PIXEL_SCALING_2X) pixel_size = PIXEL_SCALING_3X if(PIXEL_SCALING_3X) pixel_size = PIXEL_SCALING_AUTO user.client.view_size.apply() //Let's winset() it so it actually works if("scaling_method") switch(scaling_method) if(SCALING_METHOD_NORMAL) scaling_method = SCALING_METHOD_DISTORT if(SCALING_METHOD_DISTORT) scaling_method = SCALING_METHOD_BLUR if(SCALING_METHOD_BLUR) scaling_method = SCALING_METHOD_NORMAL user.client.view_size.setZoomMode() if("save") save_preferences() save_character() if("load") load_preferences() load_character() if("changeslot") if(!load_character(text2num(href_list["num"]))) random_character() real_name = random_unique_name(gender) save_character() if("tab") if (href_list["tab"]) current_tab = text2num(href_list["tab"]) if("clear_heart") hearted = FALSE hearted_until = null to_chat(user, span_notice("OOC Commendation Heart disabled")) save_preferences() ShowChoices(user) return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE, character_setup = FALSE, antagonist = FALSE, is_latejoiner = TRUE) hardcore_survival_score = 0 //Set to 0 to prevent you getting points from last another time. if((randomise[RANDOM_SPECIES] || randomise[RANDOM_HARDCORE]) && !character_setup) random_species() if((randomise[RANDOM_BODY] || (randomise[RANDOM_BODY_ANTAG] && antagonist) || randomise[RANDOM_HARDCORE]) && !character_setup) slot_randomized = TRUE random_character(gender, antagonist) if((randomise[RANDOM_NAME] || (randomise[RANDOM_NAME_ANTAG] && antagonist) || randomise[RANDOM_HARDCORE]) && !character_setup) slot_randomized = TRUE real_name = pref_species.random_name(gender) if(randomise[RANDOM_HARDCORE] && parent.mob.mind && !character_setup) if(can_be_random_hardcore()) hardcore_random_setup(character, antagonist, is_latejoiner) if(roundstart_checks) if(CONFIG_GET(flag/humans_need_surnames) && (pref_species.id == SPECIES_HUMAN)) var/firstspace = findtext(real_name, " ") var/name_length = length(real_name) if(!firstspace) //we need a surname real_name += " [pick(GLOB.last_names)]" else if(firstspace == name_length) real_name += "[pick(GLOB.last_names)]" character.real_name = real_name character.name = character.real_name character.gender = gender character.age = age if(gender == MALE || gender == FEMALE) character.body_type = gender else character.body_type = body_type character.eye_color = eye_color var/obj/item/organ/eyes/organ_eyes = character.getorgan(/obj/item/organ/eyes) if(organ_eyes) if(!initial(organ_eyes.eye_color)) organ_eyes.eye_color = eye_color organ_eyes.old_eye_color = eye_color character.hair_color = hair_color character.facial_hair_color = facial_hair_color character.skin_tone = skin_tone character.hairstyle = hairstyle character.facial_hairstyle = facial_hairstyle character.underwear = underwear character.underwear_color = underwear_color character.undershirt = undershirt character.socks = socks character.backpack = backpack character.jumpsuit_style = jumpsuit_style var/datum/species/chosen_species chosen_species = pref_species.type if(roundstart_checks && !(pref_species.id in GLOB.roundstart_races) && !(pref_species.id in (CONFIG_GET(keyed_list/roundstart_no_hard_check)))) chosen_species = /datum/species/human pref_species = new /datum/species/human save_character() character.dna.features = features.Copy() character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE) character.dna.real_name = character.real_name if(pref_species.mutant_bodyparts["tail_lizard"]) character.dna.species.mutant_bodyparts["tail_lizard"] = pref_species.mutant_bodyparts["tail_lizard"] if(pref_species.mutant_bodyparts["spines"]) character.dna.species.mutant_bodyparts["spines"] = pref_species.mutant_bodyparts["spines"] if(icon_updates) character.update_body() character.update_hair() character.update_body_parts() /datum/preferences/proc/can_be_random_hardcore() if(parent.mob.mind.assigned_role in GLOB.command_positions) //No command staff return FALSE for(var/A in parent.mob.mind.antag_datums) var/datum/antagonist/antag if(antag.get_team()) //No team antags return FALSE return TRUE /datum/preferences/proc/get_default_name(name_id) switch(name_id) if("human") return random_unique_name() if("ai") return pick(GLOB.ai_names) if("cyborg") return DEFAULT_CYBORG_NAME if("clown") return pick(GLOB.clown_names) if("mime") return pick(GLOB.mime_names) if("religion") return pick(GLOB.religion_names) if("deity") return DEFAULT_DEITY if("bible") return DEFAULT_BIBLE return random_unique_name() /datum/preferences/proc/ask_for_custom_name(mob/user,name_id) var/namedata = GLOB.preferences_custom_names[name_id] if(!namedata) return var/raw_name = input(user, "Choose your character's [namedata["qdesc"]]:","Character Preference") as text|null if(!raw_name) if(namedata["allow_null"]) custom_names[name_id] = get_default_name(name_id) else return else var/sanitized_name = reject_bad_name(raw_name,namedata["allow_numbers"]) if(!sanitized_name) to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, [namedata["allow_numbers"] ? "0-9, " : ""]-, ' and . It must not contain any words restricted by IC chat and name filters.") return else custom_names[name_id] = sanitized_name if(name_id == "religion") update_bible_and_deity_name(custom_names[name_id]) /datum/preferences/proc/update_bible_and_deity_name(religion) switch(lowertext(religion)) if("christianity") // DEFAULT_RELIGION custom_names["bible"] = pick("The Holy Bible","The Dead Sea Scrolls") custom_names["deity"] = "Space Jesus" if("buddhism") custom_names["bible"] = "The Sutras" custom_names["deity"] = "Buddha" if("clownism","honkmother","honk","honkism","comedy") custom_names["bible"] = pick("The Holy Joke Book", "Just a Prank", "Hymns to the Honkmother") custom_names["deity"] = "The Honkmother" if("chaos") custom_names["bible"] = "The Book of Lorgar" custom_names["deity"] = pick("Chaos Gods", "Dark Gods", "Ruinous Powers") if("cthulhu") custom_names["bible"] = "The Necronomicon" custom_names["deity"] = pick("Great Old Ones", "Old Ones") if("hinduism") custom_names["bible"] = "The Vedas" custom_names["deity"] = pick("Brahma", "Vishnu", "Shiva") if("imperium") custom_names["bible"] = "Uplifting Primer" custom_names["deity"] = "Astra Militarum" if("islam") custom_names["bible"] = "Quran" custom_names["deity"] = "Allah" if("judaism") custom_names["bible"] = "The Torah" custom_names["deity"] = "Yahweh" if("lampism") custom_names["bible"] = "Fluorescent Incandescence" custom_names["deity"] = "Lamp" if("monkeyism","apism","gorillism","primatism") custom_names["bible"] = pick("Going Bananas", "Bananas Out For Harambe") custom_names["deity"] = pick("Harambe", "monky") if("mormonism") custom_names["bible"] = "The Book of Mormon" custom_names["deity"] = pick("God", "Elohim", "Godhead") if("pastafarianism") custom_names["bible"] = "The Gospel of the Flying Spaghetti Monster" custom_names["deity"] = "Flying Spaghetti Monster" if("rastafarianism","rasta") custom_names["bible"] = "The Holy Piby" custom_names["deity"] = "Haile Selassie I" if("satanism") custom_names["bible"] = "The Unholy Bible" custom_names["deity"] = "Satan" if("sikhism") custom_names["bible"] = "Guru Granth Sahib" custom_names["deity"] = "Waheguru" if("science") custom_names["bible"] = pick("Principle of Relativity", "Quantum Enigma: Physics Encounters Consciousness", "Programming the Universe", "Quantum Physics and Theology", "String Theory for Dummies", "How To: Build Your Own Warp Drive", "The Mysteries of Bluespace", "Playing God: Collector's Edition") custom_names["deity"] = pick("Albert Einstein", "Stephen Hawking", "Neil deGrasse Tyson", "Carl Sagan", "Richard Dawkins") if("scientology") custom_names["bible"] = pick("The Biography of L. Ron Hubbard","Dianetics") custom_names["deity"] = pick("Money", "Power", "Xenu", "Tom Cruise", "L. Ron Hubbard", "David Miscavige", "John Travolta") if("servicianism", "partying") custom_names["bible"] = "The Tenets of Servicia" custom_names["deity"] = pick("Servicia", "Space Bacchus", "Space Dionysus") if("subgenius") custom_names["bible"] = "Book of the SubGenius" custom_names["deity"] = pick("Jehovah 1", "J. R. \"Bob\" Dobbs") if("toolboxia","greytide") custom_names["bible"] = pick("Toolbox Manifesto","iGlove Assistants") custom_names["deity"] = "Maintenance" else if(custom_names["bible"] == DEFAULT_BIBLE) custom_names["bible"] = "The Holy Book of [religion]"