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 = null 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 = "Midnight" 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/pda_style = MONO var/pda_color = "#808000" var/uses_glasses_colour = 0 //character preferences var/real_name //our character's name 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/undershirt = "Nude" //undershirt type var/socks = "Nude" //socks type var/backbag = DBACKPACK //backpack type 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/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", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs", "moth_wings" = "Plain") var/list/custom_names = list("human", "clown", "mime", "ai", "cyborg", "religion", "deity") var/prefered_security_department = SEC_DEPT_RANDOM //Mob preview var/icon/preview_icon = null //Jobs, uses bitflags var/job_civilian_high = 0 var/job_civilian_med = 0 var/job_civilian_low = 0 var/job_medsci_high = 0 var/job_medsci_med = 0 var/job_medsci_low = 0 var/job_engsec_high = 0 var/job_engsec_med = 0 var/job_engsec_low = 0 // 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 // OOC Metadata: var/metadata = "" var/unlock_content = 0 var/list/ignoring = list() var/clientfps = 0 var/parallax var/uplink_spawn_loc = UPLINK_PDA var/list/exp var/list/menuoptions var/action_buttons_screen_locs = list() /datum/preferences/New(client/C) parent = C custom_names["human"] = random_unique_name() custom_names["ai"] = pick(GLOB.ai_names) custom_names["cyborg"] = pick(GLOB.ai_names) custom_names["clown"] = pick(GLOB.clown_names) custom_names["mime"] = pick(GLOB.mime_names) 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. 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 /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return update_preview_icon() user << browse_rsc(preview_icon, "previewicon.png") var/dat = "
" dat += "Character Settings " dat += "Game 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 for(var/i=1, i<=max_save_slots, i++) S.cd = "/character[i]" S["real_name"] >> name if(!name) name = "Character[i]" dat += "[name] " dat += "
" dat += "

Occupation Choices

" dat += "Set Occupation Preferences
" 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 += "Name: " dat += "[real_name]
" dat += "Gender: [gender == MALE ? "Male" : "Female"]
" dat += "Age: [age]
" dat += "Special Names:
" dat += "Backup Human Name: [custom_names["human"]] " dat += "Clown: [custom_names["clown"]] " dat += "Mime:[custom_names["mime"]]
" dat += "AI: [custom_names["ai"]] " dat += "Cyborg: [custom_names["cyborg"]]
" dat += "Chaplain religion: [custom_names["religion"]] " dat += "Chaplain deity: [custom_names["deity"]]
" dat += "Custom job preferences:
" dat += "Prefered security department: [prefered_security_department]
" dat += "
" dat += "
" dat += "

Body

" dat += "Random Body " dat += "Always Random Body: [be_random_body ? "Yes" : "No"]
" dat += "" if(pref_species.use_skintones) dat += "" if(HAIR in pref_species.species_traits) dat += "" if((EYECOLOR in pref_species.species_traits) && !(NOEYES in pref_species.species_traits)) dat += "" if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) dat += "" if("tail_lizard" in pref_species.mutant_bodyparts) dat += "" if("snout" in pref_species.mutant_bodyparts) dat += "" if("horns" in pref_species.mutant_bodyparts) dat += "" if("frills" in pref_species.mutant_bodyparts) dat += "" if("spines" in pref_species.mutant_bodyparts) dat += "" if("body_markings" in pref_species.mutant_bodyparts) dat += "" if("legs" in pref_species.mutant_bodyparts) dat += "" if("moth_wings" in pref_species.mutant_bodyparts) dat += "" if(CONFIG_GET(flag/join_with_mutant_humans)) if("tail_human" in pref_species.mutant_bodyparts) dat += "" if("ears" in pref_species.mutant_bodyparts) dat += "" if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1) dat += "" dat += "
" dat += "Species:
[pref_species.name]
" dat += "Underwear:
[underwear]
" dat += "Undershirt:
[undershirt]
" dat += "Socks:
[socks]
" dat += "Backpack:
[backbag]
" dat += "Uplink Spawn Location:
[uplink_spawn_loc]
" dat += "

Skin Tone

" dat += "[skin_tone]
" dat += "
" dat += "

Hair Style

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

Facial Hair Style

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

Eye Color

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

Mutant Color

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

Tail

" dat += "[features["tail_lizard"]]
" dat += "
" dat += "

Snout

" dat += "[features["snout"]]
" dat += "
" dat += "

Horns

" dat += "[features["horns"]]
" dat += "
" dat += "

Frills

" dat += "[features["frills"]]
" dat += "
" dat += "

Spines

" dat += "[features["spines"]]
" dat += "
" dat += "

Body Markings

" dat += "[features["body_markings"]]
" dat += "
" dat += "

Legs

" dat += "[features["legs"]]
" dat += "
" dat += "

Moth wings

" dat += "[features["moth_wings"]]
" dat += "
" dat += "

Tail

" dat += "[features["tail_human"]]
" dat += "
" dat += "

Ears

" dat += "[features["ears"]]
" dat += "
" dat += "

