/* CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! *\ | THIS FILE CONTAINS HOOKS FOR FOR | | CHANGES SPECIFIC TO CITADEL. IF | | YOU'RE FIXING A MERGE CONFLICT | | HERE, PLEASE ASK FOR REVIEW FROM | | ANOTHER MAINTAINER TO ENSURE YOU | | DON'T INTRODUCE REGRESSIONS. | \* */ 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 = 16 //non-preference stuff var/muted = 0 var/last_ip var/last_id var/icon/custom_holoform_icon var/list/cached_holoform_icons var/last_custom_holoform = 0 //Cooldowns for saving/loading. These are four are all separate due to loading code calling these one after another var/saveprefcooldown var/loadprefcooldown var/savecharcooldown var/loadcharcooldown //game-preferences var/lastchangelog = "" //Saved changlog filesize to detect if there was a change var/ooccolor = "#c43b23" var/aooccolor = "#ce254f" 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 = FALSE var/tgui_fancy = TRUE var/tgui_lock = TRUE 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/preferred_chaos = null var/pda_style = MONO var/pda_color = "#808000" var/pda_skin = PDA_SKIN_ALT var/uses_glasses_colour = 0 //character preferences var/real_name //our character's name var/nameless = FALSE //whether or not our character is nameless var/be_random_name = 0 //whether we'll have a random name every round var/be_random_body = 0 //whether we'll have a random body every round var/gender = MALE //gender of character (well duh) var/age = 30 //age of character var/underwear = "Nude" //underwear type var/undie_color = "FFF" var/undershirt = "Nude" //undershirt type var/shirt_color = "FFF" var/socks = "Nude" //socks type var/socks_color = "FFF" var/backbag = DBACKPACK //backpack type var/jumpsuit_style = PREF_SUIT //suit/skirt var/hair_style = "Bald" //Hair type var/hair_color = "000" //Hair color var/facial_hair_style = "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/horn_color = "85615a" //Horn color var/wing_color = "fff" //Wing color var/datum/species/pref_species = new /datum/species/human() //Mutant race var/list/features = list("mcolor" = "FFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None", "wings" = "None", "frills" = "None", "deco_wings" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Plantigrade", "insect_wings" = "Plain", "insect_fluff" = "None", "insect_markings" = "None", "mcolor2" = "FFF", "mcolor3" = "FFF", "mam_body_markings" = "Plain", "mam_ears" = "None", "mam_snouts" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", "xenodorsal" = "Standard", "xenohead" = "Standard", "xenotail" = "Xenomorph Tail", "taur" = "None", "genitals_use_skintone" = FALSE, "has_cock" = FALSE, "cock_shape" = "Human", "cock_length" = 6, "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, "cock_color" = "fff", "has_sheath" = FALSE, "sheath_color" = "fff", "has_balls" = FALSE, "balls_internal" = FALSE, "balls_color" = "fff", "balls_amount" = 2, "balls_sack_size" = BALLS_SACK_SIZE_DEF, "balls_shape" = "Single", "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_ovi" = FALSE, "ovi_shape" = "knotted", "ovi_length" = 6, "ovi_color" = "fff", "has_eggsack" = FALSE, "eggsack_internal" = TRUE, "eggsack_color" = "fff", "eggsack_size" = BALLS_SACK_SIZE_DEF, "eggsack_egg_color" = "fff", "eggsack_egg_size" = EGG_GIRTH_DEF, "has_breasts" = FALSE, "breasts_color" = "fff", "breasts_size" = "C", "breasts_shape" = "Pair", "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = "Human", "vag_color" = "fff", "vag_clits" = 1, "vag_clit_diam" = 0.25, "has_womb" = FALSE, "womb_cum_rate" = CUM_RATE, "womb_cum_mult" = CUM_RATE_MULT, "womb_efficiency" = CUM_EFFICIENCY, "ipc_screen" = "Sunburst", "ipc_antenna" = "None", "flavor_text" = "", "meat_type" = "Mammalian" ) var/list/custom_names = list() var/preferred_ai_core_display = "Blue" var/prefered_security_department = SEC_DEPT_RANDOM var/custom_species = null //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 = 0 var/parallax var/ambientocclusion = TRUE var/auto_fit_viewport = TRUE var/uplink_spawn_loc = UPLINK_PDA var/sprint_spacebar = FALSE var/sprint_toggle = FALSE var/list/exp = list() var/list/menuoptions var/action_buttons_screen_locs = list() //bad stuff var/digestable = FALSE var/devourable = FALSE var/feeding = FALSE var/lickable = FALSE var/list/belly_prefs = list() var/vore_taste = "nothing in particular" //backgrounds var/mutable_appearance/character_background var/icon/bgstate = "steel" var/list/bgstate_options = list("000", "midgrey", "FFF", "white", "steel", "techmaint", "dark", "plating", "reinforced") /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 = 24 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. 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 5 /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return update_preview_icon(current_tab != 2) var/list/dat = list("
") dat += "Character Settings" dat += "Character Appearance" dat += "Loadout" dat += "Game Preferences" dat += "Content Preferences" 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(jobban_isbanned(user, "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:[be_random_name ? "Yes" : "No"]
" dat += "[nameless ? "Default designation" : "Name"]:" dat += "[real_name]
" dat += "Be nameless: [nameless ? "Yes" : "No"]
" dat += "Gender: [gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
" dat += "Age: [age]
" 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]
" //Character Appearance if(2) 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 += "" else if(use_skintones || mutant_colors) dat += "" if(HAIR in pref_species.species_traits) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Hair Style

" dat += "[hair_style]" dat += "<>
" dat += "   Change
" dat += "

Facial Hair Style

" dat += "[facial_hair_style]" dat += "<>
" dat += "   Change
" dat += "" //Mutant stuff var/mutant_category = 0 if("tail_lizard" in pref_species.default_features) 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("mam_tail" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Tail

" dat += "[features["mam_tail"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("tail_human" in pref_species.default_features) 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("meat_type" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Meat Type

" dat += "[features["meat_type"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("snout" in pref_species.default_features) 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("horns" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Horns

" dat += "[features["horns"]]" dat += "   Change
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" if("frills" in pref_species.default_features) 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("spines" in pref_species.default_features) 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("body_markings" in pref_species.default_features) 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("mam_body_markings" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Species Markings

" dat += "[features["mam_body_markings"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" if("mam_ears" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Ears

" dat += "[features["mam_ears"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("ears" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Ears

" dat += "[features["ears"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("mam_snouts" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Snout

" dat += "[features["mam_snouts"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("legs" in pref_species.default_features) 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("deco_wings" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Decorative wings

" dat += "[features["deco_wings"]]" dat += "   Change
" if("insect_wings" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Insect wings

" dat += "[features["insect_wings"]]" dat += "   Change
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("insect_fluff" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Insect Fluff

" dat += "[features["insect_fluff"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("taur" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Tauric Body

" dat += "[features["taur"]]" if("insect_markings" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Insect markings

" dat += "[features["insect_markings"]]
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("wings" in pref_species.mutant_bodyparts && 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("xenohead" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Caste Head

" dat += "[features["xenohead"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("xenotail" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Tail

" dat += "[features["xenotail"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("xenodorsal" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Dorsal Spines

" dat += "[features["xenodorsal"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("ipc_screen" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Screen

" dat += "[features["ipc_screen"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if("ipc_antenna" in pref_species.default_features) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Antenna

" dat += "[features["ipc_antenna"]]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(mutant_category) dat += "" mutant_category = 0 dat += "
" dat += "

Flavor Text

" dat += "Set Examine Text
" if(length(features["flavor_text"]) <= 40) if(!length(features["flavor_text"])) dat += "\[...\]" else dat += "[features["flavor_text"]]" else dat += "[TextPreview(features["flavor_text"])]...
" dat += "

Body

" dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
" dat += "Species:[pref_species.name]
" dat += "Custom Species Name:[custom_species ? custom_species : "None"]
" dat += "Random Body:Randomize!
" dat += "Always Random Body:[be_random_body ? "Yes" : "No"]
" dat += "
Cycle background:[bgstate]
" var/use_skintones = pref_species.use_skintones if(use_skintones) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Skin Tone

" dat += "[skin_tone]
" 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 += "

Body Colors

" dat += "Primary Color:
" dat += "    Change
" dat += "Secondary Color:
" dat += "    Change
" dat += "Tertiary Color:
" dat += "    Change
" mutant_colors = TRUE if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits)) if(!use_skintones && !mutant_colors) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Eye Color

" dat += "    Change
" dat += "
" dat += "" dat += "" dat +="" dat += APPEARANCE_CATEGORY_COLUMN dat += "

Breasts

" dat += "[features["has_breasts"] == TRUE ? "Yes" : "No"]" if(features["has_breasts"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "Color:
" dat += "   (Skin tone overriding)
" else dat += "Color:
" dat += "   Change
" dat += "Cup Size:[features["breasts_size"]]" dat += "Breast Shape:[features["breasts_shape"]]" dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]" dat += "" dat += "" dat += "
" dat += "

Clothing & Equipment

" dat += "Underwear:[underwear]" if(GLOB.underwear_list[underwear]?.has_color) dat += "Underwear Color:     Change
" dat += "Undershirt:[undershirt]" if(GLOB.undershirt_list[undershirt]?.has_color) dat += "Undershirt Color:     Change
" dat += "Socks:[socks]" if(GLOB.socks_list[socks]?.has_color) dat += "Socks Color:     Change
" dat += "Backpack:[backbag]" dat += "Jumpsuit:
[jumpsuit_style]
" dat += "Uplink Location:[uplink_spawn_loc]" dat += "
" if(NOGENITALS in pref_species.species_traits) dat += "Your species ([pref_species.name]) does not support genitals!
" else if(pref_species.use_skintones) dat += "Genitals use skintone:[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]" dat += "

Penis

" dat += "[features["has_cock"] == TRUE ? "Yes" : "No"]" if(features["has_cock"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "Penis Color:
" dat += "   (Skin tone overriding)
" else dat += "Penis Color:
" dat += "    Change
" dat += "Penis Shape: [features["cock_shape"]]" dat += "Penis Length: [features["cock_length"]] inch(es)" dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]" if(features["has_balls"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "Testicles Color:
" dat += "   (Skin tone overriding)
" else dat += "Testicles Color:
" dat += "    Change
" dat += "Testicles showing:[features["balls_shape"]]" dat += APPEARANCE_CATEGORY_COLUMN dat += "

Vagina

" dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]" if(features["has_vag"]) dat += "Vagina Type: [features["vag_shape"]]" if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "Vagina Color:
" dat += "   (Skin tone overriding)
" else dat += "Vagina Color:
" dat += "    Change
" dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]" dat += "
" if (1) // Game Preferences dat += "" if(user.client.holder) dat +="" dat +="" dat += "
" dat += "

General Settings

" dat += "UI Style: [UI_style]
" dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
" dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
" dat += "
" dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
" dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Default"]
" dat += "
" dat += "PDA Color:     Change
" dat += "PDA Style: [pda_style]
" dat += "PDA Reskin: [pda_skin]
" 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 += "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 += "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
" dat += "Antag OOC Color:     Change
" dat += "
" dat += "

Admin Settings

" dat += "Adminhelp Sounds: [(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]
" dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]
" dat += "
" dat += "Combo HUD Lighting: [(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]
" dat += "
" dat += "

Citadel Preferences

" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe. dat += "Widescreen: [widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]
" dat += "Auto stand: [autostand ? "Enabled" : "Disabled"]
" dat += "Auto OOC: [auto_ooc ? "Enabled" : "Disabled"]
" dat += "Screen Shake: [(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]
" if (user && user.client && !user.client.prefs.screenshake==0) dat += "Damage Screen Shake: [(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]
" var/p_chaos if (!preferred_chaos) p_chaos = "No preference" else p_chaos = preferred_chaos dat += "Preferred Chaos Amount: [p_chaos]
" dat += "
" dat += "
" 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 += "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 += "Ambient Occlusion: [ambientocclusion ? "Enabled" : "Disabled"]
" dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
" dat += "Sprint Key: [sprint_spacebar ? "Space" : "Shift"]
" dat += "Toggle Sprint: [sprint_toggle ? "Enabled" : "Disabled"]
" if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_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/allow_map_voting)) dat += "Preferred Map: [p_map]
" dat += "" dat += "

Special Role Settings

" if(jobban_isbanned(user, ROLE_SYNDICATE)) dat += "You are banned from antagonist roles." src.be_special = list() for (var/i in GLOB.special_roles) if(jobban_isbanned(user, i)) dat += "Be [capitalize(i)]: BANNED
" else var/days_remaining = null if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age var/mode_path = GLOB.special_roles[i] var/datum/game_mode/temp_mode = new mode_path days_remaining = temp_mode.get_remaining_days(user.client) if(days_remaining) dat += "Be [capitalize(i)]: \[IN [days_remaining] DAYS]
" else dat += "Be [capitalize(i)]: [(i in be_special) ? "Enabled" : "Disabled"]
" dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]
" dat += "
" if(3) if(!gear_tab) gear_tab = GLOB.loadout_items[1] dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" for(var/j in GLOB.loadout_items[gear_tab]) var/datum/gear/gear = GLOB.loadout_items[gear_tab][j] var/donoritem = gear.donoritem if(donoritem && !gear.donator_ckey_check(user.ckey)) continue var/class_link = "" if(gear.type in chosen_gear) class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=0'" else if(gear_points <= 0) class_link = "style='white-space:normal;' class='linkOff'" else if(donoritem) class_link = "style='white-space:normal;background:#ebc42e;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=1'" else class_link = "style='white-space:normal;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=1'" dat += "" dat += "" dat += "
[gear_points] loadout points remaining. \[Clear Loadout\]
You can only choose one item per category, unless it's an item that spawns in your backpack or hands.
" var/firstcat = TRUE for(var/i in GLOB.loadout_items) if(firstcat) firstcat = FALSE else dat += " |" if(i == gear_tab) dat += " [i] " else dat += " [i] " dat += "

[gear_tab]

NameCostRestrictionsDescription
[j][gear.cost]" if(islist(gear.restricted_roles)) if(gear.restricted_roles.len) if(gear.restricted_desc) dat += "" dat += gear.restricted_desc dat += "" else dat += "" dat += gear.restricted_roles.Join(";") dat += "" dat += "[gear.description]
" if(4) // Content preferences dat += "" dat +="
" dat += "

Fetish content prefs

" dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
" dat += "Voracious MediHound sleepers: [(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]
" dat += "Hear Vore Sounds: [(cit_toggles & EATING_NOISES) ? "Yes" : "No"]
" dat += "Hear Vore Digestion Sounds: [(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]
" dat += "Forced Feminization: [(cit_toggles & FORCED_FEM) ? "Allowed" : "Disallowed"]
" dat += "Forced Masculinization: [(cit_toggles & FORCED_MASC) ? "Allowed" : "Disallowed"]
" dat += "Lewd Hypno: [(cit_toggles & HYPNO) ? "Allowed" : "Disallowed"]
" dat += "Bimbofication: [(cit_toggles & BIMBOFICATION) ? "Allowed" : "Disallowed"]
" dat += "
" dat += "

Other content prefs

" dat += "Breast Enlargement: [(cit_toggles & BREAST_ENLARGEMENT) ? "Allowed" : "Disallowed"]
" dat += "Penis Enlargement: [(cit_toggles & PENIS_ENLARGEMENT) ? "Allowed" : "Disallowed"]
" dat += "Hypno: [(cit_toggles & NEVER_HYPNO) ? "Disallowed" : "Allowed"]
" dat += "Aphrodisiacs: [(cit_toggles & NO_APHRO) ? "Disallowed" : "Allowed"]
" dat += "Ass Slapping: [(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]
" dat += "
" 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/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620) if(!SSjob) return //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice. //splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE 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) || (job.title in splitJobs)) width += widthPerColumn if((index < limit) && (lastJob != null)) //If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with //the last job's selection color. Creating a rather nice effect. 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(!user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features)) if(user.client.prefs.pref_species.id == "human") HTML += "[rank]" else HTML += "[rank]" continue if((job_preferences["[SSjob.overflow_role]"] == JP_LOW) && (rank != SSjob.overflow_role) && !jobban_isbanned(user, 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(jobban_isbanned(user, rank)) HTML += "[rank] BANNED
\[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \]
\[IN [(available_in_days)] DAYS\]
\[MUTANT\]
\[NON-HUMAN\]
" 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, "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, "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/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["jobbancheck"]) var/job = sanitizeSQL(href_list["jobbancheck"]) var/sql_ckey = sanitizeSQL(user.ckey) var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey) FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'") if(!query_get_jobban.warn_execute()) qdel(query_get_jobban) return if(query_get_jobban.NextRow()) var/reason = query_get_jobban.item[1] var/bantime = query_get_jobban.item[2] var/duration = query_get_jobban.item[3] var/expiration_time = query_get_jobban.item[4] var/admin_key = query_get_jobban.item[5] var/text text = "You, or another user of this computer, ([user.key]) is banned from playing [job]. The ban reason is:
[reason]
This ban was applied by [admin_key] on [bantime]" if(text2num(duration) > 0) text += ". The ban is for [duration] minutes and expires on [expiration_time] (server time)" text += ".
" to_chat(user, text) qdel(query_get_jobban) 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(jobban_isbanned(user, 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 for(var/Q in all_quirks) if((quirk in L) && (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, "[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, "Refunding this would cause you to go below your balance!") return all_quirks -= quirk else if(GetPositiveQuirkCount() >= MAX_QUIRKS) to_chat(user, "You can't have more than [MAX_QUIRKS] positive quirks!") return if(balance - value < 0) to_chat(user, "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("hair_style") hair_style = random_hair_style(gender) if("facial") facial_hair_color = random_short_color() if("facial_hair_style") facial_hair_style = random_facial_hair_style(gender) if("underwear") underwear = random_underwear(gender) undie_color = random_short_color() if("undershirt") undershirt = random_undershirt(gender) shirt_color = random_short_color() if("socks") socks = random_socks() socks_color = random_short_color() if(BODY_ZONE_PRECISE_EYES) eye_color = random_eye_color() if("s_tone") skin_tone = random_skin_tone() if("bag") backbag = pick(GLOB.backbaglist) if("suit") jumpsuit_style = pick(GLOB.jumpsuitlist) if("all") random_character() 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 = alert("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?",,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 = alert("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?",,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 .") 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("flavor_text") var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"], MAX_FLAVOR_LEN, TRUE) if(msg) features["flavor_text"] = msg 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("hair_style") var/new_hair_style new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_list if(new_hair_style) hair_style = new_hair_style if("next_hair_style") hair_style = next_list_item(hair_style, GLOB.hair_styles_list) if("previous_hair_style") hair_style = previous_list_item(hair_style, GLOB.hair_styles_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_hair_style") var/new_facial_hair_style new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_list if(new_facial_hair_style) facial_hair_style = new_facial_hair_style if("next_facehair_style") facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_list) if("previous_facehair_style") facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_list) if("cycle_bg") bgstate = next_list_item(bgstate, bgstate_options) 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("undie_color") var/n_undie_color = input(user, "Choose your underwear's color.", "Character Preference", undie_color) as color|null if(n_undie_color) undie_color = sanitize_hexcolor(n_undie_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("shirt_color") var/n_shirt_color = input(user, "Choose your undershirt's color.", "Character Preference", shirt_color) as color|null if(n_shirt_color) shirt_color = sanitize_hexcolor(n_shirt_color) if("socks") var/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("socks_color") var/n_socks_color = input(user, "Choose your socks' color.", "Character Preference", socks_color) as color|null if(n_socks_color) socks_color = sanitize_hexcolor(n_socks_color) 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_race_names if(result) var/newtype = GLOB.species_list[GLOB.roundstart_race_names[result]] pref_species = new newtype() //let's ensure that no weird shit happens on species swapping. custom_species = null if(!("body_markings" in pref_species.default_features)) features["body_markings"] = "None" if(!("mam_body_markings" in pref_species.default_features)) features["mam_body_markings"] = "None" if("mam_body_markings" in pref_species.default_features) if(features["mam_body_markings"] == "None") features["mam_body_markings"] = "Plain" if("tail_lizard" in pref_species.default_features) features["tail_lizard"] = "Smooth" if(pref_species.id == "felinid") features["mam_tail"] = "Cat" features["mam_ears"] = "Cat" //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("#202020")[3])) features["mcolor"] = pref_species.default_color if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) features["mcolor2"] = pref_species.default_color if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) features["mcolor3"] = pref_species.default_color if("custom_species") var/new_species = reject_bad_name(input(user, "Choose your species subtype, if unique. This will show up on examinations and health scans. Do not abuse this:", "Character Preference", custom_species) as null|text) if(new_species) custom_species = new_species else custom_species = null 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("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin features["mcolor"] = sanitize_hexcolor(new_mutantcolor) else to_chat(user, "Invalid color. Your color is not bright enough.") if("mutant_color2") var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference") as color|null if(new_mutantcolor) var/temp_hsv = RGBtoHSV(new_mutantcolor) if(new_mutantcolor == "#000000") features["mcolor2"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin features["mcolor2"] = sanitize_hexcolor(new_mutantcolor) else to_chat(user, "Invalid color. Your color is not bright enough.") if("mutant_color3") var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference") as color|null if(new_mutantcolor) var/temp_hsv = RGBtoHSV(new_mutantcolor) if(new_mutantcolor == "#000000") features["mcolor3"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin features["mcolor3"] = sanitize_hexcolor(new_mutantcolor) else to_chat(user, "Invalid color. Your color is not bright enough.") if("ipc_screen") var/new_ipc_screen new_ipc_screen = input(user, "Choose your character's screen:", "Character Preference") as null|anything in GLOB.ipc_screens_list if(new_ipc_screen) features["ipc_screen"] = new_ipc_screen if("ipc_antenna") var/new_ipc_antenna new_ipc_antenna = input(user, "Choose your character's antenna:", "Character Preference") as null|anything in GLOB.ipc_antennas_list if(new_ipc_antenna) features["ipc_antenna"] = new_ipc_antenna 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(new_tail != "None") features["taur"] = "None" features["tail_human"] = "None" features["mam_tail"] = "None" if("tail_human") var/list/snowflake_tails_list = list() for(var/path in GLOB.tails_list_human) var/datum/sprite_accessory/tails/human/instance = GLOB.tails_list_human[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_tails_list[S.name] = path var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list if(new_tail) features["tail_human"] = new_tail if(new_tail != "None") features["taur"] = "None" features["tail_lizard"] = "None" features["mam_tail"] = "None" if("mam_tail") var/list/snowflake_tails_list = list() for(var/path in GLOB.mam_tails_list) var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_tails_list[S.name] = path var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list if(new_tail) features["mam_tail"] = new_tail if(new_tail != "None") features["taur"] = "None" features["tail_human"] = "None" features["tail_lizard"] = "None" if("meats") var/new_meat new_meat = input(user, "Choose your character's meat type:", "Character Preference") as null|anything in GLOB.meat_types if(new_meat) features["meat_type"] = new_meat if("snout") var/list/snowflake_snouts_list = list() for(var/path in GLOB.snouts_list) var/datum/sprite_accessory/mam_snouts/instance = GLOB.snouts_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_snouts_list[S.name] = path var/new_snout new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in snowflake_snouts_list if(new_snout) features["snout"] = new_snout features["mam_snouts"] = "None" if("mam_snouts") var/list/snowflake_mam_snouts_list = list() for(var/path in GLOB.mam_snouts_list) var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_mam_snouts_list[S.name] = path var/new_mam_snouts new_mam_snouts = input(user, "Choose your character's snout:", "Character Preference") as null|anything in snowflake_mam_snouts_list if(new_mam_snouts) features["mam_snouts"] = new_mam_snouts features["snout"] = "None" 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("horns_color") var/new_horn_color = input(user, "Choose your character's horn colour:", "Character Preference","#"+horn_color) as color|null if(new_horn_color) if (new_horn_color == "#000000") horn_color = "#85615A" else horn_color = sanitize_hexcolor(new_horn_color) 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("wings_color") var/new_wing_color = input(user, "Choose your character's wing colour:", "Character Preference","#"+wing_color) as color|null if(new_wing_color) if (new_wing_color == "#000000") wing_color = "#FFFFFF" else wing_color = sanitize_hexcolor(new_wing_color) 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(new_body_markings != "None") features["mam_body_markings"] = "None" 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("insect_wings") var/new_insect_wings new_insect_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_wings_list if(new_insect_wings) features["insect_wings"] = new_insect_wings if("deco_wings") var/new_deco_wings new_deco_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.deco_wings_list if(new_deco_wings) features["deco_wings"] = new_deco_wings if("insect_fluffs") var/new_insect_fluff new_insect_fluff = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_fluffs_list if(new_insect_fluff) features["insect_fluff"] = new_insect_fluff if("insect_markings") var/new_insect_markings new_insect_markings = input(user, "Choose your character's markings:", "Character Preference") as null|anything in GLOB.insect_markings_list if(new_insect_markings) features["insect_markings"] = new_insect_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("taur") var/list/snowflake_taur_list = list() for(var/path in GLOB.taur_list) var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_taur_list[S.name] = path var/new_taur new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in snowflake_taur_list if(new_taur) features["taur"] = new_taur if(new_taur != "None") features["mam_tail"] = "None" features["xenotail"] = "None" features["tail_human"] = "None" features["tail_lizard"] = "None" if("ears") var/list/snowflake_ears_list = list() for(var/path in GLOB.ears_list) var/datum/sprite_accessory/ears/instance = GLOB.ears_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_ears_list[S.name] = path var/new_ears new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list if(new_ears) features["ears"] = new_ears if("mam_ears") var/list/snowflake_ears_list = list() for(var/path in GLOB.mam_ears_list) var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_ears_list[S.name] = path var/new_ears new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list if(new_ears) features["mam_ears"] = new_ears if("mam_body_markings") var/list/snowflake_markings_list = list() for(var/path in GLOB.mam_body_markings_list) var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[path] if(istype(instance, /datum/sprite_accessory)) var/datum/sprite_accessory/S = instance if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey))) snowflake_markings_list[S.name] = path var/new_mam_body_markings new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in snowflake_markings_list if(new_mam_body_markings) features["mam_body_markings"] = new_mam_body_markings if(new_mam_body_markings != "None") features["body_markings"] = "None" else if(new_mam_body_markings == "None") features["mam_body_markings"] = "Plain" features["body_markings"] = "None" //Xeno Bodyparts if("xenohead")//Head or caste type var/new_head new_head = input(user, "Choose your character's caste:", "Character Preference") as null|anything in GLOB.xeno_head_list if(new_head) features["xenohead"] = new_head if("xenotail")//Currently one one type, more maybe later if someone sprites them. Might include animated variants in the future. var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.xeno_tail_list if(new_tail) features["xenotail"] = new_tail if(new_tail != "None") features["mam_tail"] = "None" features["taur"] = "None" features["tail_human"] = "None" features["tail_lizard"] = "None" if("xenodorsal") var/new_dors new_dors = input(user, "Choose your character's dorsal tube type:", "Character Preference") as null|anything in GLOB.xeno_dorsal_list if(new_dors) features["xenodorsal"] = new_dors //Genital code if("cock_color") var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null if(new_cockcolor) var/temp_hsv = RGBtoHSV(new_cockcolor) if(new_cockcolor == "#000000") features["cock_color"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["cock_color"] = sanitize_hexcolor(new_cockcolor) else to_chat(user,"Invalid color. Your color is not bright enough.") if("cock_length") var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null if(new_length) features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) if("cock_shape") var/new_shape new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list if(new_shape) features["cock_shape"] = new_shape if("balls_color") var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null if(new_ballscolor) var/temp_hsv = RGBtoHSV(new_ballscolor) if(new_ballscolor == "#000000") features["balls_color"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["balls_color"] = sanitize_hexcolor(new_ballscolor) else to_chat(user,"Invalid color. Your color is not bright enough.") if("balls_shape") var/new_shape new_shape = input(user, "Testicle Type:", "Character Preference") as null|anything in GLOB.balls_shapes_list if(new_shape) features["balls_shape"] = new_shape if("egg_size") var/new_size var/list/egg_sizes = list(1,2,3) new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes if(new_size) features["eggsack_egg_size"] = new_size if("egg_color") var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null if(new_egg_color) var/temp_hsv = RGBtoHSV(new_egg_color) if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color) else to_chat(user,"Invalid color. Your color is not bright enough.") if("breasts_size") var/new_size new_size = input(user, "Breast Size", "Character Preference") as null|anything in GLOB.breasts_size_list if(new_size) features["breasts_size"] = new_size if("breasts_shape") var/new_shape new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list if(new_shape) features["breasts_shape"] = new_shape if("breasts_color") var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null if(new_breasts_color) var/temp_hsv = RGBtoHSV(new_breasts_color) if(new_breasts_color == "#000000") features["breasts_color"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["breasts_color"] = sanitize_hexcolor(new_breasts_color) else to_chat(user,"Invalid color. Your color is not bright enough.") if("vag_shape") var/new_shape new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list if(new_shape) features["vag_shape"] = new_shape if("vag_color") var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null if(new_vagcolor) var/temp_hsv = RGBtoHSV(new_vagcolor) if(new_vagcolor == "#000000") features["vag_color"] = pref_species.default_color else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) features["vag_color"] = sanitize_hexcolor(new_vagcolor) else to_chat(user,"Invalid color. Your color is not bright enough.") if("ooccolor") var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null if(new_ooccolor) ooccolor = new_ooccolor if("aooccolor") var/new_aooccolor = input(user, "Choose your Antag OOC colour:", "Game Preference",ooccolor) as color|null if(new_aooccolor) aooccolor = new_aooccolor if("bag") var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist if(new_backbag) backbag = new_backbag 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) uplink_spawn_loc = new_loc 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 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] 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 maplist if (pickedmap) preferred_map = maplist[pickedmap] if ("preferred_chaos") var/pickedchaos = input(user, "Choose your preferred level of chaos. This will help with dynamic threat level ratings.", "Character Preference") as null|anything in list(CHAOS_NONE,CHAOS_LOW,CHAOS_MED,CHAOS_HIGH,CHAOS_MAX) preferred_chaos = pickedchaos if ("clientfps") var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num if (!isnull(desiredfps)) clientfps = desiredfps parent.fps = desiredfps if("ui") var/pickedui = input(user, "Choose your UI style.", "Character Preference", UI_style) as null|anything in 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("pda_skin") var/pickedPDASkin = input(user, "Choose your PDA reskin.", "Character Preference", pda_skin) as null|anything in GLOB.pda_reskins if(pickedPDASkin) pda_skin = pickedPDASkin else switch(href_list["preference"]) //CITADEL PREFERENCES EDIT - I can't figure out how to modularize these, so they have to go here. :c -Pooj if("genital_colour") features["genitals_use_skintone"] = !features["genitals_use_skintone"] if("arousable") arousable = !arousable if("has_cock") features["has_cock"] = !features["has_cock"] if(features["has_cock"] == FALSE) features["has_balls"] = FALSE if("has_balls") features["has_balls"] = !features["has_balls"] if("has_ovi") features["has_ovi"] = !features["has_ovi"] if("has_eggsack") features["has_eggsack"] = !features["has_eggsack"] if("balls_internal") features["balls_internal"] = !features["balls_internal"] if("eggsack_internal") features["eggsack_internal"] = !features["eggsack_internal"] if("has_breasts") features["has_breasts"] = !features["has_breasts"] if(features["has_breasts"] == FALSE) features["breasts_producing"] = FALSE if("breasts_producing") features["breasts_producing"] = !features["breasts_producing"] if("has_vag") features["has_vag"] = !features["has_vag"] if(features["has_vag"] == FALSE) features["has_womb"] = FALSE if("has_womb") features["has_womb"] = !features["has_womb"] if("widescreenpref") widescreenpref = !widescreenpref user.client.change_view(CONFIG_GET(string/default_view)) if("autostand") autostand = !autostand if("auto_ooc") auto_ooc = !auto_ooc if ("screenshake") var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num if (!isnull(desiredshake)) screenshake = desiredshake if("damagescreenshake") switch(damagescreenshake) if(0) damagescreenshake = 1 if(1) damagescreenshake = 2 if(2) damagescreenshake = 0 else damagescreenshake = 1 if("nameless") nameless = !nameless //END CITADEL EDIT if("publicity") if(unlock_content) toggles ^= MEMBER_PUBLIC if("gender") var/chosengender = input(user, "Select your character's gender.", "Gender Selection", gender) in list(MALE,FEMALE,"nonbinary","object") switch(chosengender) if("nonbinary") chosengender = PLURAL if("object") chosengender = NEUTER gender = chosengender facial_hair_style = random_facial_hair_style(gender) hair_style = random_hair_style(gender) if("hotkeys") hotkeys = !hotkeys if(hotkeys) winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=default") else winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default") 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 if("hear_adminhelps") toggles ^= SOUND_ADMINHELP if("announce_login") toggles ^= ANNOUNCE_LOGIN if("combohud_lighting") toggles ^= COMBOHUD_LIGHTING 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("name") be_random_name = !be_random_name if("all") be_random_body = !be_random_body 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("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("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) // Citadel edit - Prefs don't work outside of this. :c if("hound_sleeper") cit_toggles ^= MEDIHOUND_SLEEPER if("toggleeatingnoise") cit_toggles ^= EATING_NOISES if("toggledigestionnoise") cit_toggles ^= DIGESTION_NOISES if("breast_enlargement") cit_toggles ^= BREAST_ENLARGEMENT if("penis_enlargement") cit_toggles ^= PENIS_ENLARGEMENT if("feminization") cit_toggles ^= FORCED_FEM if("masculinization") cit_toggles ^= FORCED_MASC if("hypno") cit_toggles ^= HYPNO if("never_hypno") cit_toggles ^= NEVER_HYPNO if("aphro") cit_toggles ^= NO_APHRO if("ass_slap") cit_toggles ^= NO_ASS_SLAP if("bimbo") cit_toggles ^= BIMBOFICATION //END CITADEL EDIT if("ambientocclusion") ambientocclusion = !ambientocclusion if(parent && parent.screen && parent.screen.len) var/obj/screen/plane_master/game_world/PM = locate(/obj/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("sprint_key") sprint_spacebar = !sprint_spacebar if("sprint_toggle") sprint_toggle = !sprint_toggle 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(href_list["preference"] == "gear") if(href_list["clear_loadout"]) LAZYCLEARLIST(chosen_gear) gear_points = initial(gear_points) save_preferences() if(href_list["select_category"]) for(var/i in GLOB.loadout_items) if(i == href_list["select_category"]) gear_tab = i if(href_list["toggle_gear_path"]) var/datum/gear/G = GLOB.loadout_items[gear_tab][html_decode(href_list["toggle_gear_path"])] if(!G) return var/toggle = text2num(href_list["toggle_gear"]) if(!toggle && (G.type in chosen_gear))//toggling off and the item effectively is in chosen gear) LAZYREMOVE(chosen_gear, G.type) gear_points += initial(G.cost) else if(toggle && (!(is_type_in_ref_list(G, chosen_gear)))) if(!is_loadout_slot_available(G.category)) to_chat(user, "You cannot take this loadout, as you've already chosen too many of the same category!") return if(G.donoritem && !G.donator_ckey_check(user.ckey)) to_chat(user, "This is an item intended for donator use only. You are not authorized to use this item.") return if(gear_points >= initial(G.cost)) LAZYADD(chosen_gear, G.type) gear_points -= initial(G.cost) ShowChoices(user) return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE) if(be_random_name) real_name = pref_species.random_name(gender) if(be_random_body) random_character(gender) if(roundstart_checks) if(CONFIG_GET(flag/humans_need_surnames) && (pref_species.id == "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 = nameless ? "[real_name] #[rand(10000, 99999)]" : real_name character.name = character.real_name character.nameless = nameless character.custom_species = custom_species character.gender = gender character.age = age 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.horn_color = horn_color character.wing_color = wing_color character.skin_tone = skin_tone character.hair_style = hair_style character.facial_hair_style = facial_hair_style character.underwear = underwear character.saved_underwear = underwear character.undershirt = undershirt character.saved_undershirt = undershirt character.socks = socks character.saved_socks = socks character.undie_color = undie_color character.shirt_color = shirt_color character.socks_color = socks_color var/datum/species/chosen_species if(!roundstart_checks || (pref_species.id in GLOB.roundstart_races)) chosen_species = pref_species.type else 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 character.dna.nameless = character.nameless character.dna.custom_species = character.custom_species if("tail_lizard" in pref_species.default_features) character.dna.species.mutant_bodyparts |= "tail_lizard" if("mam_tail" in pref_species.default_features) character.dna.species.mutant_bodyparts |= "mam_tail" if("xenotail" in pref_species.default_features) character.dna.species.mutant_bodyparts |= "xenotail" if("meat_type" in pref_species.default_features) character.type_of_meat = GLOB.meat_types[features["meat_type"]] if(("legs" in character.dna.species.mutant_bodyparts) && (character.dna.features["legs"] == "Digitigrade" || character.dna.features["legs"] == "Avian")) pref_species.species_traits |= DIGITIGRADE else pref_species.species_traits -= DIGITIGRADE if(DIGITIGRADE in pref_species.species_traits) character.Digitigrade_Leg_Swap(FALSE) else character.Digitigrade_Leg_Swap(TRUE) //let's be sure the character updates if(icon_updates) character.update_body() character.update_hair() /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) 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 .") return else custom_names[name_id] = sanitized_name /datum/preferences/proc/get_filtered_holoform(filter_type) if(!custom_holoform_icon) return LAZYINITLIST(cached_holoform_icons) if(!cached_holoform_icons[filter_type]) cached_holoform_icons[filter_type] = process_holoform_icon_filter(custom_holoform_icon, filter_type) return cached_holoform_icons[filter_type]