#define APPEARANCE_CATEGORY_COLUMN "" #define MAX_MUTANT_ROWS 5 #define GFLUID_ETHANOL_POWER_LIMIT 80 #define GFLUID_RARITY_LIMIT REAGENT_VALUE_RARE /datum/preferences max_save_slots = DEFAULT_SAVE_SLOTS var/unholypref = "No" //Goin 2 hell fo dis one var/stomppref = TRUE // Please step on me. var/list/gfluid_blacklist = list() //Stuff you don't want people to cum into you var/new_character_creator = TRUE // old/new character creator var/show_in_directory = 1 //Show in Character Directory var/directory_tag = "Unset" //Sorting tag to use in character directory var/directory_erptag = "Unset" //ditto, but for non-vore scenes var/directory_ad = "" //Advertisement stuff to show in character directory. var/fuzzy = FALSE //Fuzzy scaling /datum/preferences/New(client/C) // Check if readable fluids list exists // Please move this check a better location if possible if(!GLOB.genital_fluids_list) // Build list build_genital_fluids_list() //Extra saves for donators max_save_slots = CONFIG_GET(number/base_save_slots) if(istype(C)) var/extra_slots = 0 if(IS_CKEY_DONATOR_GROUP(C.key, DONATOR_GROUP_TIER_3)) extra_slots = 30 else if(IS_CKEY_DONATOR_GROUP(C.key, DONATOR_GROUP_TIER_2)) extra_slots = 20 else if(IS_CKEY_DONATOR_GROUP(C.key, DONATOR_GROUP_TIER_1)) extra_slots = 10 max_save_slots = max_save_slots + extra_slots . = ..() /datum/preferences/copy_to(mob/living/carbon/human/character, icon_updates, roundstart_checks, initial_spawn) character.fuzzy = fuzzy . = ..() /datum/preferences/ShowChoices(mob/user) //check if the player wants to use the new character creation menu if(new_character_creator) return ..() //Use the old character creation menu if(!user || !user.client) return update_preview_icon(current_tab) var/list/dat = list("
") dat += "Character Settings" dat += "Character Appearance" dat += "Character Speech" dat += "Loadout" dat += "Game Preferences" dat += "Content Preferences" dat += "Keybindings" if(!path) dat += "
Please create an account to save your preferences
" dat += "
" dat += "
" switch(current_tab) if(SETTINGS_TAB) // 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 += "
Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]
" 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(APPEARANCE_TAB) 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 += "" //body moves right sandstorm change var/use_skintones = pref_species.use_skintones if(use_skintones) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Skin Tone

" dat += "[use_custom_skin_tone ? "custom: [skin_tone]" : 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 += "

Advanced Coloring

" dat += "[(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) ? "Enabled" : "Disabled"]" dat += "

Body Colors

" dat += "Primary Color:
" dat += "#[features["mcolor"]]Change
" dat += "Secondary Color:
" dat += "#[features["mcolor2"]]Change
" dat += "Tertiary Color:
" dat += "#[features["mcolor3"]]Change
" mutant_colors = TRUE dat += "Sprite Size:[features["body_size"]*100]%
" dat += "Scaled Appearance:[fuzzy ? "Fuzzy" : "Sharp"]
" if(!(NOEYES in pref_species.species_traits)) dat += "

Eye Type

" dat += "[eye_type]
" if((EYECOLOR in pref_species.species_traits)) if(!use_skintones && !mutant_colors) dat += APPEARANCE_CATEGORY_COLUMN if(left_eye_color != right_eye_color) split_eye_colors = TRUE dat += "

Heterochromia

" dat += "[split_eye_colors ? "Enabled" : "Disabled"]" if(!split_eye_colors) dat += "

Eye Color

" dat += "#[left_eye_color]Change" else dat += "

Left Eye Color

" dat += "#[left_eye_color]Change" dat += "

Right Eye Color

" dat += "#[right_eye_color]Change
" if(HAIR in pref_species.species_traits) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Hair Style

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

Facial Hair Style

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

Hair Gradient

" dat += "[grad_style]" dat += "<>
" dat += "#[grad_color]Change
" dat += "" //Mutant stuff var/mutant_category = 0 dat += APPEARANCE_CATEGORY_COLUMN dat += "

Show mismatched markings

" dat += "[show_mismatched_markings ? "Yes" : "No"]" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) //just in case someone sets the max rows to 1 or something dumb like that dat += "" mutant_category = 0 // rp marking selection // assume you can only have mam markings or regular markings or none, never both var/marking_type if(parent.can_have_part("mam_body_markings")) marking_type = "mam_body_markings" if(marking_type) dat += APPEARANCE_CATEGORY_COLUMN dat += "

[GLOB.all_mutant_parts[marking_type]]

" // give it the appropriate title for the type of marking dat += "Add marking" // list out the current markings you have if(length(features[marking_type])) dat += "
" dat += "

Flavor Text

" dat += "Set Examine Text
" if(length(features["flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN) if(!length(features["flavor_text"])) dat += "\[...\]
" //skyrat - adds
//come to brazil or brazil comes to you else dat += "[html_encode(features["flavor_text"])]
" //skyrat - adds
and uses html_encode else dat += "[TextPreview(html_encode(features["flavor_text"]))]...
" //skyrat edit, uses html_encode //SPLURT edit - naked flavor text dat += "

Naked Flavor Text

" dat += "Set Naked Examine Text
" if(length(features["naked_flavor_text"]) <= 40) if(!length(features["naked_flavor_text"])) dat += "\[...\]
" else dat += "[html_encode(features["naked_flavor_text"])]
" else dat += "[TextPreview(html_encode(features["naked_flavor_text"]))]...
" //SPLURT edit end dat += "

Silicon Flavor Text

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

OOC notes

" dat += "Set OOC notes
" var/ooc_notes_len = length(features["ooc_notes"]) if(ooc_notes_len <= MAX_FLAVOR_PREVIEW_LEN) if(!ooc_notes_len) dat += "\[...\]
" else dat += "[features["ooc_notes"]]
" else dat += "[TextPreview(features["ooc_notes"])]...
" //SPLURT EDIT dat += "

Headshot Image

" dat += "Set Headshot Image
" if(features["headshot_link"]) dat += "" dat += "

" //SPLURT EDIT END //SKYRAT EDIT dat += "ERP : [erppref]
" dat += "Non-Con : [nonconpref]
" dat += "Vore : [vorepref]
" //END OF SKYRAT EDIT dat += "

Records


