#define SAVE_RESET -1 var/list/preferences_datums = list() datum/preferences //doohickeys for savefiles var/path var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used var/savefile_version = 0 //non-preference stuff var/warns = 0 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 = "#010000" //Whatever this is set to acts as 'reset' color and is thus unusable as an actual custom color var/be_special = 0 //Special role selection var/UI_style = "Midnight" var/UI_style_color = "#ffffff" var/UI_style_alpha = 255 var/tooltipstyle = "Midnight" //Style for popup tooltips var/client_fps = 0 //character preferences var/real_name //our character's name var/be_random_name = 0 //whether we are a random name every round var/nickname //our character's nickname var/age = 30 //age of character var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2). var/b_type = "A+" //blood type (not-chooseable) var/backbag = 2 //backpack type var/pdachoice = 1 //PDA type var/h_style = "Bald" //Hair type var/r_hair = 0 //Hair color var/g_hair = 0 //Hair color var/b_hair = 0 //Hair color var/grad_style = "none" //Gradient style var/r_grad = 0 //Gradient color var/g_grad = 0 //Gradient color var/b_grad = 0 //Gradient color var/f_style = "Shaved" //Face hair type var/r_facial = 0 //Face hair color var/g_facial = 0 //Face hair color var/b_facial = 0 //Face hair color var/s_tone = 0 //Skin tone var/r_skin = 238 //Skin color // Vorestation edit, so color multi sprites can aren't BLACK AS THE VOID by default. var/g_skin = 206 //Skin color // Vorestation edit, so color multi sprites can aren't BLACK AS THE VOID by default. var/b_skin = 179 //Skin color // Vorestation edit, so color multi sprites can aren't BLACK AS THE VOID by default. var/r_eyes = 0 //Eye color var/g_eyes = 0 //Eye color var/b_eyes = 0 //Eye color var/species = SPECIES_HUMAN //Species datum to use. var/species_preview //Used for the species selection window. var/list/alternate_languages = list() //Secondary language(s) var/list/language_prefixes = list() //Kanguage prefix keys var/list/gear //Left in for Legacy reasons, will no longer save. var/list/gear_list = list() //Custom/fluff item loadouts. var/gear_slot = 1 //The current gear save slot var/list/traits //Traits which modifier characters for better or worse (mostly worse). var/synth_color = 0 //Lets normally uncolorable synth parts be colorable. var/r_synth //Used with synth_color to color synth parts that normaly can't be colored. var/g_synth //Same as above var/b_synth //Same as above var/synth_markings = 1 //Enable/disable markings on synth parts. //VOREStation Edit - 1 by default //Some faction information. var/home_system = "Unset" //System of birth. var/citizenship = "None" //Current home system. var/faction = "None" //General associated faction. var/religion = "None" //Religious association. var/antag_faction = "None" //Antag associated faction. var/antag_vis = "Hidden" //How visible antag association is to others. //Mob preview var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen. var/static/list/preview_screen_locs = list( "1" = "character_preview_map:1,5:-12", "2" = "character_preview_map:1,3:15", "4" = "character_preview_map:1:7,2:10", "8" = "character_preview_map:1:-7,1:5", "BG" = "character_preview_map:1,1 to 1,5" ) //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 //Keeps track of preferrence for not getting any wanted jobs var/alternate_option = 1 var/used_skillpoints = 0 var/skill_specialization = null var/list/skills = list() // skills can range from 0 to 3 // maps each organ to either null(intact), "cyborg" or "amputated" // will probably not be able to do this for head and torso ;) var/list/organ_data = list() var/list/rlimb_data = list() var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor" var/list/body_markings = list() // "name" = "#rgbcolor" var/list/flavor_texts = list() var/list/flavour_texts_robot = list() var/list/body_descriptors = list() var/med_record = "" var/sec_record = "" var/gen_record = "" var/exploit_record = "" var/disabilities = 0 var/economic_status = "Average" var/uplinklocation = "PDA" // OOC Metadata: var/metadata = "" var/list/ignored_players = list() var/client/client = null var/client_ckey = null // Communicator identity data var/communicator_visibility = 0 var/datum/category_collection/player_setup_collection/player_setup var/datum/browser/panel var/lastnews // Hash of last seen lobby news content. var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel. var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off /datum/preferences/New(client/C) player_setup = new(src) set_biological_gender(pick(MALE, FEMALE)) real_name = random_name(identifying_gender,species) b_type = RANDOM_BLOOD_TYPE gear = list() gear_list = list() gear_slot = 1 if(istype(C)) client = C client_ckey = C.ckey if(!IsGuestKey(C.key)) load_path(C.ckey) if(load_preferences()) if(load_character()) return /datum/preferences/Destroy() . = ..() QDEL_LIST_ASSOC_VAL(char_render_holders) /datum/preferences/proc/ZeroSkills(var/forced = 0) for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V]) if(!skills.Find(S.ID) || forced) skills[S.ID] = SKILL_NONE /datum/preferences/proc/CalculateSkillPoints() used_skillpoints = 0 for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V]) var/multiplier = 1 switch(skills[S.ID]) if(SKILL_NONE) used_skillpoints += 0 * multiplier if(SKILL_BASIC) used_skillpoints += 1 * multiplier if(SKILL_ADEPT) // secondary skills cost less if(S.secondary) used_skillpoints += 1 * multiplier else used_skillpoints += 3 * multiplier if(SKILL_EXPERT) // secondary skills cost less if(S.secondary) used_skillpoints += 3 * multiplier else used_skillpoints += 6 * multiplier /datum/preferences/proc/GetSkillClass(points) return CalculateSkillClass(points, age) /proc/CalculateSkillClass(points, age) if(points <= 0) return "Unconfigured" // skill classes describe how your character compares in total points points -= min(round((age - 20) / 2.5), 4) // every 2.5 years after 20, one extra skillpoint if(age > 30) points -= round((age - 30) / 5) // every 5 years after 30, one extra skillpoint switch(points) if(-1000 to 3) return "Terrifying" if(4 to 6) return "Below Average" if(7 to 10) return "Average" if(11 to 14) return "Above Average" if(15 to 18) return "Exceptional" if(19 to 24) return "Genius" if(24 to 1000) return "God" /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return if(!get_mob_by_key(client_ckey)) to_chat(user, "No mob exists for the given client!") close_load_dialog(user) return if(!char_render_holders) update_preview_icon() show_character_previews() var/dat = "
" if(path) dat += "Slot - " dat += "Load slot - " dat += "Save slot - " dat += "Reload slot - " dat += "Reset slot - " dat += "Copy slot" else dat += "Please create an account to save your preferences." dat += "
" dat += player_setup.header() dat += "