Wings

" dat += "[features["wings"]]
" dat += "
" if (1) // Game Preferences dat += "
" dat += "

General Settings

" dat += "UI Style: [UI_style]
" dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Default"]
" dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
" dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
" dat += "PDA Style: [pda_style]
" dat += "PDA Color:     Change
" dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
" dat += "Window Flashing: [(windowflashing) ? "Yes" : "No"]
" dat += "Play admin midis: [(toggles & SOUND_MIDI) ? "Yes" : "No"]
" dat += "Play lobby music: [(toggles & SOUND_LOBBY) ? "Yes" : "No"]
" dat += "Ghost ears: [(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost sight: [(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
" dat += "Ghost whispers: [(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost radio: [(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]
" dat += "Ghost pda: [(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]
" dat += "Pull requests: [(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]
" dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]
" if(CONFIG_GET(flag/allow_metadata)) dat += "OOC Notes: Edit
" if(user.client) if(user.client.holder) dat += "Adminhelp Sound: [(toggles & SOUND_ADMINHELP)?"On":"Off"]
" dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"On":"Off"]
" if(unlock_content || check_rights_for(user.client, R_ADMIN)) dat += "OOC:     Change
" if(unlock_content) dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
" 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]
" 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/allow_map_voting)) dat += "Preferred Map: [p_map]
" 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 += "
" 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) ? "Yes" : "No"]
" dat += "
" dat += "
" if(!IsGuestKey(user.key)) dat += "Undo " dat += "Save Setup " dat += "Reset Setup" dat += "
" var/datum/browser/popup = new(user, "preferences", "
Character Setup
", 640, 770) popup.set_content(dat) popup.open(0) /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 SSjob.occupations) 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((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant")) 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\]
" var/prefLevelLabel = "ERROR" var/prefLevelColor = "pink" var/prefUpperLevel = -1 // level to assign on left click var/prefLowerLevel = -1 // level to assign on right click if(GetJobDepartment(job, 1) & job.flag) prefLevelLabel = "High" prefLevelColor = "slateblue" prefUpperLevel = 4 prefLowerLevel = 2 else if(GetJobDepartment(job, 2) & job.flag) prefLevelLabel = "Medium" prefLevelColor = "green" prefUpperLevel = 1 prefLowerLevel = 3 else if(GetJobDepartment(job, 3) & job.flag) prefLevelLabel = "Low" prefLevelColor = "orange" prefUpperLevel = 2 prefLowerLevel = 4 else prefLevelLabel = "NEVER" prefLevelColor = "red" prefUpperLevel = 3 prefLowerLevel = 1 HTML += "" if(rank == "Assistant")//Assistant is special if(job_civilian_low & ASSISTANT) HTML += "Yes" else HTML += "No" HTML += "
  
" HTML += "
" var/message = "Be an Assistant 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
" user << browse(null, "window=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(0) return /datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level) if (!job) return 0 if (level == 1) // to high // remove any other job(s) set to high job_civilian_med |= job_civilian_high job_engsec_med |= job_engsec_high job_medsci_med |= job_medsci_high job_civilian_high = 0 job_engsec_high = 0 job_medsci_high = 0 if (job.department_flag == CIVILIAN) job_civilian_low &= ~job.flag job_civilian_med &= ~job.flag job_civilian_high &= ~job.flag switch(level) if (1) job_civilian_high |= job.flag if (2) job_civilian_med |= job.flag if (3) job_civilian_low |= job.flag return 1 else if (job.department_flag == ENGSEC) job_engsec_low &= ~job.flag job_engsec_med &= ~job.flag job_engsec_high &= ~job.flag switch(level) if (1) job_engsec_high |= job.flag if (2) job_engsec_med |= job.flag if (3) job_engsec_low |= job.flag return 1 else if (job.department_flag == MEDSCI) job_medsci_low &= ~job.flag job_medsci_med &= ~job.flag job_medsci_high &= ~job.flag switch(level) if (1) job_medsci_high |= job.flag if (2) job_medsci_med |= job.flag if (3) job_medsci_low |= job.flag return 1 return 0 /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 if(role == "Assistant") if(job_civilian_low & job.flag) job_civilian_low &= ~job.flag else job_civilian_low |= job.flag SetChoices(user) return 1 SetJobPreferenceLevel(job, desiredLvl) SetChoices(user) return 1 /datum/preferences/proc/ResetJobs() job_civilian_high = 0 job_civilian_med = 0 job_civilian_low = 0 job_medsci_high = 0 job_medsci_med = 0 job_medsci_low = 0 job_engsec_high = 0 job_engsec_med = 0 job_engsec_low = 0 /datum/preferences/proc/GetJobDepartment(datum/job/job, level) if(!job || !level) return 0 switch(job.department_flag) if(CIVILIAN) switch(level) if(1) return job_civilian_high if(2) return job_civilian_med if(3) return job_civilian_low if(MEDSCI) switch(level) if(1) return job_medsci_high if(2) return job_medsci_med if(3) return job_medsci_low if(ENGSEC) switch(level) if(1) return job_engsec_high if(2) return job_engsec_med if(3) return job_engsec_low return 0 /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, 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()) 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/a_ckey = query_get_jobban.item[5] var/text text = "You, or another user of this computer, ([user.ckey]) is banned from playing [job]. The ban reason is:
[reason]
This ban was applied by [a_ckey] 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) 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, "Assistant")) joblessrole = BERANDOMJOB else joblessrole = BEASSISTANT if(BEASSISTANT) joblessrole = BERANDOMJOB if(BERANDOMJOB) joblessrole = RETURNTOLOBBY SetChoices(user) if("setJobLevel") UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) else SetChoices(user) return 1 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) if("undershirt") undershirt = random_undershirt(gender) if("socks") socks = random_socks() if("eyes") eye_color = random_eye_color() if("s_tone") skin_tone = random_skin_tone() if("bag") backbag = pick(GLOB.backbaglist) if("all") random_character() if("input") 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 = reject_bad_name( input(user, "Choose your character's name:", "Character Preference") as text|null ) 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("metadata") var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null if(new_metadata) metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) 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 if(gender == MALE) new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_male_list else new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_female_list if(new_hair_style) hair_style = new_hair_style if("next_hair_style") if (gender == MALE) hair_style = next_list_item(hair_style, GLOB.hair_styles_male_list) else hair_style = next_list_item(hair_style, GLOB.hair_styles_female_list) if("previous_hair_style") if (gender == MALE) hair_style = previous_list_item(hair_style, GLOB.hair_styles_male_list) else hair_style = previous_list_item(hair_style, GLOB.hair_styles_female_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 if(gender == MALE) new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_male_list else new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_female_list if(new_facial_hair_style) facial_hair_style = new_facial_hair_style if("next_facehair_style") if (gender == MALE) facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list) else facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list) if("previous_facehair_style") if (gender == MALE) facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list) else facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list) if("underwear") var/new_underwear if(gender == MALE) new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m else new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f if(new_underwear) underwear = new_underwear if("undershirt") var/new_undershirt if(gender == MALE) new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m else new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f 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("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, "Invalid color. Your color is not bright enough.") 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("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 = new_ooccolor 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("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("human_name") var/new_human_name = reject_bad_name( input(user, "Choose your character's backup human name, used in the event you are assigned a command role as another species:", "Character Preference") as text|null ) if(new_human_name) custom_names["human"] = new_human_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("clown_name") var/new_clown_name = reject_bad_name( input(user, "Choose your character's clown name:", "Character Preference") as text|null ) if(new_clown_name) custom_names["clown"] = new_clown_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("mime_name") var/new_mime_name = reject_bad_name( input(user, "Choose your character's mime name:", "Character Preference") as text|null ) if(new_mime_name) custom_names["mime"] = new_mime_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("ai_name") var/new_ai_name = reject_bad_name( input(user, "Choose your character's AI name:", "Character Preference") as text|null, 1 ) if(new_ai_name) custom_names["ai"] = new_ai_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, 0-9, -, ' and .") if("cyborg_name") var/new_cyborg_name = reject_bad_name( input(user, "Choose your character's cyborg name:", "Character Preference") as text|null, 1 ) if(new_cyborg_name) custom_names["cyborg"] = new_cyborg_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, 0-9, -, ' and .") if("religion_name") var/new_religion_name = reject_bad_name( input(user, "Choose your character's religion:", "Character Preference") as text|null ) if(new_religion_name) custom_names["religion"] = new_religion_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("deity_name") var/new_deity_name = reject_bad_name( input(user, "Choose your character's deity:", "Character Preference") as text|null ) if(new_deity_name) custom_names["deity"] = new_deity_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("sec_dept") var/department = input(user, "Choose your prefered 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 ("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") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork") if(pickedui) UI_style = pickedui if("pda_style") var/pickedPDAStyle = input(user, "Choose your PDA style.", "Character Preference") as null|anything in list(MONO, SHARE, ORBITRON, VT) 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 else switch(href_list["preference"]) if("publicity") if(unlock_content) toggles ^= MEMBER_PUBLIC if("gender") if(gender == MALE) gender = FEMALE else gender = MALE underwear = random_underwear(gender) undershirt = random_undershirt(gender) socks = random_socks() 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("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) 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) 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"]) ShowChoices(user) return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1) if(be_random_name) real_name = pref_species.random_name(gender) if(be_random_body) random_character(gender) if(CONFIG_GET(flag/humans_need_surnames)) 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 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.hair_style = hair_style character.facial_hair_style = facial_hair_style character.underwear = underwear character.undershirt = undershirt character.socks = socks character.backbag = backbag character.dna.features = features.Copy() character.dna.real_name = character.real_name var/datum/species/chosen_species if(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.set_species(chosen_species, icon_update=0) if(icon_updates) character.update_body() character.update_hair() character.update_body_parts()