" dat += "Security Records
" if(length_char(security_records) <= 40) if(!length(security_records)) dat += "\[...\]" else dat += "[security_records]" else dat += "[TextPreview(security_records)]...
" dat += "
Medical Records
" if(length_char(medical_records) <= 40) if(!length(medical_records)) dat += "\[...\]
" else dat += "[medical_records]" else dat += "[TextPreview(medical_records)]...
" dat += APPEARANCE_CATEGORY_COLUMN //body moves right sandstorm change dat += "

Body

" dat += "Gender:[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
" if(pref_species.sexes) dat += "Body Model:[features["body_model"] == MALE ? "Masculine" : "Feminine"]
" dat += "Limb Modification:
" dat += "Modify Limbs
" for(var/modification in modified_limbs) if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC) dat += "[modification]: [modified_limbs[modification][2]]
" else dat += "[modification]: [modified_limbs[modification][1]]
" dat += "
" dat += "Species:[pref_species.name]
" dat += "Custom Species Name:[custom_species ? custom_species : "None"]
" dat += "Custom Blood Color:" dat += "[custom_blood_color ? "Enabled" : "Disabled"]
" if(custom_blood_color) dat += "Blood Color: [blood_color] Change
" dat += "Random Body:Randomize!
" dat += "Always Random Body:[be_random_body ? "Yes" : "No"]
" dat += "
Cycle background:[bgstate]
" dat += "
" var/list/markings = features[marking_type] if(!islist(markings)) // something went terribly wrong markings = list() var/list/reverse_markings = reverseList(markings) for(var/list/marking_list in reverse_markings) var/marking_index = markings.Find(marking_list) // consider changing loop to go through indexes over lists instead of using Find here var/limb_value = marking_list[1] var/actual_name = GLOB.bodypart_names[num2text(limb_value)] // get the actual name from the bitflag representing the part the marking is applied to var/color_marking_dat = "" var/number_colors = 1 var/datum/sprite_accessory/mam_body_markings/S = GLOB.mam_body_markings_list[marking_list[2]] var/matrixed_sections = S.covered_limbs[actual_name] if(S && matrixed_sections) // if it has nothing initialize it to white if(length(marking_list) == 2) var/first = "#FFFFFF" var/second = "#FFFFFF" var/third = "#FFFFFF" if(features["mcolor"]) first = "#[features["mcolor"]]" if(features["mcolor2"]) second = "#[features["mcolor2"]]" if(features["mcolor3"]) third = "#[features["mcolor3"]]" marking_list += list(list(first, second, third)) // just assume its 3 colours if it isnt it doesnt matter we just wont use the other values // index magic var/primary_index = 1 var/secondary_index = 2 var/tertiary_index = 3 switch(matrixed_sections) if(MATRIX_GREEN) primary_index = 2 if(MATRIX_BLUE) primary_index = 3 if(MATRIX_RED_BLUE) secondary_index = 2 if(MATRIX_GREEN_BLUE) primary_index = 2 secondary_index = 3 // we know it has one matrixed section at minimum color_marking_dat += "[marking_list[3][primary_index]]" // if it has a second section, add it if(matrixed_sections == MATRIX_RED_BLUE || matrixed_sections == MATRIX_GREEN_BLUE || matrixed_sections == MATRIX_RED_GREEN || matrixed_sections == MATRIX_ALL) color_marking_dat += "[marking_list[3][secondary_index]]" number_colors = 2 // if it has a third section, add it if(matrixed_sections == MATRIX_ALL) color_marking_dat += "[marking_list[3][tertiary_index]]" number_colors = 3 color_marking_dat += " Change
" dat += "" dat += "
[marking_list[2]] - [actual_name] ˄ ˅ X [color_marking_dat]
" for(var/mutant_part in GLOB.all_mutant_parts) if(mutant_part == "mam_body_markings") continue if(parent.can_have_part(mutant_part)) if(!mutant_category) dat += APPEARANCE_CATEGORY_COLUMN dat += "

[GLOB.all_mutant_parts[mutant_part]]

" dat += "[features[mutant_part]]" var/color_type = GLOB.colored_mutant_parts[mutant_part] //if it can be coloured, show the appropriate button if(color_type) dat += "#[features[color_type]] Change
" else if(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) //advanced individual part colouring system //is it matrixed or does it have extra parts to be coloured? var/find_part = features[mutant_part] || pref_species.mutant_bodyparts[mutant_part] var/find_part_list = GLOB.mutant_reference_list[mutant_part] if(find_part && find_part != "None" && find_part_list) var/datum/sprite_accessory/accessory = find_part_list[find_part] if(accessory) if(accessory.color_src == MATRIXED || accessory.color_src == MUTCOLORS || accessory.color_src == MUTCOLORS2 || accessory.color_src == MUTCOLORS3) //mutcolors1-3 are deprecated now, please don't rely on these in the future var/mutant_string = accessory.mutant_part_string var/primary_feature = "[mutant_string]_primary" var/secondary_feature = "[mutant_string]_secondary" var/tertiary_feature = "[mutant_string]_tertiary" if(!features[primary_feature]) features[primary_feature] = features["mcolor"] if(!features[secondary_feature]) features[secondary_feature] = features["mcolor2"] if(!features[tertiary_feature]) features[tertiary_feature] = features["mcolor3"] var/matrixed_sections = accessory.matrixed_sections if(accessory.color_src == MATRIXED && !matrixed_sections) message_admins("Sprite Accessory Failure (customization): Accessory [accessory.type] is a matrixed item without any matrixed sections set!") continue else if(accessory.color_src == MATRIXED) switch(matrixed_sections) if(MATRIX_GREEN) //only composed of a green section primary_feature = secondary_feature //swap primary for secondary, so it properly assigns the second colour, reserved for the green section if(MATRIX_BLUE) primary_feature = tertiary_feature //same as above, but the tertiary feature is for the blue section if(MATRIX_RED_BLUE) //composed of a red and blue section secondary_feature = tertiary_feature //swap secondary for tertiary, as blue should always be tertiary if(MATRIX_GREEN_BLUE) //composed of a green and blue section primary_feature = secondary_feature //swap primary for secondary, as first option is green, which is linked to the secondary secondary_feature = tertiary_feature //swap secondary for tertiary, as second option is blue, which is linked to the tertiary dat += "Primary Color
" dat += "#[features[primary_feature]] Change
" if((accessory.color_src == MATRIXED && (matrixed_sections == MATRIX_RED_BLUE || matrixed_sections == MATRIX_GREEN_BLUE || matrixed_sections == MATRIX_RED_GREEN || matrixed_sections == MATRIX_ALL)) || (accessory.extra && (accessory.extra_color_src == MUTCOLORS || accessory.extra_color_src == MUTCOLORS2 || accessory.extra_color_src == MUTCOLORS3))) dat += "Secondary Color
" dat += "#[features[secondary_feature]] Change
" if((accessory.color_src == MATRIXED && matrixed_sections == MATRIX_ALL) || (accessory.extra2 && (accessory.extra2_color_src == MUTCOLORS || accessory.extra2_color_src == MUTCOLORS2 || accessory.extra2_color_src == MUTCOLORS3))) dat += "Tertiary Color
" dat += "#[features[tertiary_feature]] Change
" mutant_category++ if(mutant_category >= MAX_MUTANT_ROWS) dat += "" mutant_category = 0 if(length(pref_species.allowed_limb_ids)) if(!chosen_limb_id || !(chosen_limb_id in pref_species.allowed_limb_ids)) chosen_limb_id = pref_species.limbs_id || pref_species.id dat += "

Body sprite

" dat += "[chosen_limb_id]" if(mutant_category) dat += "" mutant_category = 0 dat += "" dat += "" dat += "" dat += "" //SPLURT EDIT BEGIN - gregnancy preferences dat += "" //SPLURT EDIT END dat += APPEARANCE_CATEGORY_COLUMN 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 += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "Penis Color:
" dat += "#[features["cock_color"]]Change
" var/tauric_shape = FALSE if(features["cock_taur"]) var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[features["cock_shape"]] if(P.taur_icon && parent.can_have_part("taur")) var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]] if(T.taur_mode & P.accepted_taurs) tauric_shape = TRUE dat += "Penis Shape:[features["cock_shape"]][tauric_shape ? " (Taur)" : ""]" dat += "Penis Length:[features["cock_length"]] inch(es)" dat += "Diameter Ratio:[features["cock_diameter_ratio"]]" dat += "Penis Visibility:[features["cock_visibility"]]" dat += "Egg Stuffing:[features["cock_stuffing"] == TRUE ? "Yes" : "No"]" 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 += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "Testicles Color:
" dat += "#[features["balls_color"]]Change
" dat += "Testicles Shape:[features["balls_shape"]]" dat += "Testicles Visibility:[features["balls_visibility"]]" dat += "Egg Stuffing:[features["balls_stuffing"] == TRUE ? "Yes" : "No"]" dat += "Produces:" var/datum/reagent/balls_fluid = find_reagent_object_from_type(features["balls_fluid"]) if(balls_fluid && (balls_fluid in GLOB.genital_fluids_list)) dat += "[balls_fluid.name]" else dat += "Nothing?" dat += "" 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 += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "Vagina Color:
" dat += "#[features["vag_color"]]Change
" dat += "Vagina Visibility:[features["vag_visibility"]]" dat += "Egg Stuffing:[features["vag_stuffing"] == TRUE ? "Yes" : "No"]" dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]" if(features["has_womb"] == TRUE) dat += "Produces:" var/datum/reagent/womb_fluid = find_reagent_object_from_type(features["womb_fluid"]) if(womb_fluid && (womb_fluid in GLOB.genital_fluids_list)) dat += "[womb_fluid.name]" else dat += "Nothing?" 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 += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "Color:
" dat += "#[features["breasts_color"]]Change
" dat += "Cup Size:[features["breasts_size"]]" dat += "Breasts Shape:[features["breasts_shape"]]" dat += "Breasts Visibility:[features["breasts_visibility"]]" dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]" dat += "Egg Stuffing:[features["breasts_stuffing"] == TRUE ? "Yes" : "No"]" if(features["breasts_producing"] == TRUE) dat += "Produces:" var/datum/reagent/breasts_fluid = find_reagent_object_from_type(features["breasts_fluid"]) if(breasts_fluid && (breasts_fluid in GLOB.genital_fluids_list)) dat += "[breasts_fluid.name]" else dat += "Nothing?" dat += "" dat += APPEARANCE_CATEGORY_COLUMN dat += "

Butt

" dat += "[features["has_butt"] == TRUE ? "Yes" : "No"]" if(features["has_butt"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "Color:
" dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "Color:
" dat += "#[features["butt_color"]]Change
" dat += "Butt Size:[features["butt_size"]]" dat += "Butt Visibility:[features["butt_visibility"]]" dat += "Egg Stuffing:[features["butt_stuffing"] == TRUE ? "Yes" : "No"]" dat += "Butthole Sprite:[features["has_anus"] == TRUE ? "Yes" : "No"]" if(features["has_anus"]) dat += "Butthole Color:
" if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "#[features["anus_color"]]Change
" dat += "Butthole Shape:[features["anus_shape"]]" dat += "Butthole Visibility:[features["anus_visibility"]]" dat += "Egg Stuffing:[features["anus_stuffing"] == TRUE ? "Yes" : "No"]" dat += "" dat += APPEARANCE_CATEGORY_COLUMN dat += "

Belly

" dat += "[features["has_belly"] == TRUE ? "Yes" : "No"]" if(features["has_belly"]) if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) dat += "Color:
" dat += "[SKINTONE2HEX(skin_tone)](Skin tone overriding)
" else dat += "Color:
" dat += "#[features["belly_color"]]Change
" dat += "Belly Size:[features["belly_size"]]" dat += "Belly Visibility:[features["belly_visibility"]]" dat += "Egg Stuffing:[features["belly_stuffing"] == TRUE ? "Yes" : "No"]" dat += "" if(all_quirks.Find("Dullahan")) dat += APPEARANCE_CATEGORY_COLUMN dat += "

Neckfire

" dat += "[features["neckfire"] ? "Yes" : "No"]" if(features["neckfire"]) dat += "Color:
" dat += "#[features["neckfire_color"]]Change
" dat += "" dat += "" dat += "
" dat += "

Clothing & Equipment

" /* skyrat change dat += "Underwear:[underwear]" if(GLOB.underwear_list[underwear]?.has_color) dat += "Underwear Color: #[undie_color] Change
" dat += "Undershirt:[undershirt]" if(GLOB.undershirt_list[undershirt]?.has_color) dat += "Undershirt Color: #[shirt_color] Change
" dat += "Socks:[socks]" if(GLOB.socks_list[socks]?.has_color) dat += "Socks Color: #[socks_color] Change
" */ dat += "Backpack:[backbag]" dat += "Jumpsuit:
[jumpsuit_style]
" if((HAS_FLESH in pref_species.species_traits) || (HAS_BONE in pref_species.species_traits)) dat += "
Temporal Scarring:
[(persistent_scars) ? "Enabled" : "Disabled"]" dat += "Clear scar slots
" dat += "Uplink Location:[uplink_spawn_loc]" dat += "
" dat += "

Lewd preferences

" dat += "Lust tolerance:[lust_tolerance]" dat += "Sexual potency:[sexual_potency]" dat += "
" dat += "

Pregnancy preferences

" dat += "Chance of impregnation:[virility ? virility : "Disabled"]" dat += "Chance of getting pregnant:[fertility ? fertility : "Disabled"]" dat += "Lay inert eggs:[features["inert_eggs"] == TRUE ? "Enabled" : "Disabled"]" if(fertility) dat += "Pregnancy inflation:[pregnancy_inflation ? "Enabled" : "Disabled"]" dat += "Pregnancy breast growth:[pregnancy_breast_growth ? "Enabled" : "Disabled"]" if(fertility || features["inert_eggs"]) dat += "Egg shell:[egg_shell]" dat += "
" if(SPEECH_TAB) 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 += "" //END OF SANDSTORM EDIT dat += "" dat += "
" dat += "

Speech preferences

" dat += "Custom Speech Verb:
" dat += "[custom_speech_verb]
" dat += "Custom Tongue:
" dat += "[custom_tongue]
" //SANDSTORM EDIT - additional language + runechat color dat += "Additional Language
" var/list/languages_sorted = sort_list(language) dat += "[language.len ? languages_sorted.Join(", ") : "None"]
" dat += "Custom runechat color: [enable_personal_chat_color ? "Enabled" : "Disabled"]
[enable_personal_chat_color ? "[personal_chat_color] Change" : ""]
" dat += "
" dat += "

Vocal Bark preferences

" var/datum/bark/B = GLOB.bark_list[bark_id] dat += "Vocal Bark Sound:
" dat += "[B ? initial(B.name) : "INVALID"]
" dat += "Vocal Bark Speed: [bark_speed]
" dat += "Vocal Bark Pitch: [bark_pitch]
" dat += "Vocal Bark Variance: [bark_variance]
" dat += "
Preview Bark
" dat += "
" if(GAME_PREFERENCES_TAB) // Game Preferences dat += "" dat += "" dat += "
" dat += "

General Settings

" dat += "UI Style: [UI_style]
" dat += "Outline: [outline_enabled ? "Enabled" : "Disabled"]
" dat += "Outline Color: [outline_color ? "" : "Theme-based (null)"][outline_color] Change
" dat += "Screentip: [screentip_pref]
" dat += "Screentip Color: [screentip_color] Change
" dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
" dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
" dat += "Input Framework: [(tgui_input_mode) ? "tgui" : "BYOND"]
" dat += "tgui Button Size: [(tgui_large_buttons) ? "Large" : "Small"]
" dat += "tgui Buttons Swapped: [(tgui_swapped_buttons) ? "Yes" : "No"]
" dat += "Show Runechat Chat Bubbles: [chat_on_map ? "Enabled" : "Disabled"]
" dat += "Runechat message char limit: [max_chat_length]
" dat += "See Runechat for non-mobs: [see_chat_non_mob ? "Enabled" : "Disabled"]
" //SKYRAT CHANGES BEGIN dat += "See Runechat for emotes: [see_chat_emotes ? "Enabled" : "Disabled"]
" //SKYRAT CHANGES END dat += "Shift view when pixelshifting: [view_pixelshift ? "Enabled" : "Disabled"]
" //SPLURT Edit dat += "
" dat += "PDA Color: [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: [ooccolor ? ooccolor : GLOB.normal_ooc_colour] Change
" dat += "Antag OOC Color: [aooccolor ? aooccolor : GLOB.normal_aooc_colour] Change
" dat += "
" dat += "

Special Role Settings

" if(jobban_isbanned(user, ROLE_SYNDICATE)) dat += "You are banned from antagonist roles." src.be_special = list() dat += "DISABLE ALL ANTAGONISM [(toggles & NO_ANTAG) ? "YES" : "NO"]
" 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 var/enabled_text = "" if(i in be_special) if(be_special[i] >= 1) enabled_text = "Enabled" else enabled_text = "Low" else enabled_text = "Disabled" dat += "Be [capitalize(i)]: [enabled_text]
" dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]
" dat += "
" dat += "
" if(user.client.holder) // sandstorm start - moves admin prefs to the right 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 += "Use Modern Player Panel: [use_new_playerpanel ? "Yes" : "No"]
" // sandstorm end - moves admins prefs to the right //deadmin dat += "

Deadmin While Playing

" if(CONFIG_GET(flag/auto_deadmin_players)) dat += "Always Deadmin: FORCED
" else dat += "Always Deadmin: [(deadmin & DEADMIN_ALWAYS)?"Enabled":"Disabled"]
" if(!(deadmin & DEADMIN_ALWAYS)) dat += "
" if(!CONFIG_GET(flag/auto_deadmin_antagonists)) dat += "As Antag: [(deadmin & DEADMIN_ANTAGONIST)?"Deadmin":"Keep Admin"]
" else dat += "As Antag: FORCED
" if(!CONFIG_GET(flag/auto_deadmin_heads)) dat += "As Command: [(deadmin & DEADMIN_POSITION_HEAD)?"Deadmin":"Keep Admin"]
" else dat += "As Command: FORCED
" if(!CONFIG_GET(flag/auto_deadmin_security)) dat += "As Security: [(deadmin & DEADMIN_POSITION_SECURITY)?"Deadmin":"Keep Admin"]
" else dat += "As Security: FORCED
" if(!CONFIG_GET(flag/auto_deadmin_silicons)) dat += "As Silicon: [(deadmin & DEADMIN_POSITION_SILICON)?"Deadmin":"Keep Admin"]
" else dat += "As Silicon: FORCED
" 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 += "Long strip menu: [long_strip_menu ? "Enabled" : "Disabled"]
" dat += "Auto stand: [autostand ? "Enabled" : "Disabled"]
" dat += "Auto OOC: [auto_ooc ? "Enabled" : "Disabled"]
" dat += "Force Slot Storage HUD: [no_tetris_storage ? "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")]
" dat += "Recoil Screen Push: [(recoil_screenshake==100) ? "Full" : ((recoil_screenshake==0) ? "None" : "[screenshake]")]
" var/p_chaos if (!preferred_chaos) p_chaos = "No preference" else p_chaos = preferred_chaos dat += "Preferred Chaos Amount: [p_chaos]
" dat += "

S.P.L.U.R.T. Preferences

" dat += "Be Antagonist Victim: [be_victim ? be_victim : BEVICTIM_ASK]
" dat += "Disable combat mode cursor: [disable_combat_cursor?"Yes":"No"]
" dat += "Splashscreen Player Panel Style: [(toggles & TG_PLAYER_PANEL)?"TG":"Old"]
" dat += "Character Creation Menu Style: [new_character_creator ? "New" : "Old"]
" 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 += "Income Updates: [(chat_toggles & CHAT_BANKCARD) ? "Allowed" : "Muted"]
" dat += "
" 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 += "HUD Button Flashes: [hud_toggle_flash ? "Enabled" : "Disabled"]
" dat += "HUD Button Flash Color: [hud_toggle_color] Change
" /* CITADEL EDIT - We're using top menu instead button_name = pixel_size dat += "Pixel Scaling: [(button_name) ? "Pixel Perfect [button_name]x" : "Stretch to fit"]
" switch(scaling_method) if(SCALING_METHOD_NORMAL) button_name = "Nearest Neighbor" if(SCALING_METHOD_DISTORT) button_name = "Point Sampling" if(SCALING_METHOD_BLUR) button_name = "Bilinear" dat += "Scaling Method: [button_name]
" */ 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 += "" if(LOADOUT_TAB) //calculate your gear points from the chosen item gear_points = CONFIG_GET(number/initial_gear_points) var/list/chosen_gear = loadout_data["SAVE_[loadout_slot]"] if(chosen_gear) for(var/loadout_item in chosen_gear) var/loadout_item_path = loadout_item[LOADOUT_ITEM] if(loadout_item_path) var/datum/gear/loadout_gear = text2path(loadout_item_path) if(loadout_gear) gear_points -= initial(loadout_gear.cost) else chosen_gear = list() dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" dat += "" for(var/name in GLOB.loadout_items[gear_category][gear_subcategory]) var/datum/gear/gear = GLOB.loadout_items[gear_category][gear_subcategory][name] var/donoritem = gear.donoritem if(donoritem && !gear.donator_ckey_check(user.ckey)) continue var/class_link = "" var/list/loadout_item = has_loadout_gear(loadout_slot, "[gear.type]") var/extra_loadout_data = "" if(loadout_item) class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=0'" if(gear.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC) extra_loadout_data += "
Color" for(var/loadout_color in loadout_item[LOADOUT_COLOR]) extra_loadout_data += "[loadout_color]" else var/loadout_color_non_poly = "#FFFFFF" if(length(loadout_item[LOADOUT_COLOR])) loadout_color_non_poly = loadout_item[LOADOUT_COLOR][1] extra_loadout_data += "
Color" extra_loadout_data += "[loadout_color_non_poly]" if(gear.loadout_flags & LOADOUT_CAN_NAME) extra_loadout_data += "
Name [loadout_item[LOADOUT_CUSTOM_NAME] ? loadout_item[LOADOUT_CUSTOM_NAME] : "N/A"]" if(gear.loadout_flags & LOADOUT_CAN_DESCRIPTION) extra_loadout_data += "
Description" else if((gear_points - gear.cost) < 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(name)];toggle_gear=1'" else if(!istype(gear, /datum/gear/unlockable) || can_use_unlockable(gear)) class_link = "style='white-space:normal;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(name)];toggle_gear=1'" else class_link = "style='white-space:normal;background:#eb2e2e;' class='linkOff'" dat += "" dat += "" else //we add the user's progress to the description assuming they have progress var/datum/gear/unlockable/unlockable = gear var/progress_made = unlockable_loadout_data[unlockable.progress_key] if(!progress_made) progress_made = 0 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.
" if(!length(GLOB.loadout_items)) dat += "
ERROR: No loadout categories - something is horribly wrong!" else if(!GLOB.loadout_categories[gear_category]) gear_category = GLOB.loadout_categories[1] var/firstcat = TRUE for(var/category in GLOB.loadout_categories) if(firstcat) firstcat = FALSE else dat += " |" if(category == gear_category) dat += " [category] " else dat += " [category] " dat += "

" if(!length(GLOB.loadout_categories[gear_category])) dat += "No subcategories detected. Something is horribly wrong!" else var/list/subcategories = GLOB.loadout_categories[gear_category] if(!subcategories.Find(gear_subcategory)) gear_subcategory = subcategories[1] var/firstsubcat = TRUE for(var/subcategory in subcategories) if(firstsubcat) firstsubcat = FALSE else dat += " |" if(gear_subcategory == subcategory) dat += " [subcategory] " else dat += " [subcategory] " dat += "
NameCostRestrictionsDescription
[name][extra_loadout_data][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 += "" if(!istype(gear, /datum/gear/unlockable)) // the below line essentially means "if the loadout item is picked by the user and has a custom description, give it the custom description, otherwise give it the default description" dat += "[loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description]
[loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description] Progress: [min(progress_made, unlockable.progress_required)]/[unlockable.progress_required]
" if(CONTENT_PREFERENCES_TAB) // Content preferences dat += "" dat +="
" dat += "

Fetish content prefs

" dat += "Allow Lewd Verbs: [(toggles & VERB_CONSENT) ? "Yes":"No"]
" // Skyrat - ERP Mechanic Addition dat += "Mute Lewd Verb Sounds: [(toggles & LEWD_VERB_SOUNDS) ? "Yes":"No"]
" // Skyrat - ERP Mechanic Addition dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
" dat += "Genital examine text:[(cit_toggles & GENITAL_EXAMINE) ? "Enabled" : "Disabled"]
" dat += "Vore examine text:[(cit_toggles & VORE_EXAMINE) ? "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 += "Allow trash forcefeeding (requires Trashcan quirk) [(cit_toggles & TRASH_FORCEFEED) ? "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 += "Butt Enlargement: [(cit_toggles & BUTT_ENLARGEMENT) ? "Allowed" : "Disallowed"]
" dat += "Belly Inflation: [(cit_toggles & BELLY_INFLATION) ? "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"]
" //SPLURT EDIT dat += "? " dat += "Unholy ERP verbs : [unholypref]
" //https://www.youtube.com/watch?v=OHKARc-GObU dat += "? " dat += "Stomping Interactions : [stomppref ? "Yes" : "No"]
" //END OF SPLURT EDIT //SKYRAT EDIT dat += "? " dat += "Extreme ERP verbs : [extremepref]
" // https://youtu.be/0YrU9ASVw6w if(extremepref != "No") dat += "? " dat += "Harmful ERP verbs : [extremeharm]
" //END OF SKYRAT EDIT dat += "Automatic Wagging: [(cit_toggles & NO_AUTO_WAG) ? "Disabled" : "Enabled"]
" dat += "? " dat += "Genital Fluid Blacklist
" if(gfluid_blacklist?.len) dat += "? " dat += "Genital Fluid Un-Blacklist
" dat += "
" dat += "
" if(KEYBINDINGS_TAB_OLD) // Custom keybindings dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Input"]
" dat += "Keybindings mode controls how the game behaves with tab and map/input focus.
If it is on Hotkeys, the game will always attempt to force you to map focus, meaning keypresses are sent \ directly to the map instead of the input. You will still be able to use the command bar, but you need to tab to do it every time you click on the game map.
\ If it is on Input, the game will not force focus away from the input bar, and you can switch focus using TAB between these two modes: If the input bar is pink, that means that you are in non-hotkey mode, sending all keypresses of the normal \ alphanumeric characters, punctuation, spacebar, backspace, enter, etc, typing keys into the input bar. If the input bar is white, you are in hotkey mode, meaning all keypresses go into the game's keybind handling system unless you \ manually click on the input bar to shift focus there.
\ Input mode is the closest thing to the old input system.
\ IMPORTANT: While in input mode's non hotkey setting (tab toggled), Ctrl + KEY will send KEY to the keybind system as the key itself, not as Ctrl + KEY. This means Ctrl + T/W/A/S/D/all your familiar stuff still works, but you \ won't be able to access any regular Ctrl binds.
" dat += "
Modifier-Independent binding - This is a singular bind that works regardless of if Ctrl/Shift/Alt are held down. For example, if combat mode is bound to C in modifier-independent binds, it'll trigger regardless of if you are \ holding down shift for sprint. Each keybind can only have one independent binding, and each key can only have one keybind independently bound to it." // Create an inverted list of keybindings -> key var/list/user_binds = list() var/list/user_modless_binds = list() for (var/key in key_bindings) for(var/kb_name in key_bindings[key]) user_binds[kb_name] += list(key) for (var/key in modless_key_bindings) user_modless_binds[modless_key_bindings[key]] = key var/list/kb_categories = list() // Group keybinds by category for (var/name in GLOB.keybindings_by_name) var/datum/keybinding/kb = GLOB.keybindings_by_name[name] kb_categories[kb.category] += list(kb) dat += {" "} for (var/category in kb_categories) dat += "

[category]

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

" dat += "\[Reset to default\]" dat += "" dat += "
" if(!IsGuestKey(user.key)) dat += "Undo " dat += "Save Setup " dat += "Reset Setup" dat += "
" winshow(user, "preferences_window", TRUE) var/datum/browser/popup = new(user, "preferences_browser", "
Character Setup
", 640, 770) popup.set_content(dat.Join()) popup.open(FALSE) onclose(user, "preferences_window", src) /datum/preferences/process_link(mob/user, list/href_list) switch(href_list["task"]) if("random") //no if("input") switch(href_list["preference"]) if("marking_color") var/index = text2num(href_list["marking_index"]) var/marking_type = href_list["marking_type"] if(index && marking_type && features[marking_type]) // work out the input options to show the user var/list/options = list("Primary") var/number_colors = text2num(href_list["number_colors"]) var/color_number = 1 // 1-3 which color are we editing if(number_colors >= 2) options += "Secondary" if(number_colors == 3) options += "Tertiary" var/color_option = input(user, "Select the colour you wish to edit") as null|anything in options if(color_option) if(color_option == "Secondary") color_number = 2 if(color_option == "Tertiary") color_number = 3 // perform some magic on the color number var/list/marking_list = features[marking_type][index] var/datum/sprite_accessory/mam_body_markings/S = GLOB.mam_body_markings_list[marking_list[2]] var/matrixed_sections = S.covered_limbs[GLOB.bodypart_names[num2text(marking_list[1])]] if(color_number == 1) switch(matrixed_sections) if(MATRIX_GREEN) color_number = 2 if(MATRIX_BLUE) color_number = 3 else if(color_number == 2) switch(matrixed_sections) if(MATRIX_RED_BLUE) color_number = 3 if(MATRIX_GREEN_BLUE) color_number = 3 var/color_list = features[marking_type][index][3] var/new_marking_color = input(user, "Choose your character's marking color:", "Character Preference","#"+color_list[color_number]) as color|null if(new_marking_color) var/temp_hsv = RGBtoHSV(new_marking_color) if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) // mutantcolors must be bright, but only if they affect the skin color_list[color_number] = "#[sanitize_hexcolor(new_marking_color, 6)]" else to_chat(user, "Invalid color. Your color is not bright enough.") else switch(href_list["preference"]) if("charcreation_style") new_character_creator = !new_character_creator . = ..() /proc/build_genital_fluids_list() // Define disallowed reagents var/list/blacklisted = list( // Base ethanol /datum/reagent/consumable/ethanol, // // Effect drinks // // Removes dizziness, drowsiness, and sleeping /datum/reagent/consumable/ethanol/kahlua, // Can cause organ loss and death /datum/reagent/consumable/ethanol/thirteenloko, // Drugs the user /datum/reagent/consumable/ethanol/threemileisland, // Causes hallucinations /datum/reagent/consumable/ethanol/absinthe, // Heals body parts for assistants /datum/reagent/consumable/ethanol/hooch, // Heals revolutionary antagonists /datum/reagent/consumable/ethanol/cuba_libre, // Heals radiation for engineers /datum/reagent/consumable/ethanol/screwdrivercocktail, // Restores blood volume /datum/reagent/consumable/ethanol/bloody_mary, // Causes the user to emit light /datum/reagent/consumable/ethanol/tequila_sunrise, // Increases body temperature /datum/reagent/consumable/ethanol/toxins_special, // Causes hallucinations /datum/reagent/consumable/ethanol/beepsky_smash, // Heals brute and burn damage for dwarfs /datum/reagent/consumable/ethanol/manly_dorf, // Drugs the user /datum/reagent/consumable/ethanol/manhattan_proj, // Increases body temperature /datum/reagent/consumable/ethanol/antifreeze, // Heals brute damage /datum/reagent/consumable/ethanol/barefoot, // Increases body temperature /datum/reagent/consumable/ethanol/sbiten, // Reduces body temperature /datum/reagent/consumable/ethanol/iced_beer, // Grants points for changeling antagonist /datum/reagent/consumable/ethanol/changelingsting, // Plays an explosion sound effect /datum/reagent/consumable/ethanol/syndicatebomb, // Heals body parts for clowns /datum/reagent/consumable/ethanol/bananahonk, // Heals body parts for mimes /datum/reagent/consumable/ethanol/silencer, // Attracts nearby ores /datum/reagent/consumable/ethanol/fetching_fizz, // Heals critical health users 'extremely quickly' /datum/reagent/consumable/ethanol/hearty_punch, // Causes confusion, dizziness, slurring, sleep, and toxin damage /datum/reagent/consumable/ethanol/atomicbomb, // Causes dizziness, slurring, confusion, drugging, and toxin damage /datum/reagent/consumable/ethanol/gargle_blaster, // Causes brain damage, drugging, and dizziness /datum/reagent/consumable/ethanol/neurotoxin, // Causes brain damage /datum/reagent/consumable/ethanol/neuroweak, // Causes slurring, dizziness, drugging, jittering, and toxin damage /datum/reagent/consumable/ethanol/hippies_delight, // Causes cult sluttering and stuttering /datum/reagent/consumable/ethanol/narsour, // Causes clock cult slurring and stuttering /datum/reagent/consumable/ethanol/cogchamp, // Heals body part and brute damage for some mobs /datum/reagent/consumable/ethanol/pinotmort, // Heals body part and brute damage for security /datum/reagent/consumable/ethanol/quadruple_sec, // Heals body part, brute, suffocation, burn, and toxin damage for security /datum/reagent/consumable/ethanol/quintuple_sec, // Heals brute, burn, toxin, suffocation, and stamina damage /datum/reagent/consumable/ethanol/bastion_bourbon, // Grants nutrition /datum/reagent/consumable/ethanol/squirt_cider, // Grants nutrition /datum/reagent/consumable/ethanol/sugar_rush, // Grants soothed throat effect and increases temperature /datum/reagent/consumable/ethanol/peppermint_patty, // Removes mighty shield reagent /datum/reagent/consumable/ethanol/alexander, // Heals brute and burn damage for sleeping users /datum/reagent/consumable/ethanol/between_the_sheets, // Removes nutrition and causes toxin damage /datum/reagent/consumable/ethanol/fernet, // Removes nutrition and causes toxin damage /datum/reagent/consumable/ethanol/fernet_cola, // Removes nutrition and clears overeating duration /datum/reagent/consumable/ethanol/fanciulli, // Reduces body temperature /datum/reagent/consumable/ethanol/branca_menta, // Heals body part damage for mimes /datum/reagent/consumable/ethanol/blank_paper, // Heals body part, suffocation, and toxin damage for wizards /datum/reagent/consumable/ethanol/wizz_fizz, // Causes toxin damage to insects /datum/reagent/consumable/ethanol/bug_spray, // Reduces stamina /datum/reagent/consumable/ethanol/turbo, // Increases age, changes hair color, causes nearsightedness, causes a beard /datum/reagent/consumable/ethanol/old_timer, // Heals burn damage, removes jittering, and removes stuttering for Chaplain /datum/reagent/consumable/ethanol/trappist, // Teleports the user /datum/reagent/consumable/ethanol/blazaam, // Increases temperature, and can cause ignition /datum/reagent/consumable/ethanol/mauna_loa, // Heals body part, brute, suffocation, fire, foxin, and radiation for the Captain /datum/reagent/consumable/ethanol/commander_and_chief, // Increases temperature /datum/reagent/consumable/ethanol/hellfire, // Causes drugging and stamina loss /datum/reagent/consumable/ethanol/hotlime_miami, // Causes brute damage /datum/reagent/consumable/ethanol/crevice_spike, /* * The following reagents have effects * But are too mild to warrant blacklisting * // Tints the user green /datum/reagent/consumable/ethanol/beer/green, // Heals radiation /datum/reagent/consumable/ethanol/vodka, // Heals brute loss /datum/reagent/consumable/ethanol/bilk, // Plays an explosion sound effect /datum/reagent/consumable/ethanol/b52, // Displays a chat message /datum/reagent/consumable/ethanol/gunfire, */ // // SPLURT effect drinks // /* * The following reagents have effects * But are allowed for humor purposes * // Causes clothing loss /datum/reagent/consumable/ethanol/panty_dropper, // Causes brain damage /datum/reagent/consumable/ethanol/lean, */ // Contains morphine /datum/reagent/consumable/ethanol/isloation_cell/morphine, // Contains hexacrocin, morphine, and enthrall /datum/reagent/consumable/ethanol/chemical_ex, // Captain drink /datum/reagent/consumable/ethanol/heart_of_gold, // Captain drink /datum/reagent/consumable/ethanol/moth_in_chief, // Replaces the tongue /datum/reagent/consumable/ethanol/skullfucker_deluxe, // Heals brute, burn, and toxin or suffocation damage /datum/reagent/consumable/ethanol/ionstorm, // // Effect drink reagents // // Causes toxin damage /datum/reagent/consumable/poisonberryjuice, // Heals body parts for clown /datum/reagent/consumable/banana, // Heals body parts for mime /datum/reagent/consumable/nothing, // Causes forced laughter emote and mood event /datum/reagent/consumable/laughter, // Causes stun and mood event /datum/reagent/consumable/superlaughter, // Heals brute, fire, toxin, and suffocation damage, and reduces nutrition for non-doctors /datum/reagent/consumable/doctor_delight, // Reduces size /datum/reagent/consumable/red_queen, // Causes stamina loss, forced emote, chat messages, and arousal /datum/reagent/consumable/catnip_tea, // Heals toxin damage /datum/reagent/consumable/aloejuice, /* * The following reagents have effects * But are allowed for humor purposes * // Heals body part and brute damage, removes capsaicin, and heals body parts for calcium healers /datum/reagent/consumable/milk, // Heals body parts /datum/reagent/consumable/soymilk, // Heals body parts /datum/reagent/consumable/coconutmilk, // Heals body parts /datum/reagent/consumable/cream, */ /* * The following reagents have effects * But are too mild to warrant blacklisting * // Heals suffocation damage /datum/reagent/consumable/orangejuice, // Heals burn damage /datum/reagent/consumable/tomatojuice, // Heals body parts /datum/reagent/consumable/tomatojuice, // Heals blurred vision, blindness, and nearsightedness /datum/reagent/consumable/carrotjuice, // Removes dizziness, drowsiness, and sleeping, increases temperature, and removes frost oil /datum/reagent/consumable/coffee, // Reduces dizziness, drowsiness, jittering, and sleeping, heals toxin damage, and increases temperature /datum/reagent/consumable/tea, // Reduces nutrition, dizziness, drowsiness, and jittering, and increases temperature /datum/reagent/consumable/tea/red, // Heals liver damage, reduces dizziness, drowsiness, and jittering, and increases temperature /datum/reagent/consumable/tea/green, // Heals toxin damage, reduces dizziness, drowsiness, and jittering, and increases temperature /datum/reagent/consumable/tea/forest, // Causes drugging and dizziness, removes all disgust /datum/reagent/consumable/tea/mush, // Displays chat messages /datum/reagent/consumable/tea/arnold_palmer, // Reduces dizziness, drowsiness, jittering, and sleeping, and reduces temperature /datum/reagent/consumable/icecoffee, // Reduces dizziness, drowsiness, and sleeping, heals toxin damage, and reduces temperature /datum/reagent/consumable/icetea, // Reduces drowsiness and temperature /datum/reagent/consumable/space_cola, // Causes jittering, drugging, and dizziness, removes drowsiness, reduces sleeping and temperature /datum/reagent/consumable/nuka_cola, // Reduces drowsiness, sleeping, and temperature, and causes jittering /datum/reagent/consumable/spacemountainwind, // Reduces temperature /datum/reagent/consumable/space_up, // Reduces temperature /datum/reagent/consumable/lemon_lime, // Reduces temperature /datum/reagent/consumable/pwr_game, // Reduces temperature /datum/reagent/consumable/shamblers, // Adds sugar or honey /datum/reagent/consumable/buzz_fuzz, // Causes jittering, and dizziness, removes drowsiness, reduces sleeping and temperature /datum/reagent/consumable/grey_bull, // Reduces dizziness, and drowsiness, and temperature /datum/reagent/consumable/sodawater, // Reduces dizziness, and drowsiness, and temperature /datum/reagent/consumable/tonic, // Reduces dizziness and drowsiness, removes sleeping, increases temperature and jittering, heals body parts /datum/reagent/consumable/soy_latte, // Reduces dizziness and drowsiness, removes sleeping, increases temperature and jittering, heals body parts /datum/reagent/consumable/cafe_latte, // Reduces temperature /datum/reagent/consumable/grape_soda, // Causes throat soothed effect /datum/reagent/consumable/menthol, // Reduces temperature /datum/reagent/consumable/cream_soda, // Reduces disgust /datum/reagent/consumable/sol_dry, // Causes chat messages /datum/reagent/consumable/milk/pinkmilk, // Causes chat messages /datum/reagent/consumable/tea/pinktea, // Causes jittering, and dizziness, removes drowsiness, reduces sleeping and temperature /datum/reagent/consumable/monkey_energy, */ // // Effect standard reagents // // Grants nutrition /datum/reagent/consumable/nutriment/vitamin, // Can cause hyperglycemic shock (sleeping) /datum/reagent/consumable/sugar, // Increases temperature /datum/reagent/consumable/capsaicin, // Reduces temperature /datum/reagent/consumable/frostoil, // Causes coughing, and can be used for stuns /datum/reagent/consumable/condensedcapsaicin, // Heals the cook, but damages vampires /datum/reagent/consumable/garlic, // Heals body part damage /datum/reagent/consumable/sprinkles, // Increases temperature /datum/reagent/consumable/hot_ramen, // Increases temperature /datum/reagent/consumable/hell_ramen, // Adds sugar reagent /datum/reagent/consumable/corn_syrup, // Adds sugar, heals brute, burn, suffocation, and toxin /datum/reagent/consumable/honey, // Causes temporary blindness and blurred vision /datum/reagent/consumable/tearjuice, // Causes unconsciousness, breath loss, brain damage, toxin damage, stamina loss, and blurred vision /datum/reagent/consumable/entpoly, // Heals brute and burn damage /datum/reagent/consumable/vitfro, // Causes electrocution /datum/reagent/consumable/liquidelectricity, // Causes forced speech /datum/reagent/consumable/char, // Secret reagent, makes all food max quality /datum/reagent/consumable/secretsauce, // Used for making most food /datum/reagent/consumable/enzyme, /* * The following reagents have effects * But are too mild to warrant blacklisting * // Increases temperature /datum/reagent/consumable/hot_coco, */ ) // Define base list var/list/consumable_list = subtypesof(/datum/reagent/consumable) // Define additional allowed reagents var/list/whitelist_list = list( // Just water /datum/reagent/water, // Causes arousal // Allowed for ERP reasons /datum/reagent/drug/aphrodisiac, /datum/reagent/drug/aphrodisiacplus, // Allowed for expansion reasons /datum/reagent/fermi/breast_enlarger, /datum/reagent/fermi/penis_enlarger, /datum/reagent/fermi/butt_enlarger, // Allowed for reduction reasons /datum/reagent/fermi/BEsmaller, /datum/reagent/fermi/PEsmaller, /datum/reagent/fermi/AEsmaller_hypo, // Code comment here, whoever named the AEsmaller_hypo needs to understand the chem shouldn't be named after the fact it's found in a hypo // Causes positive mood bonus // On overdose: Causes negative mood penalty and disgust /datum/reagent/drug/copium/gfluid, // Restores blood volume /datum/reagent/blood, ) // Add whitelisted entries to main list LAZYADD(consumable_list, whitelist_list) // Define final list var/list/reagent_list // Define final type-based list var/list/reagent_list_paths for(var/reagent in consumable_list) // Define reagent var/datum/reagent/instance = find_reagent_object_from_type(reagent) // Check if reagent exists if(!instance) continue // Check if reagent is non-liquid if(instance.reagent_state != LIQUID) // Ignore reagent continue // Check if reagent is blacklisted if(reagent in blacklisted) // Ignore reagent continue // Check if reagent is manually whitelisted if(reagent in whitelist_list) // Add immediately LAZYADD(reagent_list, instance) LAZYADD(reagent_list_paths, reagent) // Skip further processing continue // Check if reagent exceeds rarity limit if(instance.value >= GFLUID_RARITY_LIMIT) // Ignore reagent continue // Check if reagent is an ethanol sub-type if(istype(instance, /datum/reagent/consumable/ethanol)) // Define ethanol reagent var/datum/reagent/consumable/ethanol/drink = instance // Check if booze power exceeds the defined limit if(drink.boozepwr > GFLUID_ETHANOL_POWER_LIMIT) // Ignore reagent continue // Add reagent to final list LAZYADD(reagent_list, instance) // Add reagent to type list LAZYADD(reagent_list_paths, reagent) // Define readable GLOB GLOB.genital_fluids_list = reagent_list // Define type-path GLOB GLOB.genital_fluids_paths = reagent_list_paths /proc/allowed_gfluid_paths() // Check if paths list exists if(!GLOB.genital_fluids_paths) // Build list build_genital_fluids_list() // Return list of valid types return GLOB.genital_fluids_paths #undef APPEARANCE_CATEGORY_COLUMN #undef MAX_MUTANT_ROWS