" dat += player_setup.content(user) dat += "" //user << browse(dat, "window=preferences;size=635x736") winshow(user, "preferences_window", TRUE) var/datum/browser/popup = new(user, "preferences_browser", "Character Setup", 800, 800) popup.set_content(dat) popup.open(FALSE) // Skip registring onclose on the browser pane onclose(user, "preferences_window", src) // We want to register on the window itself /datum/preferences/proc/update_character_previews(mutable_appearance/MA) if(!client) return var/obj/screen/setup_preview/bg/BG = LAZYACCESS(char_render_holders, "BG") if(!BG) BG = new BG.plane = TURF_PLANE BG.icon = 'icons/effects/128x48.dmi' BG.pref = src LAZYSET(char_render_holders, "BG", BG) client.screen |= BG BG.icon_state = bgstate BG.screen_loc = preview_screen_locs["BG"] for(var/D in global.cardinal) var/obj/screen/setup_preview/O = LAZYACCESS(char_render_holders, "[D]") if(!O) O = new O.pref = src LAZYSET(char_render_holders, "[D]", O) client.screen |= O O.appearance = MA O.dir = D O.screen_loc = preview_screen_locs["[D]"] /datum/preferences/proc/show_character_previews() if(!client || !char_render_holders) return for(var/render_holder in char_render_holders) client.screen |= char_render_holders[render_holder] /datum/preferences/proc/clear_character_previews() for(var/index in char_render_holders) var/obj/screen/S = char_render_holders[index] client?.screen -= S qdel(S) char_render_holders = null /datum/preferences/proc/process_link(mob/user, list/href_list) if(!user) return if(!istype(user, /mob/new_player)) return if(href_list["preference"] == "open_whitelist_forum") if(config.forumurl) user << link(config.forumurl) else to_chat(user, "The forum URL is not set in the server configuration.") return ShowChoices(usr) return 1 /datum/preferences/Topic(href, list/href_list) if(..()) return 1 if(href_list["save"]) save_preferences() save_character() else if(href_list["reload"]) load_preferences() load_character() attempt_vr(client.prefs_vr,"load_vore","") //VOREStation Edit sanitize_preferences() else if(href_list["load"]) if(!IsGuestKey(usr.key)) open_load_dialog(usr) return 1 else if(href_list["changeslot"]) load_character(text2num(href_list["changeslot"])) attempt_vr(client.prefs_vr,"load_vore","") //VOREStation Edit sanitize_preferences() close_load_dialog(usr) else if(href_list["resetslot"]) if("No" == alert("This will reset the current slot. Continue?", "Reset current slot?", "No", "Yes")) return 0 load_character(SAVE_RESET) sanitize_preferences() else if(href_list["copy"]) if(!IsGuestKey(usr.key)) open_copy_dialog(usr) return 1 else if(href_list["overwrite"]) overwrite_character(text2num(href_list["overwrite"])) sanitize_preferences() close_load_dialog(usr) else if(href_list["close"]) // User closed preferences window, cleanup anything we need to. clear_character_previews() return 1 else return 0 ShowChoices(usr) return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = TRUE) // Sanitizing rather than saving as someone might still be editing when copy_to occurs. player_setup.sanitize_setup() // This needs to happen before anything else becuase it sets some variables. character.set_species(species) // Special Case: This references variables owned by two different datums, so do it here. if(be_random_name) real_name = random_name(identifying_gender,species) // Ask the preferences datums to apply their own settings to the new mob player_setup.copy_to_mob(character) // VOREStation Edit - Sync up all their organs and species one final time character.force_update_organs() if(icon_updates) character.force_update_limbs() character.update_icons_body() character.update_mutations() character.update_underwear() character.update_hair() if(LAZYLEN(character.descriptors)) for(var/entry in body_descriptors) character.descriptors[entry] = body_descriptors[entry] /datum/preferences/proc/open_load_dialog(mob/user) var/dat = "" dat += "
" var/savefile/S = new /savefile(path) if(S) dat += "Select a character slot to load
" var/name for(var/i=1, i<= config.character_slots, i++) S.cd = "/character[i]" S["real_name"] >> name if(!name) name = "Character[i]" if(i==default_slot) name = "[name]" dat += "[name]
" dat += "
" dat += "
" //user << browse(dat, "window=saves;size=300x390") panel = new(user, "Character Slots", "Character Slots", 300, 390, src) panel.set_content(dat) panel.open() /datum/preferences/proc/close_load_dialog(mob/user) //user << browse(null, "window=saves") panel.close() /datum/preferences/proc/open_copy_dialog(mob/user) var/dat = "" dat += "
" var/savefile/S = new /savefile(path) if(S) dat += "Select a character slot to overwrite
" dat += "You will then need to save to confirm
" var/name for(var/i=1, i<= config.character_slots, i++) S.cd = "/character[i]" S["real_name"] >> name if(!name) name = "Character[i]" if(i==default_slot) name = "[name]" dat += "[name]
" dat += "
" dat += "
" panel = new(user, "Character Slots", "Character Slots", 300, 390, src) panel.set_content(dat) panel.open()