mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 07:48:55 +00:00
4525 lines
225 KiB
Plaintext
4525 lines
225 KiB
Plaintext
#define DEFAULT_SLOT_AMT 2
|
|
#define HANDS_SLOT_AMT 2
|
|
#define BACKPACK_SLOT_AMT 4
|
|
|
|
GLOBAL_LIST_EMPTY(preferences_datums)
|
|
|
|
/datum/preferences
|
|
var/client/parent
|
|
//doohickeys for savefiles
|
|
var/path
|
|
var/vr_path
|
|
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
|
|
var/max_save_slots = 24
|
|
|
|
// Intra-round persistence begin
|
|
/// Flags for admin mutes
|
|
var/muted = NONE
|
|
/// Last IP the person was seen on
|
|
var/last_ip
|
|
/// Last CID the person was seen on
|
|
var/last_id
|
|
/// Do we log their clicks to disk?
|
|
var/log_clicks = FALSE
|
|
/// Characters they have joined the round under - Lazylist of names
|
|
var/list/characters_joined_as
|
|
/// Slots they have joined the round under - Lazylist of numbers
|
|
var/list/slots_joined_as
|
|
/// Are we currently subject to respawn restrictions? Usually set by us using the "respawn" verb, but can be lifted by admins.
|
|
var/respawn_restrictions_active = FALSE
|
|
/// time of death we consider for respawns
|
|
var/respawn_time_of_death = -INFINITY
|
|
/// did they DNR? used to prevent respawns.
|
|
var/dnr_triggered = FALSE
|
|
/// did they cryo on their last ghost?
|
|
var/respawn_did_cryo = FALSE
|
|
|
|
// Intra-round persistence end
|
|
|
|
var/icon/custom_holoform_icon
|
|
var/list/cached_holoform_icons
|
|
var/last_custom_holoform = 0
|
|
|
|
//Cooldowns for saving/loading. These are four are all separate due to loading code calling these one after another
|
|
COOLDOWN_DECLARE(saveprefcooldown)
|
|
COOLDOWN_DECLARE(loadprefcooldown)
|
|
COOLDOWN_DECLARE(savecharcooldown)
|
|
COOLDOWN_DECLARE(loadcharcooldown)
|
|
|
|
//game-preferences
|
|
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
|
|
var/ooccolor = "#c43b23"
|
|
var/aooccolor = "#ce254f"
|
|
var/enable_tips = TRUE
|
|
var/tip_delay = 500 //tip delay in milliseconds
|
|
|
|
//Antag preferences
|
|
var/list/be_special = list() //Special role selection. ROLE_SYNDICATE being missing means they will never be antag!
|
|
var/tmp/old_be_special = 0 //Bitflag version of be_special, used to update old savefiles and nothing more
|
|
//If it's 0, that's good, if it's anything but 0, the owner of this prefs file's antag choices were,
|
|
//autocorrected this round, not that you'd need to check that.
|
|
|
|
var/UI_style = null
|
|
var/outline_enabled = TRUE
|
|
var/outline_color = COLOR_THEME_MIDNIGHT
|
|
var/screentip_pref = SCREENTIP_PREFERENCE_ENABLED
|
|
var/screentip_color = "#ffd391"
|
|
var/screentip_images = TRUE
|
|
var/hotkeys = TRUE
|
|
|
|
///Runechat preference. If true, certain messages will be displayed on the map, not ust on the chat area. Boolean.
|
|
var/chat_on_map = TRUE
|
|
///Limit preference on the size of the message. Requires chat_on_map to have effect.
|
|
var/max_chat_length = CHAT_MESSAGE_MAX_LENGTH
|
|
///Whether non-mob messages will be displayed, such as machine vendor announcements. Requires chat_on_map to have effect. Boolean.
|
|
var/see_chat_non_mob = TRUE
|
|
///Whether emotes will be displayed on runechat. Requires chat_on_map to have effect. Boolean.
|
|
var/see_rc_emotes = TRUE
|
|
|
|
/// Custom Keybindings
|
|
var/list/key_bindings = list()
|
|
/// List with a key string associated to a list of keybindings. Unlike key_bindings, this one operates on raw key, allowing for binding a key that triggers regardless of if a modifier is depressed as long as the raw key is sent.
|
|
var/list/modless_key_bindings = list()
|
|
|
|
var/tgui_fancy = TRUE
|
|
var/tgui_lock = TRUE
|
|
var/tgui_input_mode = TRUE // All the Input Boxes (Text,Number,List,Alert)
|
|
var/tgui_large_buttons = TRUE
|
|
var/tgui_swapped_buttons = FALSE
|
|
var/windowflashing = TRUE
|
|
var/toggles = TOGGLES_DEFAULT
|
|
/// A separate variable for deadmin toggles, only deals with those.
|
|
var/deadmin = NONE
|
|
var/db_flags
|
|
var/chat_toggles = TOGGLES_DEFAULT_CHAT
|
|
var/ghost_form = "ghost"
|
|
var/ghost_orbit = GHOST_ORBIT_CIRCLE
|
|
var/ghost_accs = GHOST_ACCS_DEFAULT_OPTION
|
|
var/ghost_others = GHOST_OTHERS_DEFAULT_OPTION
|
|
var/ghost_hud = 1
|
|
var/inquisitive_ghost = 1
|
|
var/allow_midround_antag = 1
|
|
var/preferred_map = null
|
|
var/preferred_chaos = null
|
|
var/be_victim = null
|
|
var/use_new_playerpanel = TRUE
|
|
var/disable_combat_cursor = FALSE
|
|
var/pda_style = MONO
|
|
var/pda_color = "#808000"
|
|
var/pda_skin = PDA_SKIN_ALT
|
|
|
|
// Added by SPLURT (Custom Blood Color)
|
|
var/custom_blood_color = FALSE
|
|
var/blood_color = BLOOD_COLOR_UNIVERSAL
|
|
///
|
|
|
|
var/uses_glasses_colour = 0
|
|
|
|
//character preferences
|
|
var/real_name //our character's name
|
|
var/nameless = FALSE //whether or not our character is nameless
|
|
var/be_random_name = 0 //whether we'll have a random name every round
|
|
var/be_random_body = 0 //whether we'll have a random body every round
|
|
var/gender = MALE //gender of character (well duh)
|
|
var/age = 30 //age of character
|
|
//Sandstorm CHANGES BEGIN
|
|
var/erppref = "Ask"
|
|
var/nonconpref = "Ask"
|
|
var/vorepref = "Ask"
|
|
var/extremepref = "No" //This is for extreme shit, maybe even literal shit, better to keep it on no by default
|
|
var/extremeharm = "No" //If "extreme content" is enabled, this option serves as a toggle for the related interactions to cause damage or not
|
|
var/see_chat_emotes = TRUE
|
|
var/view_pixelshift = FALSE
|
|
var/enable_personal_chat_color = FALSE
|
|
var/personal_chat_color = "#ffffff"
|
|
var/list/alt_titles_preferences = list()
|
|
var/lust_tolerance = 100
|
|
var/sexual_potency = 15
|
|
//Sandstorm CHANGES END
|
|
var/underwear = "Nude" //underwear type
|
|
var/undie_color = "FFFFFF"
|
|
var/undershirt = "Nude" //undershirt type
|
|
var/shirt_color = "FFFFFF"
|
|
var/socks = "Nude" //socks type
|
|
var/socks_color = "FFFFFF"
|
|
var/backbag = DBACKPACK //backpack type
|
|
var/jumpsuit_style = PREF_SUIT //suit/skirt
|
|
var/hair_style = "Bald" //Hair type
|
|
var/hair_color = "000000" //Hair color
|
|
var/facial_hair_style = "Shaved" //Face hair type
|
|
var/facial_hair_color = "000000" //Facial hair color
|
|
var/grad_style //Hair gradient style
|
|
var/grad_color = "FFFFFF" //Hair gradient color
|
|
var/skin_tone = "caucasian1" //Skin color
|
|
var/use_custom_skin_tone = FALSE
|
|
var/left_eye_color = "000000" //Eye color
|
|
var/right_eye_color = "000000"
|
|
var/eye_type = DEFAULT_EYES_TYPE //Eye type
|
|
var/split_eye_colors = FALSE
|
|
var/datum/species/pref_species = new /datum/species/human() //Mutant race
|
|
var/list/features = list(
|
|
"mcolor" = "FFFFFF",
|
|
"mcolor2" = "FFFFFF",
|
|
"mcolor3" = "FFFFFF",
|
|
"tail_lizard" = "Smooth",
|
|
"tail_human" = "None",
|
|
"snout" = "Round",
|
|
"horns" = "None",
|
|
"horns_color" = "85615a",
|
|
"ears" = "None",
|
|
"wings" = "None",
|
|
"wings_color" = "FFF",
|
|
"frills" = "None",
|
|
"deco_wings" = "None",
|
|
"spines" = "None",
|
|
"legs" = "Plantigrade",
|
|
"insect_wings" = "Plain",
|
|
"insect_fluff" = "None",
|
|
"insect_markings" = "None",
|
|
"arachnid_legs" = "Plain",
|
|
"arachnid_spinneret" = "Plain",
|
|
"arachnid_mandibles" = "Plain",
|
|
"mam_body_markings" = list(),
|
|
"mam_ears" = "None",
|
|
"mam_snouts" = "None",
|
|
"mam_tail" = "None",
|
|
"mam_tail_animated" = "None",
|
|
"xenodorsal" = "Standard",
|
|
"xenohead" = "Standard",
|
|
"xenotail" = "Xenomorph Tail",
|
|
"taur" = "None",
|
|
"genitals_use_skintone" = FALSE,
|
|
"has_cock" = FALSE,
|
|
"cock_shape" = DEF_COCK_SHAPE,
|
|
"cock_length" = COCK_SIZE_DEF,
|
|
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
|
|
"cock_color" = "ffffff",
|
|
"cock_taur" = FALSE,
|
|
"has_balls" = FALSE,
|
|
"balls_color" = "ffffff",
|
|
"balls_shape" = DEF_BALLS_SHAPE,
|
|
"balls_size" = BALLS_SIZE_DEF,
|
|
"balls_cum_rate" = CUM_RATE,
|
|
"balls_cum_mult" = CUM_RATE_MULT,
|
|
"balls_fluid" = /datum/reagent/consumable/semen,
|
|
"balls_efficiency" = CUM_EFFICIENCY,
|
|
"has_breasts" = FALSE,
|
|
"breasts_color" = "ffffff",
|
|
"breasts_size" = BREASTS_SIZE_DEF,
|
|
"breasts_shape" = DEF_BREASTS_SHAPE,
|
|
"breasts_fluid" = /datum/reagent/consumable/milk,
|
|
"breasts_producing" = FALSE,
|
|
"has_vag" = FALSE,
|
|
"vag_shape" = DEF_VAGINA_SHAPE,
|
|
"vag_color" = "ffffff",
|
|
"has_womb" = FALSE,
|
|
"womb_fluid" = /datum/reagent/consumable/semen/femcum,
|
|
"has_butt" = FALSE,
|
|
"butt_color" = "ffffff",
|
|
"butt_size" = BUTT_SIZE_DEF,
|
|
"has_belly" = FALSE,
|
|
"has_anus" = FALSE,
|
|
"anus_color" = "ffffff",
|
|
"anus_shape" = DEF_ANUS_SHAPE,
|
|
"belly_color" = "ffffff",
|
|
"belly_size" = BELLY_SIZE_DEF,
|
|
"balls_visibility" = GEN_VISIBLE_NO_UNDIES,
|
|
"breasts_visibility"= GEN_VISIBLE_NO_UNDIES,
|
|
"cock_visibility" = GEN_VISIBLE_NO_UNDIES,
|
|
"vag_visibility" = GEN_VISIBLE_NO_UNDIES,
|
|
"butt_visibility" = GEN_VISIBLE_NO_UNDIES,
|
|
"belly_visibility" = GEN_VISIBLE_NO_UNDIES,
|
|
"anus_visibility" = GEN_VISIBLE_NO_UNDIES,
|
|
"breasts_accessible" = FALSE,
|
|
"cock_accessible" = FALSE,
|
|
"balls_accessible" = FALSE,
|
|
"vag_accessible" = FALSE,
|
|
"butt_accessible" = FALSE,
|
|
"anus_accessible" = FALSE,
|
|
"belly_accessible" = FALSE,
|
|
"cock_stuffing" = FALSE,
|
|
"balls_stuffing" = FALSE,
|
|
"vag_stuffing" = FALSE,
|
|
"breasts_stuffing" = FALSE,
|
|
"butt_stuffing" = FALSE,
|
|
"belly_stuffing" = FALSE,
|
|
"anus_stuffing" = FALSE,
|
|
"inert_eggs" = FALSE,
|
|
"ipc_screen" = "Sunburst",
|
|
"ipc_antenna" = "None",
|
|
"flavor_text" = "",
|
|
"naked_flavor_text" = "", //SPLURT edit
|
|
"silicon_flavor_text" = "",
|
|
"ooc_notes" = "",
|
|
"meat_type" = "Mammalian",
|
|
"body_model" = MALE,
|
|
"body_size" = RESIZE_DEFAULT_SIZE,
|
|
"color_scheme" = OLD_CHARACTER_COLORING,
|
|
|
|
"neckfire" = FALSE,
|
|
"neckfire_color" = "ffffff"
|
|
)
|
|
|
|
|
|
var/custom_speech_verb = "default" //if your say_mod is to be something other than your races
|
|
var/custom_tongue = "default" //if your tongue is to be something other than your races
|
|
var/list/language = list() //additional language your character has
|
|
var/modified_limbs = list() //prosthetic/amputated limbs
|
|
var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded
|
|
|
|
// Vocal bark prefs
|
|
var/bark_id = "mutedc3"
|
|
var/bark_speed = 4
|
|
var/bark_pitch = 1
|
|
var/bark_variance = 0.2
|
|
COOLDOWN_DECLARE(bark_previewing)
|
|
|
|
/// Security record note section
|
|
var/security_records
|
|
/// Medical record note section
|
|
var/medical_records
|
|
|
|
var/list/custom_names = list()
|
|
var/preferred_ai_core_display = "Blue"
|
|
var/prefered_security_department = SEC_DEPT_RANDOM
|
|
var/custom_species = null
|
|
|
|
//Quirk list
|
|
var/list/all_quirks = list()
|
|
|
|
//Quirk category currently selected
|
|
var/quirk_category = QUIRK_POSITIVE // defaults to positive, the first tab!
|
|
|
|
//Job preferences 2.0 - indexed by job title , no key or value implies never
|
|
var/list/job_preferences = list()
|
|
|
|
// Want randomjob if preferences already filled - Donkie
|
|
var/joblessrole = BERANDOMJOB //defaults to 1 for fewer assistants
|
|
|
|
// 0 = character settings, 1 = game preferences
|
|
var/current_tab = SETTINGS_TAB
|
|
|
|
var/unlock_content = 0
|
|
|
|
var/list/ignoring = list()
|
|
|
|
var/clientfps = 60
|
|
|
|
var/parallax = PARALLAX_INSANE
|
|
|
|
var/ambientocclusion = TRUE
|
|
///Should we automatically fit the viewport?
|
|
var/auto_fit_viewport = FALSE
|
|
///Should we be in the widescreen mode set by the config?
|
|
var/widescreenpref = TRUE
|
|
///Strip menu style
|
|
var/long_strip_menu = TRUE
|
|
///What size should pixels be displayed as? 0 is strech to fit
|
|
var/pixel_size = 0
|
|
///What scaling method should we use?
|
|
var/scaling_method = "normal"
|
|
var/uplink_spawn_loc = UPLINK_PDA
|
|
///The playtime_reward_cloak variable can be set to TRUE from the prefs menu only once the user has gained over 5K playtime hours. If true, it allows the user to get a cool looking roundstart cloak.
|
|
var/playtime_reward_cloak = FALSE
|
|
|
|
var/hud_toggle_flash = TRUE
|
|
var/hud_toggle_color = "#ffffff"
|
|
|
|
var/list/exp = list()
|
|
var/list/menuoptions
|
|
|
|
var/action_buttons_screen_locs = list()
|
|
|
|
//bad stuff
|
|
var/vore_flags = 0
|
|
var/list/belly_prefs = list()
|
|
var/vore_taste = "nothing in particular"
|
|
var/vore_smell = null
|
|
var/toggleeatingnoise = TRUE
|
|
var/toggledigestionnoise = TRUE
|
|
var/hound_sleeper = TRUE
|
|
var/cit_toggles = TOGGLES_CITADEL
|
|
|
|
//backgrounds
|
|
var/mutable_appearance/character_background
|
|
var/icon/bgstate = "steel"
|
|
var/list/bgstate_options = list("000", "midgrey", "FFF", "white", "steel", "techmaint", "dark", "plating", "reinforced")
|
|
|
|
var/show_mismatched_markings = FALSE //determines whether or not the markings lists should show markings that don't match the currently selected species. Intentionally left unsaved.
|
|
|
|
var/character_settings_tab = GENERAL_CHAR_TAB
|
|
var/preferences_tab = GAME_PREFS_TAB
|
|
var/preview_pref = PREVIEW_PREF_JOB
|
|
|
|
var/no_tetris_storage = FALSE
|
|
|
|
///loadout stuff
|
|
var/gear_points = 10
|
|
var/list/gear_categories
|
|
var/list/loadout_data = list()
|
|
var/list/unlockable_loadout_data = list()
|
|
var/loadout_slot = 1 //goes from 1 to MAXIMUM_LOADOUT_SAVES
|
|
var/gear_category
|
|
var/gear_subcategory
|
|
|
|
var/screenshake = 100
|
|
var/damagescreenshake = 2
|
|
var/recoil_screenshake = 100
|
|
var/arousable = TRUE
|
|
var/autostand = TRUE
|
|
var/auto_ooc = FALSE
|
|
|
|
///This var stores the amount of points the owner will get for making it out alive.
|
|
var/hardcore_survival_score = 0
|
|
|
|
///Someone thought we were nice! We get a little heart in OOC until we join the server past the below time (we can keep it until the end of the round otherwise)
|
|
var/hearted
|
|
///If we have a hearted commendations, we honor it every time the player loads preferences until this time has been passed
|
|
var/hearted_until
|
|
/// If we have persistent scars enabled
|
|
var/persistent_scars = TRUE
|
|
///If we want to broadcast deadchat connect/disconnect messages
|
|
var/broadcast_login_logout = TRUE
|
|
///What outfit typepaths we've favorited in the SelectEquipment menu
|
|
var/list/favorite_outfits = list()
|
|
/// We have 5 slots for persistent scars, if enabled we pick a random one to load (empty by default) and scars at the end of the shift if we survived as our original person
|
|
var/list/scars_list = list("1" = "", "2" = "", "3" = "", "4" = "", "5" = "")
|
|
/// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)]
|
|
var/scars_index = 1
|
|
|
|
var/hide_ckey = FALSE //pref for hiding if your ckey shows round-end or not
|
|
|
|
var/list/tcg_cards = list()
|
|
var/list/tcg_decks = list()
|
|
|
|
//SPLURT EDIT - gregnancy
|
|
/// Does john spaceman's cum actually impregnate people?
|
|
var/virility = 0
|
|
/// Can john spaceman get gregnant if all conditions are right? (has a womb and is not on contraceptives)
|
|
var/fertility = 0
|
|
/// Does john spaceman look like a gluttonous slob if he pregent?
|
|
var/pregnancy_inflation = FALSE
|
|
/// Self explanitory
|
|
var/pregnancy_breast_growth = FALSE
|
|
|
|
var/egg_shell = "chicken"
|
|
//SPLURT END
|
|
|
|
var/loadout_errors = 0
|
|
|
|
var/pref_queue
|
|
var/char_queue
|
|
|
|
var/silicon_lawset
|
|
|
|
/datum/preferences/New(client/C)
|
|
parent = C
|
|
|
|
for(var/custom_name_id in GLOB.preferences_custom_names)
|
|
custom_names[custom_name_id] = get_default_name(custom_name_id)
|
|
|
|
UI_style = GLOB.available_ui_styles[1]
|
|
if(istype(C))
|
|
if(!IsGuestKey(C.key))
|
|
load_path(C.ckey)
|
|
unlock_content = C.IsByondMember()
|
|
if(unlock_content)
|
|
max_save_slots += 8 //SPLURT EDIT
|
|
var/loaded_preferences_successfully = load_preferences()
|
|
if(loaded_preferences_successfully)
|
|
if(load_character())
|
|
return
|
|
//we couldn't load character data so just randomize the character appearance + name
|
|
random_character() //let's create a random character then - rather than a fat, bald and naked man.
|
|
key_bindings = deepCopyList(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys
|
|
C?.ensure_keys_set(src)
|
|
real_name = pref_species.random_name(gender,1)
|
|
if(!loaded_preferences_successfully)
|
|
save_preferences()
|
|
save_character() //let's save this new random character so it doesn't keep generating new ones.
|
|
menuoptions = list()
|
|
return
|
|
|
|
#define APPEARANCE_CATEGORY_COLUMN "<td valign='top' width='17%'>"
|
|
#define MAX_MUTANT_ROWS 5
|
|
|
|
/datum/preferences/proc/ShowChoices(mob/user)
|
|
if(!user || !user.client)
|
|
return
|
|
update_preview_icon(current_tab)
|
|
var/list/dat = list("<center>")
|
|
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=[SETTINGS_TAB]' [current_tab == SETTINGS_TAB ? "class='linkOn'" : ""]>Character Settings</a>"
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=[PREFERENCES_TAB]' [current_tab == PREFERENCES_TAB ? "class='linkOn'" : ""]>Preferences</a>"
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=[KEYBINDINGS_TAB]' [current_tab == KEYBINDINGS_TAB ? "class='linkOn'" : ""]>Keybindings</a>"
|
|
|
|
if(!path)
|
|
dat += "<div class='notice'>Please create an account to save your preferences</div>"
|
|
|
|
dat += "</center>"
|
|
|
|
dat += "<HR>"
|
|
|
|
switch(current_tab)
|
|
if(SETTINGS_TAB) // Character Settings#
|
|
if(path)
|
|
var/savefile/S = new /savefile(path)
|
|
if(S)
|
|
dat += "<center>"
|
|
var/name
|
|
var/unspaced_slots = 0
|
|
for(var/i=1, i<=max_save_slots, i++)
|
|
unspaced_slots++
|
|
if(unspaced_slots > 4)
|
|
dat += "<br>"
|
|
unspaced_slots = 0
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
if(!name)
|
|
name = "Character[i]"
|
|
dat += "<a style='white-space:nowrap;' href='?_src_=prefs;preference=changeslot;num=[i];' [i == default_slot ? "class='linkOn'" : ""]>[name]</a> "
|
|
dat += "</center>"
|
|
|
|
dat += "<HR>"
|
|
|
|
dat += "<center>"
|
|
var/savefile/client_file = new(user.client.Import())
|
|
var/savefile_name
|
|
if(istype(client_file, /savefile))
|
|
if(!client_file["deleted"] || savefile_needs_update(client_file) != -2)
|
|
client_file["real_name"] >> savefile_name
|
|
dat += "Local storage: [savefile_name ? savefile_name : "Empty"]"
|
|
dat += "<br />"
|
|
dat += "<a href='?_src_=prefs;preference=export_slot'>Export current slot</a>"
|
|
dat += "<a [savefile_name ? "href='?_src_=prefs;preference=import_slot' style='white-space:normal;'" : "class='linkOff'"]>Import into current slot</a>"
|
|
dat += "<a href='?_src_=prefs;preference=delete_local_copy' style='white-space:normal;background:#eb2e2e;'>Delete locally saved character</a>"
|
|
dat += "<br />"
|
|
dat += "<a href='?_src_=prefs;preference=give_slot' [offer ? "style='white-space:normal;background:#eb2e2e;'" : ""]>[offer ? "Cancel offer" : "Offer slot"]</a>"
|
|
dat += "<a href='?_src_=prefs;preference=retrieve_slot'>Retrieve offered character</a>"
|
|
if(offer)
|
|
dat += "<br />"
|
|
dat += "The redemption code is <b>[offer.redemption_code]</b>"
|
|
dat += "<br />"
|
|
dat += "The offer will automatically be cancelled if there is an error, or if someone takes it"
|
|
|
|
dat += "</center>"
|
|
|
|
dat += "<HR>"
|
|
|
|
dat += "<center>"
|
|
dat += "<a href='?_src_=prefs;preference=character_tab;tab=[GENERAL_CHAR_TAB]' [character_settings_tab == GENERAL_CHAR_TAB ? "class='linkOn'" : ""]>General</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_tab;tab=[BACKGROUND_CHAR_TAB]' [character_settings_tab == BACKGROUND_CHAR_TAB ? "class='linkOn'" : ""]>Background</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_tab;tab=[APPEARANCE_CHAR_TAB]' [character_settings_tab == APPEARANCE_CHAR_TAB ? "class='linkOn'" : ""]>Appearance</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_tab;tab=[MARKINGS_CHAR_TAB]' [character_settings_tab == MARKINGS_CHAR_TAB ? "class='linkOn'" : ""]>Markings</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_tab;tab=[SPEECH_CHAR_TAB]' [character_settings_tab == SPEECH_CHAR_TAB ? "class='linkOn'" : ""]>Speech</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_tab;tab=[LOADOUT_CHAR_TAB]' [character_settings_tab == LOADOUT_CHAR_TAB ? "class='linkOn'" : ""]>Loadout</a>" //If you change the index of this tab, change all the logic regarding tab
|
|
dat += "</center>"
|
|
|
|
dat += "<HR>"
|
|
dat += "<center>"
|
|
dat += "<table width='100%'>"
|
|
dat += "<tr>"
|
|
dat += "<td width=35% style=\"line-height:5px\">"
|
|
dat += "<center><b>Preview:</b></center><br>"
|
|
dat += "<center style=\"line-height:20px\">"
|
|
dat += "<a href='?_src_=prefs;preference=character_preview;tab=[PREVIEW_PREF_JOB]' [preview_pref == PREVIEW_PREF_JOB ? "class='linkOn'" : ""]>[PREVIEW_PREF_JOB]</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_preview;tab=[PREVIEW_PREF_LOADOUT]' [preview_pref == PREVIEW_PREF_LOADOUT ? "class='linkOn'" : ""]>[PREVIEW_PREF_LOADOUT]</a>"
|
|
dat += "<a href='?_src_=prefs;preference=character_preview;tab=[PREVIEW_PREF_NAKED]' [preview_pref == PREVIEW_PREF_NAKED ? "class='linkOn'" : ""]>[PREVIEW_PREF_NAKED]</a>"
|
|
dat += "<br>"
|
|
dat += "<a href='?_src_=prefs;preference=character_preview;tab=[PREVIEW_PREF_NAKED_AROUSED]' [preview_pref == PREVIEW_PREF_NAKED_AROUSED ? "class='linkOn'" : ""]>[PREVIEW_PREF_NAKED_AROUSED]</a>"
|
|
dat += "</center>"
|
|
dat += "</td>"
|
|
if(character_settings_tab == LOADOUT_CHAR_TAB) //if loadout
|
|
//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)
|
|
loadout_errors = 0
|
|
for(var/loadout_item in chosen_gear)
|
|
var/loadout_item_path = loadout_item[LOADOUT_ITEM]
|
|
if(!loadout_item_path)
|
|
loadout_errors++
|
|
continue
|
|
var/datum/gear/loadout_gear = text2path(loadout_item_path)
|
|
if(!loadout_gear)
|
|
loadout_errors++
|
|
continue
|
|
gear_points -= initial(loadout_gear.cost)
|
|
else
|
|
chosen_gear = list()
|
|
|
|
dat += "<td width=65% style=\"line-height:10px\">"
|
|
dat += "<center><b><font color='[gear_points == 0 ? "#E62100" : "#CCDDFF"]'>[gear_points]</font> loadout point[gear_points == 1 ? "" : "s"] remaining</center><br>"
|
|
dat += "<center><a href='?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a></b></center>"
|
|
dat += "</td>"
|
|
else
|
|
dat += "<td width=35% style=\"line-height:10px\">"
|
|
dat += "<center><b>Mismatched parts:</b></center><br>"
|
|
dat += "<center><a href='?_src_=prefs;preference=mismatched_markings;task=input'>[(show_mismatched_markings) ? "Enabled" : "Disabled"]</a></center>"
|
|
dat += "</td>"
|
|
|
|
dat += "<td width=30% style=\"line-height:10px\">"
|
|
dat += "<center><b>Advanced colors:</b></center><br>"
|
|
dat += "<center><a href='?_src_=prefs;preference=color_scheme;task=input'>[(features["color_scheme"] == ADVANCED_CHARACTER_COLORING) ? "Enabled" : "Disabled"]</a></center>"
|
|
dat += "</td>"
|
|
|
|
dat += "</tr>"
|
|
dat += "</table>"
|
|
dat += "</center>"
|
|
dat += "<HR>"
|
|
switch(character_settings_tab)
|
|
//General
|
|
if(GENERAL_CHAR_TAB)
|
|
dat += "<center><h2>Occupation Choices</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
|
|
if(CONFIG_GET(flag/roundstart_traits))
|
|
dat += "<center><h2>Quirk Setup</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Quirks</a><br></center>"
|
|
dat += "<center><b>Current Quirks:</b> [english_list(all_quirks, "None")]</center>"
|
|
dat += "<h2>Identity</h2>"
|
|
dat += "<table width='100%'><tr><td width='30%' valign='top'>"
|
|
if(jobban_isbanned(user, "appearance"))
|
|
dat += "<b>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.</b><br>"
|
|
|
|
dat += "<b>[nameless ? "Default designation" : "Name"]:</b><br>"
|
|
dat += "<a href='?_src_=prefs;preference=name;task=input'>[real_name]</a><BR>"
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=name;task=random'>Random Name</a><br>"
|
|
dat += "<a href='?_src_=prefs;preference=nameless'>Be nameless: [nameless ? "Yes" : "No"]</a><BR>"
|
|
dat += "<b>Always Random Name:</b><a style='display:block;width:30px' href='?_src_=prefs;preference=name'>[be_random_name ? "Yes" : "No"]</a><BR>"
|
|
|
|
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender;task=input'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
|
|
dat += "<b>Age:</b> <a style='display:block;width:30px' href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
|
|
dat += "<a href='?_src_=prefs;preference=hide_ckey;task=input'><b>Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]</b></a><br>"
|
|
dat += "</td>"
|
|
|
|
dat += "<td valign='top'>"
|
|
dat += "<b>Special Names:</b><BR>"
|
|
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 += "<br>"
|
|
dat += "<a href ='?_src_=prefs;preference=[custom_name_id];task=input'><b>[namedata["pref_name"]]:</b> [custom_names[custom_name_id]]</a> "
|
|
dat += "<br><br>"
|
|
|
|
dat += "<b>Custom job preferences:</b><BR>"
|
|
dat += "<a href='?_src_=prefs;preference=ai_core_icon;task=input'><b>Preferred AI Core Display:</b> [preferred_ai_core_display]</a><br>"
|
|
dat += "<a href='?_src_=prefs;preference=sec_dept;task=input'><b>Preferred Security Department:</b> [prefered_security_department]</a><BR>"
|
|
|
|
dat += "<h2>Silicon preferences</h2>"
|
|
if(!CONFIG_GET(flag/allow_silicon_choosing_laws))
|
|
dat += "<i>The server has disabled choosing your own laws, you can still choose and save, but it won't do anything in-game.</i><br>"
|
|
dat += "<b>Starting lawset:</b> <a href='?_src_=prefs;task=input;preference=silicon_lawset'>[silicon_lawset ? silicon_lawset : "Server default"]</a><br>"
|
|
|
|
if(silicon_lawset)
|
|
var/list/config_laws = CONFIG_GET(keyed_list/choosable_laws)
|
|
var/datum/ai_laws/law_datum = GLOB.all_law_datums[config_laws[silicon_lawset]]
|
|
if(law_datum)
|
|
dat += "<i>[law_datum]</i><br>"
|
|
dat += english_list(law_datum.get_law_list(TRUE),
|
|
"I was unable to find the laws for your lawset, sorry <font style='translate: rotate(90deg)'>:(</font>",
|
|
"<br>", "<br>")
|
|
|
|
dat += "</td></tr></table>"
|
|
//Character background
|
|
if(BACKGROUND_CHAR_TAB)
|
|
dat += "<table width='100%'><tr><td width='30%' valign='top'>"
|
|
|
|
dat += "<h2>Flavor Text</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Examine Text</b></a><br>"
|
|
if(length(features["flavor_text"]) <= MAX_FLAVOR_PREVIEW_LEN)
|
|
if(!length(features["flavor_text"]))
|
|
dat += "\[...\]"
|
|
else
|
|
dat += "[features["flavor_text"]]"
|
|
else
|
|
dat += "[TextPreview(features["flavor_text"])]..."
|
|
//SPLURT edit - naked flavor text
|
|
dat += "<h2>Naked Flavor Text</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=naked_flavor_text;task=input'><b>Set Naked Examine Text</b></a><br>"
|
|
if(length(features["naked_flavor_text"]) <= 40)
|
|
if(!length(features["naked_flavor_text"]))
|
|
dat += "\[...\]<BR>"
|
|
else
|
|
dat += "[html_encode(features["naked_flavor_text"])]<BR>"
|
|
else
|
|
dat += "[TextPreview(html_encode(features["naked_flavor_text"]))]...<BR>"
|
|
//SPLURT edit end
|
|
dat += "<h2>Silicon Flavor Text</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=silicon_flavor_text;task=input'><b>Set Silicon Examine Text</b></a><br>"
|
|
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 += "<h2>OOC notes</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=ooc_notes;task=input'><b>Set OOC notes</b></a><br>"
|
|
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 += "<h2>Headshot Image</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=headshot'><b>Set Headshot Image</b></a><br>"
|
|
if(features["headshot_link"])
|
|
dat += "<img src='[features["headshot_link"]]' width='160px' height='120px'>"
|
|
dat += "<br><br>"
|
|
//SPLURT EDIT END
|
|
dat += "</td>"
|
|
|
|
dat += "<td valign='top'>"
|
|
dat += "<h2>Records</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=security_records;task=input'><b>Security Records</b></a><br>"
|
|
if(length_char(security_records) <= 40)
|
|
if(!length(security_records))
|
|
dat += "\[...\]"
|
|
else
|
|
dat += "[security_records]"
|
|
else
|
|
dat += "[TextPreview(security_records)]..."
|
|
|
|
dat += "<br><a href='?_src_=prefs;preference=medical_records;task=input'><b>Medical Records</b></a><br>"
|
|
if(length_char(medical_records) <= 40)
|
|
if(!length(medical_records))
|
|
dat += "\[...\]"
|
|
else
|
|
dat += "[medical_records]"
|
|
else
|
|
dat += "[TextPreview(medical_records)]..."
|
|
dat += "</td></tr></table>"
|
|
//Character Appearance
|
|
if(APPEARANCE_CHAR_TAB)
|
|
dat += "<table><tr><td width='20%' height='300px' valign='top'>"
|
|
|
|
dat += "<h2>Body</h2>"
|
|
dat += "<b>Gender:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=gender;task=input'>[gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]</a><BR>"
|
|
if(pref_species.sexes)
|
|
dat += "<b>Body Model:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=body_model'>[features["body_model"] == MALE ? "Masculine" : "Feminine"]</a><BR>"
|
|
dat += "<b>Limb Modification:</b><BR>"
|
|
dat += "<a href='?_src_=prefs;preference=modify_limbs;task=input'>Modify Limbs</a><BR>"
|
|
for(var/modification in modified_limbs)
|
|
if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC)
|
|
dat += "<b>[modification]: [modified_limbs[modification][2]]</b><BR>"
|
|
else
|
|
dat += "<b>[modification]: [modified_limbs[modification][1]]</b><BR>"
|
|
dat += "<BR>"
|
|
dat += "<b>Species:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=species;task=input'>[pref_species.name]</a><BR>"
|
|
dat += "<b>Custom Species Name:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=custom_species;task=input'>[custom_species ? custom_species : "None"]</a><BR>"
|
|
//Added by SPLURT (Custom Blood Color)
|
|
dat += "<b>Custom Blood Color:</b>"
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=toggle_custom_blood_color;task=input'>[custom_blood_color ? "Enabled" : "Disabled"]</a><BR>"
|
|
if(custom_blood_color)
|
|
dat += "<b>Blood Color:</b> <span style='border:1px solid #161616; background-color: [blood_color];'><font color='[color_hex2num(blood_color) < 200 ? "FFFFFF" : "000000"]'>[blood_color]</font></span> <a href='?_src_=prefs;preference=blood_color;task=input'>Change</a><BR>"
|
|
///
|
|
dat += "<b>Random Body:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=all;task=random'>Randomize!</A><BR>"
|
|
dat += "<b>Always Random Body:</b><a href='?_src_=prefs;preference=all'>[be_random_body ? "Yes" : "No"]</A><BR>"
|
|
dat += "<br><b>Cycle background:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=cycle_bg;task=input'>[bgstate]</a><BR>"
|
|
|
|
dat += "</td>"
|
|
|
|
var/use_skintones = pref_species.use_skintones
|
|
if(use_skintones)
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
|
|
dat += "<h3>Skin Tone</h3>"
|
|
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=s_tone;task=input'>[use_custom_skin_tone ? "custom: <span style='border:1px solid #161616; background-color: [skin_tone];'><font color='[color_hex2num(skin_tone) < 200 ? "FFFFFF" : "000000"]'>[skin_tone]</font></span>" : skin_tone]</a><BR>"
|
|
|
|
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 += "<h2>Body Colors</h2>"
|
|
|
|
dat += "<b>Primary Color:</b><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor"]];'><font color='[color_hex2num(features["mcolor"]) < 200 ? "FFFFFF" : "000000"]'>#[features["mcolor"]]</font></span> <a href='?_src_=prefs;preference=mutant_color;task=input'>Change</a><BR>"
|
|
|
|
dat += "<b>Secondary Color:</b><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor2"]];'><font color='[color_hex2num(features["mcolor2"]) < 200 ? "FFFFFF" : "000000"]'>#[features["mcolor2"]]</font></span> <a href='?_src_=prefs;preference=mutant_color2;task=input'>Change</a><BR>"
|
|
|
|
dat += "<b>Tertiary Color:</b><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor3"]];'><font color='[color_hex2num(features["mcolor3"]) < 200 ? "FFFFFF" : "000000"]'>#[features["mcolor3"]]</font></span> <a href='?_src_=prefs;preference=mutant_color3;task=input'>Change</a><BR>"
|
|
mutant_colors = TRUE
|
|
|
|
dat += "<b>Sprite Size:</b> <a href='?_src_=prefs;preference=body_size;task=input'>[features["body_size"]*100]%</a><br>"
|
|
dat += "<b>Scaled Appearance:</b> <a href='?_src_=prefs;preference=toggle_fuzzy;task=input'>[fuzzy ? "Fuzzy" : "Sharp"]</a><br>"
|
|
|
|
if(!(NOEYES in pref_species.species_traits))
|
|
dat += "<h3>Eye Type</h3>"
|
|
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=eye_type;task=input'>[eye_type]</a><BR>"
|
|
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 += "<h3>Heterochromia</h3>"
|
|
dat += "</b><a style='display:block;width:100px' href='?_src_=prefs;preference=toggle_split_eyes;task=input'>[split_eye_colors ? "Enabled" : "Disabled"]</a>"
|
|
if(!split_eye_colors)
|
|
dat += "<h3>Eye Color</h3>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'><font color='[color_hex2num(left_eye_color) < 200 ? "FFFFFF" : "000000"]'>#[left_eye_color]</font></span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a>"
|
|
else
|
|
dat += "<h3>Left Eye Color</h3>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[left_eye_color];'><font color='[color_hex2num(left_eye_color) < 200 ? "FFFFFF" : "000000"]'>#[left_eye_color]</font></span> <a href='?_src_=prefs;preference=eye_left;task=input'>Change</a>"
|
|
dat += "<h3>Right Eye Color</h3>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[right_eye_color];'><font color='[color_hex2num(right_eye_color) < 200 ? "FFFFFF" : "000000"]'>#[right_eye_color]</font></span> <a href='?_src_=prefs;preference=eye_right;task=input'>Change</a><BR>"
|
|
|
|
if(HAIR in pref_species.species_traits)
|
|
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
|
|
dat += "<h3>Hair Style</h3>"
|
|
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=hair_style;task=input'>[hair_style]</a>"
|
|
dat += "<a href='?_src_=prefs;preference=previous_hair_style;task=input'><</a> <a href='?_src_=prefs;preference=next_hair_style;task=input'>></a><BR>"
|
|
dat += "<span style='border:1px solid #161616; background-color: #[hair_color];'><font color='[color_hex2num(hair_color) < 200 ? "FFFFFF" : "000000"]'>#[hair_color]</font></span> <a href='?_src_=prefs;preference=hair;task=input'>Change</a><BR>"
|
|
|
|
dat += "<h3>Facial Hair Style</h3>"
|
|
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=facial_hair_style;task=input'>[facial_hair_style]</a>"
|
|
dat += "<a href='?_src_=prefs;preference=previous_facehair_style;task=input'><</a> <a href='?_src_=prefs;preference=next_facehair_style;task=input'>></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[facial_hair_color];'><font color='[color_hex2num(facial_hair_color) < 200 ? "FFFFFF" : "000000"]'>#[facial_hair_color]</font></span> <a href='?_src_=prefs;preference=facial;task=input'>Change</a><BR>"
|
|
|
|
dat += "<h3>Hair Gradient</h3>"
|
|
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=grad_style;task=input'>[grad_style]</a>"
|
|
dat += "<a href='?_src_=prefs;preference=previous_grad_style;task=input'><</a> <a href='?_src_=prefs;preference=next_grad_style;task=input'>></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[grad_color];'><font color='[color_hex2num(grad_color) < 200 ? "FFFFFF" : "000000"]'>#[grad_color]</font></span> <a href='?_src_=prefs;preference=grad_color;task=input'>Change</a><BR>"
|
|
|
|
dat += "</td>"
|
|
|
|
//Mutant stuff
|
|
var/mutant_category = 0
|
|
|
|
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 += "<h3>[GLOB.all_mutant_parts[mutant_part]]</h3>"
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=[mutant_part];task=input'>[features[mutant_part]]</a>"
|
|
var/color_type = GLOB.colored_mutant_parts[mutant_part] //if it can be coloured, show the appropriate button
|
|
if(color_type)
|
|
dat += "<span style='border:1px solid #161616; background-color: #[features[color_type]];'><font color='[color_hex2num(features[color_type]) < 200 ? "FFFFFF" : "000000"]'>#[features[color_type]]</font></span> <a href='?_src_=prefs;preference=[color_type];task=input'>Change</a><BR>"
|
|
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 += "<b>Primary Color</b><BR>"
|
|
dat += "<span style='border:1px solid #161616; background-color: #[features[primary_feature]];'><font color='[color_hex2num(features[primary_feature]) < 200 ? "FFFFFF" : "000000"]'>#[features[primary_feature]]</font></span> <a href='?_src_=prefs;preference=[primary_feature];task=input'>Change</a><BR>"
|
|
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 += "<b>Secondary Color</b><BR>"
|
|
dat += "<span style='border:1px solid #161616; background-color: #[features[secondary_feature]];'><font color='[color_hex2num(features[secondary_feature]) < 200 ? "FFFFFF" : "000000"]'>#[features[secondary_feature]]</font></span> <a href='?_src_=prefs;preference=[secondary_feature];task=input'>Change</a><BR>"
|
|
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 += "<b>Tertiary Color</b><BR>"
|
|
dat += "<span style='border:1px solid #161616; background-color: #[features[tertiary_feature]];'><font color='[color_hex2num(features[tertiary_feature]) < 200 ? "FFFFFF" : "000000"]'>#[features[tertiary_feature]]</font></span> <a href='?_src_=prefs;preference=[tertiary_feature];task=input'>Change</a><BR>"
|
|
|
|
mutant_category++
|
|
if(mutant_category >= MAX_MUTANT_ROWS)
|
|
dat += "</td>"
|
|
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
|
|
if(!mutant_category)
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
dat += "<h3>Body sprite</h3>"
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=bodysprite;task=input'>[chosen_limb_id]</a>"
|
|
|
|
if(mutant_category)
|
|
dat += "</td>"
|
|
mutant_category = 0
|
|
|
|
dat += "</tr></table>"
|
|
|
|
dat += "</td>"
|
|
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
|
dat += "<h2>Clothing & Equipment</h2>"
|
|
/*
|
|
dat += "<b>Underwear:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a>"
|
|
if(GLOB.underwear_list[underwear]?.has_color)
|
|
dat += "<b>Underwear Color:</b> <span style='border:1px solid #161616; background-color: #[undie_color];'><font color='[color_hex2num(undie_color) < 200 ? "FFFFFF" : "000000"]'>#[undie_color]</font></span> <a href='?_src_=prefs;preference=undie_color;task=input'>Change</a><BR>"
|
|
dat += "<b>Undershirt:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a>"
|
|
if(GLOB.undershirt_list[undershirt]?.has_color)
|
|
dat += "<b>Undershirt Color:</b> <span style='border:1px solid #161616; background-color: #[shirt_color];'><font color='[color_hex2num(shirt_color) < 200 ? "FFFFFF" : "000000"]'>#[shirt_color]</font></span> <a href='?_src_=prefs;preference=shirt_color;task=input'>Change</a><BR>"
|
|
dat += "<b>Socks:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=socks;task=input'>[socks]</a>"
|
|
if(GLOB.socks_list[socks]?.has_color)
|
|
dat += "<b>Socks Color:</b> <span style='border:1px solid #161616; background-color: #[socks_color];'><font color='[color_hex2num(socks_color) < 200 ? "FFFFFF" : "000000"]'>#[socks_color]</font></span> <a href='?_src_=prefs;preference=socks_color;task=input'>Change</a><BR>"
|
|
*/
|
|
dat += "<b>Backpack:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a>"
|
|
dat += "<b>Jumpsuit:</b><BR><a href ='?_src_=prefs;preference=suit;task=input'>[jumpsuit_style]</a><BR>"
|
|
if((HAS_FLESH in pref_species.species_traits) || (HAS_BONE in pref_species.species_traits))
|
|
dat += "<BR><b>Temporal Scarring:</b><BR><a href='?_src_=prefs;preference=persistent_scars'>[(persistent_scars) ? "Enabled" : "Disabled"]</A>"
|
|
dat += "<a href='?_src_=prefs;preference=clear_scars'>Clear scar slots</A>"
|
|
dat += "<b>Uplink Location:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a>"
|
|
|
|
dat += "<h2>Consent preferences</h2>"
|
|
dat += "ERP : <a href='?_src_=prefs;preference=erp_pref'>[erppref]</a><br>"
|
|
dat += "Non-Con : <a href='?_src_=prefs;preference=noncon_pref'>[nonconpref]</a><br>"
|
|
dat += "Vore : <a href='?_src_=prefs;preference=vore_pref'>[vorepref]</a><br>"
|
|
|
|
dat += "<h2>Lewd preferences</h2>"
|
|
dat += "<b>Lust tolerance:</b><a href='?_src_=prefs;preference=lust_tolerance;task=input'>[lust_tolerance]</a><br>"
|
|
dat += "<b>Sexual potency:</b><a href='?_src_=prefs;preference=sexual_potency;task=input'>[sexual_potency]</a>"
|
|
dat += "</td>"
|
|
|
|
//SPLURT EDIT BEGIN - gregnancy preferences
|
|
dat += "<td width='220px' height='300px' valign='top'>"
|
|
dat += "<h3>Pregnancy preferences</h3>"
|
|
dat += "<b>Chance of impregnation:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=virility;task=input'>[virility ? virility : "Disabled"]</a>"
|
|
dat += "<b>Chance of getting pregnant:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=fertility;task=input'>[fertility ? fertility : "Disabled"]</a>"
|
|
dat += "<b>Lay inert eggs:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=inert_eggs'>[features["inert_eggs"] == TRUE ? "Enabled" : "Disabled"]</a>"
|
|
if(fertility)
|
|
dat += "<b>Pregnancy inflation:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=pregnancy_inflation;task=input'>[pregnancy_inflation ? "Enabled" : "Disabled"]</a>"
|
|
dat += "<b>Pregnancy breast growth:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=pregnancy_breast_growth;task=input'>[pregnancy_breast_growth ? "Enabled" : "Disabled"]</a>"
|
|
if(fertility || features["inert_eggs"])
|
|
dat += "<b>Egg shell:</b><a style='display:block;width:100px' href ='?_src_=prefs;preference=egg_shell;task=input'>[egg_shell]</a>"
|
|
dat += "</td>"
|
|
//SPLURT EDIT END
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
|
|
if(NOGENITALS in pref_species.species_traits)
|
|
dat += "<b>Your species ([pref_species.name]) does not support genitals!</b><br>"
|
|
else
|
|
if(pref_species.use_skintones)
|
|
dat += "<b>Genitals use skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Yes" : "No"]</a>"
|
|
dat += "<h3>Penis</h3>"
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_cock"])
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Penis Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)</a><br>"
|
|
else
|
|
dat += "<b>Penis Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'><font color='[color_hex2num(features["cock_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["cock_color"]]</font></span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><br>"
|
|
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 += "<b>Penis Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]][tauric_shape ? " (Taur)" : ""]</a>"
|
|
dat += "<b>Penis Length:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a>"
|
|
dat += "<b>Max Length:</b><a style='display:block;width:120px' href='?_src_=prefs;preference=cock_max_length;task=input'>[features["cock_max_length"] ? features["cock_max_length"] : "Disabled"]</a>"
|
|
dat += "<b>Min Length:</b><a style='display:block;width:120px' href='?_src_=prefs;preference=cock_min_length;task=input'>[features["cock_min_length"] ? features["cock_min_length"] : "Disabled"]</a>"
|
|
dat += "<b>Diameter Ratio:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=cock_diameter_ratio;task=input'>[features["cock_diameter_ratio"]]</a>" //SPLURT Edit
|
|
dat += "<b>Penis Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=cock_visibility;task=input'>[features["cock_visibility"]]</a>"
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=cock_stuffing'>[features["cock_stuffing"] == TRUE ? "Yes" : "No"]</a>" //SPLURT Edit
|
|
dat += "<b>Penis Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=cock_accessible'>[features["cock_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += "<b>Has Testicles:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_balls"])
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Testicles Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)<br>"
|
|
else
|
|
dat += "<b>Testicles Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'><font color='[color_hex2num(features["balls_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["balls_color"]]</font></span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><br>"
|
|
dat += "<b>Testicles Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=balls_shape;task=input'>[features["balls_shape"]]</a>"
|
|
dat += "<b>Testicles Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=balls_visibility;task=input'>[features["balls_visibility"]]</a>"
|
|
//SPLURT Edit
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_stuffing'>[features["balls_stuffing"] == TRUE ? "Yes" : "No"]</a>"
|
|
dat += "<b>Max Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_max_size;task=input'>[features["balls_max_size"] ? features["balls_max_size"] : "Disabled"]</a>"
|
|
dat += "<b>Min Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=balls_min_size;task=input'>[features["balls_min_size"] ? features["balls_min_size"] : "Disabled"]</a>"
|
|
dat += "<b>Produces:</b>"
|
|
var/datum/reagent/balls_fluid = find_reagent_object_from_type(features["balls_fluid"])
|
|
if(balls_fluid && (balls_fluid in GLOB.genital_fluids_list))
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>[balls_fluid.name]</a>"
|
|
else
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=balls_fluid;task=input'>Nothing?</a>"
|
|
//SPLURT Edit end
|
|
dat += "</td>"
|
|
dat += "<b>Testicles Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=balls_accessible'>[features["balls_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
dat += "<h3>Vagina</h3>"
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_vag"])
|
|
dat += "<b>Vagina Type:</b> <a style='display:block;width:100px' href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a>"
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Vagina Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)<br>"
|
|
else
|
|
dat += "<b>Vagina Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'><font color='[color_hex2num(features["vag_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["vag_color"]]</font></span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><br>"
|
|
dat += "<b>Vagina Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=vag_visibility;task=input'>[features["vag_visibility"]]</a>"
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=vag_stuffing'>[features["vag_stuffing"] == TRUE ? "Yes" : "No"]</a>" //SPLURT Edit
|
|
dat += "<b>Vagina Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=vag_accessible'>[features["vag_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += "<b>Has Womb:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a>"
|
|
//SPLURT Edit
|
|
if(features["has_womb"] == TRUE)
|
|
dat += "<b>Produces:</b>"
|
|
var/datum/reagent/womb_fluid = find_reagent_object_from_type(features["womb_fluid"])
|
|
if(womb_fluid && (womb_fluid in GLOB.genital_fluids_list))
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=womb_fluid;task=input'>[womb_fluid.name]</a>"
|
|
else
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=womb_fluid;task=input'>Nothing?</a>"
|
|
//SPLURT Edit end
|
|
dat += "</td>"
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
dat += "<h3>Breasts</h3>"
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_breasts"])
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)<br>"
|
|
else
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'><font color='[color_hex2num(features["breasts_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["breasts_color"]]</font></span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><br>"
|
|
dat += "<b>Cup Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a>"
|
|
dat += "<b>Breasts Shape:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a>"
|
|
dat += "<b>Breasts Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=breasts_visibility;task=input'>[features["breasts_visibility"]]</a>"
|
|
dat += "<b>Breasts Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=breasts_accessible'>[features["breasts_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += "<b>Lactates:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_producing'>[features["breasts_producing"] == TRUE ? "Yes" : "No"]</a>"
|
|
//SPLURT Edit
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_stuffing'>[features["breasts_stuffing"] == TRUE ? "Yes" : "No"]</a>"
|
|
dat += "<b>Max Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_max_size;task=input'>[features["breasts_max_size"] ? features["breasts_max_size"] : "Disabled"]</a>"
|
|
dat += "<b>Min Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_min_size;task=input'>[features["breasts_min_size"] ? features["breasts_min_size"] : "Disabled"]</a>"
|
|
if(features["breasts_producing"] == TRUE)
|
|
dat += "<b>Produces:</b>"
|
|
var/datum/reagent/breasts_fluid = find_reagent_object_from_type(features["breasts_fluid"])
|
|
if(breasts_fluid && (breasts_fluid in GLOB.genital_fluids_list))
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>[breasts_fluid.name]</a>"
|
|
else
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=breasts_fluid;task=input'>Nothing?</a>"
|
|
//SPLURT Edit end
|
|
dat += "</td>"
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
dat += "<h3>Butt</h3>"
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_butt'>[features["has_butt"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_butt"])
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)<br>"
|
|
else
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["butt_color"]];'><font color='[color_hex2num(features["butt_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["butt_color"]]</font></span> <a href='?_src_=prefs;preference=butt_color;task=input'>Change</a><br>"
|
|
dat += "<b>Butt Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=butt_size;task=input'>[features["butt_size"]]</a>"
|
|
dat += "<b>Butt Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=butt_visibility;task=input'>[features["butt_visibility"]]</a>"
|
|
//SPLURT Edit
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=butt_stuffing'>[features["butt_stuffing"] == TRUE ? "Yes" : "No"]</a>"
|
|
dat += "<b>Max Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=butt_max_size;task=input'>[features["butt_max_size"] ? features["butt_max_size"] : "Disabled"]</a>"
|
|
dat += "<b>Min Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=butt_min_size;task=input'>[features["butt_min_size"] ? features["butt_min_size"] : "Disabled"]</a>"
|
|
dat += "<b>Butthole Sprite:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=has_anus'>[features["has_anus"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_anus"])
|
|
dat += "<b>Butthole Color:</b></a><BR>"
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)<br>"
|
|
else
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["anus_color"]];'><font color='[color_hex2num(features["anus_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["anus_color"]]</font></span> <a href='?_src_=prefs;preference=anus_color;task=input'>Change</a><br>"
|
|
dat += "<b>Butthole Shape:</b> <a style='display:block;width:120px' href='?_src_=prefs;preference=anus_shape;task=input'>[features["anus_shape"]]</a>"
|
|
dat += "<b>Butthole Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=anus_visibility;task=input'>[features["anus_visibility"]]</a>"
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=anus_stuffing'>[features["anus_stuffing"] == TRUE ? "Yes" : "No"]</a>"
|
|
|
|
dat += "<b>Butt Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=butt_accessible'>[features["butt_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += "<h3>Anus</h3>"
|
|
dat += "<b>Anus Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=anus_accessible'>[features["anus_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += "</td>"
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
dat += "<h3>Belly</h3>"
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_belly'>[features["has_belly"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_belly"])
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: [SKINTONE2HEX(skin_tone)];'><font color='[color_hex2num(SKINTONE2HEX(skin_tone)) < 200 ? "FFFFFF" : "000000"]'>[SKINTONE2HEX(skin_tone)]</font></span>(Skin tone overriding)<br>"
|
|
else
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["belly_color"]];'><font color='[color_hex2num(features["belly_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["belly_color"]]</font></span> <a href='?_src_=prefs;preference=belly_color;task=input'>Change</a><br>"
|
|
dat += "<b>Belly Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=belly_size;task=input'>[features["belly_size"]]</a>"
|
|
dat += "<b>Max Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=belly_max_size;task=input'>[features["belly_max_size"] ? features["belly_max_size"] : "Disabled" ]</a>"
|
|
dat += "<b>Min Size:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=belly_min_size;task=input'>[features["belly_min_size"] ? features["belly_min_size"] : "Disabled" ]</a>"
|
|
dat += "<b>Belly Visibility:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=belly_visibility;task=input'>[features["belly_visibility"]]</a>"
|
|
dat += "<b>Egg Stuffing:</b><a style='display:block;width:50px' href='?_src_=prefs;preference=belly_stuffing'>[features["belly_stuffing"] == TRUE ? "Yes" : "No"]</a>"
|
|
dat += "<b>Belly Always Accessible:</b><a style='display:block;width:100px' href='?_src_=prefs;preference=belly_accessible'>[features["belly_accessible"] ? "Yes" : "No"]</a>"
|
|
dat += "</td>"
|
|
if(all_quirks.Find("Dullahan"))
|
|
dat += APPEARANCE_CATEGORY_COLUMN
|
|
dat += "<h3>Neckfire</h3>"
|
|
dat += "<a style='display:block;width:50px' href='?_src_=prefs;preference=has_neckfire;task=input'>[features["neckfire"] ? "Yes" : "No"]</a>"
|
|
if(features["neckfire"])
|
|
dat += "<b>Color:</b></a><BR>"
|
|
dat += "<span style='border: 1px solid #161616; background-color: #[features["neckfire_color"]];'><font color='[color_hex2num(features["neckfire_color"]) < 200 ? "FFFFFF" : "000000"]'>#[features["neckfire_color"]]</font></span><a href='?_src_=prefs;preference=has_neckfire_color;task=input'>Change</a><br>"
|
|
|
|
dat += "</td>"
|
|
//SPLURT Edit end
|
|
dat += "</td>"
|
|
dat += "</tr></table>"
|
|
//Markings
|
|
if(MARKINGS_CHAR_TAB)
|
|
var/iterated_markings = 0
|
|
var/total_pages = 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 += "<center>"
|
|
dat += "<h3>[GLOB.all_mutant_parts[marking_type]]</h3>" // give it the appropriate title for the type of marking
|
|
dat += "<a href='?_src_=prefs;preference=marking_add;marking_type=[marking_type];task=input'>Add marking</a>"
|
|
dat += "</center>"
|
|
|
|
dat += "<table width=100%><tr>"
|
|
|
|
for(var/limb in GLOB.bodypart_values)
|
|
if(length(GLOB.bodypart_values) % 3 != 0)
|
|
continue
|
|
total_pages++
|
|
|
|
for(var/limb in GLOB.bodypart_values)
|
|
if(!iterated_markings)
|
|
dat += "<td width=[(100 / total_pages)]%>"
|
|
dat += "<h3><center>[limb]</center></h3>"
|
|
dat += "<table align='center'; width='100%'; height='100px'; style='background-color:#13171C'>"
|
|
dat += "<td width=4%><font size=2> </font></td>"
|
|
dat += "<td width=10%><font size=2> </font></td>"
|
|
dat += "<td width=6%><font size=2> </font></td>"
|
|
dat += "<td width=25%><font size=2> </font></td>"
|
|
dat += "<td width=40%><font size=2> </font></td>"
|
|
dat += "<td width=15%><font size=2> </font></td>"
|
|
dat += "</tr>"
|
|
|
|
// list out the current markings you have
|
|
if(length(features[marking_type]))
|
|
var/list/markings = features[marking_type]
|
|
if(!islist(markings))
|
|
// something went terribly wrong
|
|
markings = list()
|
|
|
|
for(var/list/marking_list in 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
|
|
if(actual_name != limb)
|
|
continue
|
|
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 += "<a href='?_src_=prefs;preference=marking_color_specific;marking_index=[marking_index];marking_type=[marking_type];number_color=[number_colors];task=input'><span style='border: 1px solid #161616; background-color: [marking_list[3][primary_index]];'><font color='[color_hex2num(marking_list[3][primary_index]) < 200 ? "FFFFFF" : "000000"]'>[marking_list[3][primary_index]]</font></span></a>"
|
|
// 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)
|
|
number_colors = 2
|
|
color_marking_dat += "<a href='?_src_=prefs;preference=marking_color_specific;marking_index=[marking_index];marking_type=[marking_type];number_color=[number_colors];task=input'><span style='border: 1px solid #161616; background-color: [marking_list[3][secondary_index]];'><font color='[color_hex2num(marking_list[3][secondary_index]) < 200 ? "FFFFFF" : "000000"]'>[marking_list[3][secondary_index]]</font></span></a>"
|
|
// if it has a third section, add it
|
|
if(matrixed_sections == MATRIX_ALL)
|
|
number_colors = 3
|
|
color_marking_dat += "<a href='?_src_=prefs;preference=marking_color_specific;marking_index=[marking_index];marking_type=[marking_type];number_color=[number_colors];task=input'><span style='border: 1px solid #161616; background-color: [marking_list[3][tertiary_index]];'><font color='[color_hex2num(marking_list[3][tertiary_index]) < 200 ? "FFFFFF" : "000000"]'>[marking_list[3][tertiary_index]]</font></span></a>"
|
|
dat += "<tr style='vertical-align:top;'>"
|
|
dat += "<td>[marking_index]</td>"
|
|
dat += "<td><a href='?_src_=prefs;preference=marking_up;task=input;marking_index=[marking_index];marking_type=[marking_type]'>˅</a></td>"
|
|
dat += "<td><a href='?_src_=prefs;preference=marking_down;task=input;marking_index=[marking_index];marking_type=[marking_type];'>˄</a></td>"
|
|
dat += "<td>[marking_list[2]]</td>"
|
|
dat += "<td>[color_marking_dat]</td>"
|
|
dat += "<td><a href='?_src_=prefs;preference=marking_remove;task=input;marking_index=[marking_index];marking_type=[marking_type]'>X</a></td>"
|
|
dat += "</tr>"
|
|
|
|
else
|
|
dat += "<tr style='vertical-align:top;'>"
|
|
dat += "<td> </td>"
|
|
dat += "<td> </td>"
|
|
dat += "<td> </td>"
|
|
dat += "<td> </td>"
|
|
dat += "<td> </td>"
|
|
dat += "<td> </td>"
|
|
dat += "</tr>"
|
|
|
|
dat += "</table>"
|
|
|
|
iterated_markings++
|
|
if(iterated_markings >= 3)
|
|
dat += "</td>"
|
|
iterated_markings = 0
|
|
dat += "</tr></table>"
|
|
|
|
if(SPEECH_CHAR_TAB)
|
|
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
|
dat += "<h2>Speech preferences</h2>"
|
|
dat += "<b>Custom Speech Verb:</b><BR>"
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=speech_verb;task=input'>[custom_speech_verb]</a><BR>"
|
|
dat += "<b>Custom Tongue:</b><BR>"
|
|
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=tongue;task=input'>[custom_tongue]</a><BR>"
|
|
//SANDSTORM EDIT - additional language + runechat color
|
|
dat += "<b>Additional Language</b><br>"
|
|
dat += "<a href='?_src_=prefs;preference=language;task=menu'>[english_list(language, "None")]</a></center><br>"
|
|
dat += "<b>Custom runechat color:</b> <a href='?_src_=prefs;preference=enable_personal_chat_color'>[enable_personal_chat_color ? "Enabled" : "Disabled"]</a><br> [enable_personal_chat_color ? "<span style='border: 1px solid #161616; background-color: [personal_chat_color];'><font color='[color_hex2num(personal_chat_color) < 200 ? "FFFFFF" : "000000"]'>[personal_chat_color]</font></span> <a href='?_src_=prefs;preference=personal_chat_color;task=input'>Change</a>" : ""]<br>"
|
|
dat += "</td>"
|
|
//END OF SANDSTORM EDIT
|
|
dat += "<td width='340px' height='300px' valign='top'>"
|
|
dat += "<h2>Vocal Bark preferences</h2>"
|
|
var/datum/bark/B = GLOB.bark_list[bark_id]
|
|
dat += "<b>Vocal Bark Sound:</b><BR>"
|
|
dat += "<a style='display:block;width:200px' href='?_src_=prefs;preference=barksound;task=input'>[B ? initial(B.name) : "INVALID"]</a><BR>"
|
|
dat += "<b>Vocal Bark Speed:</b> <a href='?_src_=prefs;preference=barkspeed;task=input'>[bark_speed]</a><BR>"
|
|
dat += "<b>Vocal Bark Pitch:</b> <a href='?_src_=prefs;preference=barkpitch;task=input'>[bark_pitch]</a><BR>"
|
|
dat += "<b>Vocal Bark Variance:</b> <a href='?_src_=prefs;preference=barkvary;task=input'>[bark_variance]</a><BR>"
|
|
dat += "<BR><a href='?_src_=prefs;preference=barkpreview'>Preview Bark</a><BR>"
|
|
dat += "</td>"
|
|
dat += "</tr></table>"
|
|
if(LOADOUT_CHAR_TAB)
|
|
dat += "<table align='center' width='100%'>"
|
|
dat += "<tr><td colspan=4><center><i style=\"color: grey;\">You can only choose one item per category, unless it's an item that spawns in your backpack or hands.</center></td></tr>"
|
|
dat += "<tr><td colspan=4><center><b>"
|
|
|
|
if(!length(GLOB.loadout_items))
|
|
dat += "<center>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 += " <span class='linkOn'>[(category == LOADOUT_CATEGORY_ERROR && loadout_errors) ? "[category] (<font color=\"red\">!</font>)" : category]</span> "
|
|
else
|
|
dat += " <a href='?_src_=prefs;preference=gear;select_category=[html_encode(category)]'>[(category == LOADOUT_CATEGORY_ERROR && loadout_errors) ? "[category] (<font color=\"red\">!</font>)" : category]</a> "
|
|
|
|
dat += "</b></center></td></tr>"
|
|
dat += "<tr><td colspan=4><hr></td></tr>"
|
|
|
|
dat += "<tr><td colspan=4><center><b>"
|
|
|
|
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 += " <span class='linkOn'>[subcategory]</span> "
|
|
else
|
|
dat += " <a href='?_src_=prefs;preference=gear;select_subcategory=[html_encode(subcategory)]'>[subcategory]</a> "
|
|
dat += "</b></center></td></tr>"
|
|
|
|
var/even = FALSE
|
|
if(gear_category != LOADOUT_CATEGORY_ERROR)
|
|
dat += "<table align='center'; width='100%'; height='100%'; style='background-color:#13171C'>"
|
|
dat += "<center>"
|
|
dat += "<tr width=10% style='vertical-align:top;'><td width=15%><b>Name</b></td>"
|
|
dat += "<td style='vertical-align:top'><b>Cost</b></td>"
|
|
dat += "<td width=10%><font size=2><b>Restrictions</b></font></td>"
|
|
dat += "<td width=80%><font size=2><b>Description</b></font></td></tr>"
|
|
dat += "</center>"
|
|
|
|
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/background_cl = "#23273C"
|
|
if(even)
|
|
background_cl = "#17191C"
|
|
even = !even
|
|
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 += "<BR><a href='?_src_=prefs;preference=gear;loadout_color_polychromic=1;loadout_gear_name=[html_encode(gear.name)];'>Color</a>"
|
|
for(var/loadout_color in loadout_item[LOADOUT_COLOR])
|
|
extra_loadout_data += "<span style='border: 1px solid #161616; background-color: [loadout_color];'><font color='[color_hex2num(loadout_color) < 200 ? "FFFFFF" : "000000"]'>[loadout_color]</font></span>"
|
|
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 += "<BR><a href='?_src_=prefs;preference=gear;loadout_color=1;loadout_gear_name=[html_encode(gear.name)];'>Color</a>"
|
|
extra_loadout_data += "<span style='border: 1px solid #161616; background-color: [loadout_color_non_poly];'><font color='[color_hex2num(loadout_color_non_poly) < 200 ? "FFFFFF" : "000000"]'>[loadout_color_non_poly]</font></span>"
|
|
extra_loadout_data += "<BR><a href='?_src_=prefs;preference=gear;loadout_color_HSV=1;loadout_gear_name=[html_encode(gear.name)];'>HSV Color</a>" // SPLURT EDIT
|
|
if(gear.loadout_flags & LOADOUT_CAN_NAME)
|
|
extra_loadout_data += "<BR><a href='?_src_=prefs;preference=gear;loadout_rename=1;loadout_gear_name=[html_encode(gear.name)];'>Name</a> [loadout_item[LOADOUT_CUSTOM_NAME] ? loadout_item[LOADOUT_CUSTOM_NAME] : "N/A"]"
|
|
if(gear.loadout_flags & LOADOUT_CAN_DESCRIPTION)
|
|
extra_loadout_data += "<BR><a href='?_src_=prefs;preference=gear;loadout_redescribe=1;loadout_gear_name=[html_encode(gear.name)];'>Description</a>"
|
|
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 += "<tr style='vertical-align:top; background-color: [background_cl];'><td width=15%><a [class_link]>[name]</a>[extra_loadout_data]</td>"
|
|
dat += "<td width = 5% style='vertical-align:top'>[gear.cost]</td><td>"
|
|
if(islist(gear.restricted_roles))
|
|
if(gear.restricted_roles.len)
|
|
if(gear.restricted_desc)
|
|
dat += "<font size=2>"
|
|
dat += gear.restricted_desc
|
|
dat += "</font>"
|
|
else
|
|
dat += "<font size=2>"
|
|
dat += gear.restricted_roles.Join(";")
|
|
dat += "</font>"
|
|
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 += "</td><td><font size=2><i>[loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description]</i></font></td></tr>"
|
|
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 += "</td><td><font size=2><i>[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]</i></font></td></tr>"
|
|
dat += "</table>"
|
|
else
|
|
dat += "<table align='center'; width='100%'; height='100%'; style='background-color:#13171C'>"
|
|
dat += "<center>"
|
|
dat += "<tr width=10% style='vertical-align:top;'><td width=15%><b>Item type</b></td>"
|
|
dat += "<td><font size=2><b>Data contained</b></font></td></tr>"
|
|
dat += "</center>"
|
|
var/list/sanitize_current_slot = loadout_data["SAVE_[loadout_slot]"]
|
|
for(var/list/entry in sanitize_current_slot)
|
|
var/test_item = entry["loadout_item"]
|
|
if(text2path(test_item))
|
|
continue
|
|
var/background_cl = "#23273C"
|
|
if(even)
|
|
background_cl = "#17191C"
|
|
even = !even
|
|
dat += "<tr style='vertical-align:top; background-color: [background_cl];'><td width=15%><a \
|
|
\"style='white-space:normal;' href='?_src_=prefs;preference=gear;clear_invalid_gear=[html_encode(test_item)];'\" \
|
|
>[test_item ? test_item : "no path!!?! Report to an admin!"]</a></td>"
|
|
dat += "<td style='vertical-align:top'>"
|
|
var/list/other_data = entry["loadout_item"] ? entry - "loadout_item" : entry
|
|
dat += json_encode(other_data)
|
|
dat += "</td></tr>"
|
|
dat += "</table>"
|
|
if(PREFERENCES_TAB) // Game Preferences
|
|
dat += "<center>"
|
|
dat += "<a href='?_src_=prefs;preference=preferences_tab;tab=[GAME_PREFS_TAB]' [preferences_tab == GAME_PREFS_TAB ? "class='linkOn'" : ""]>General</a>"
|
|
dat += "<a href='?_src_=prefs;preference=preferences_tab;tab=[OOC_PREFS_TAB]' [preferences_tab == OOC_PREFS_TAB ? "class='linkOn'" : ""]>OOC</a>"
|
|
dat += "<a href='?_src_=prefs;preference=preferences_tab;tab=[CONTENT_PREFS_TAB]' [preferences_tab == CONTENT_PREFS_TAB ? "class='linkOn'" : ""]>Content</a>"
|
|
dat += "</center>"
|
|
|
|
dat += "<HR>"
|
|
|
|
switch(preferences_tab)
|
|
if(GAME_PREFS_TAB)
|
|
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
|
dat += "<h2>General Settings</h2>"
|
|
dat += "<b>UI Style:</b> <a href='?_src_=prefs;task=input;preference=ui'>[UI_style]</a><br>"
|
|
dat += "<b>Outline:</b> <a href='?_src_=prefs;preference=outline_enabled'>[outline_enabled ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Outline Color:</b> [outline_color ? "<span style='border:1px solid #161616; background-color: [outline_color];'>" : "Theme-based (null)"]<font color='[color_hex2num(outline_color) < 200 ? "FFFFFF" : "000000"]'>[outline_color]</font></span> <a href='?_src_=prefs;preference=outline_color'>Change</a><BR>"
|
|
dat += "<b>Screentip:</b> <a href='?_src_=prefs;preference=screentip_pref'>[screentip_pref]</a><br>"
|
|
dat += "<b>Screentip Color:</b> <span style='border:1px solid #161616; background-color: [screentip_color];'><font color='[color_hex2num(screentip_color) < 200 ? "FFFFFF" : "000000"]'>[screentip_color]</font></span> <a href='?_src_=prefs;preference=screentip_color'>Change</a><BR>"
|
|
dat += "<font style='border-bottom:2px dotted white; cursor:help;'\
|
|
title=\"This is an accessibility preference, if disabled, fallbacks to only text which colorblind people can understand better\">\
|
|
<b>Screentip context with images:</b></font> <a href='?_src_=prefs;preference=screentip_images'>[screentip_images ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>tgui Monitors:</b> <a href='?_src_=prefs;preference=tgui_lock'>[(tgui_lock) ? "Primary" : "All"]</a><br>"
|
|
dat += "<b>tgui Style:</b> <a href='?_src_=prefs;preference=tgui_fancy'>[(tgui_fancy) ? "Fancy" : "No Frills"]</a><br>"
|
|
dat += "<b>Show Runechat Chat Bubbles:</b> <a href='?_src_=prefs;preference=chat_on_map'>[chat_on_map ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Runechat message char limit:</b> <a href='?_src_=prefs;preference=max_chat_length;task=input'>[max_chat_length]</a><br>"
|
|
dat += "<b>See Runechat for non-mobs:</b> <a href='?_src_=prefs;preference=see_chat_non_mob'>[see_chat_non_mob ? "Enabled" : "Disabled"]</a><br>"
|
|
//SANDSTORM CHANGES BEGIN
|
|
dat += "<b>See Runechat for emotes:</b> <a href='?_src_=prefs;preference=see_chat_emotes'>[see_chat_emotes ? "Enabled" : "Disabled"]</a><br>"
|
|
//SANDSTORM CHANGES END
|
|
dat += "<b>Shift view when pixelshifting:</b> <a href='?_src_=prefs;preference=view_pixelshift'>[view_pixelshift ? "Enabled" : "Disabled"]</a><br>" //SPLURT Edit
|
|
dat += "<br>"
|
|
dat += "<b>PDA Color:</b> <span style='border:1px solid #161616; background-color: [pda_color];'><font color='[color_hex2num(pda_color) < 200 ? "FFFFFF" : "000000"]'>[pda_color]</font></span> <a href='?_src_=prefs;preference=pda_color;task=input'>Change</a><BR>"
|
|
dat += "<b>PDA Style:</b> <a href='?_src_=prefs;task=input;preference=pda_style'>[pda_style]</a><br>"
|
|
dat += "<b>PDA Reskin:</b> <a href='?_src_=prefs;task=input;preference=pda_skin'>[pda_skin]</a><br>"
|
|
dat += "<br>"
|
|
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
|
|
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'>[(chat_toggles & CHAT_GHOSTRADIO) ? "All Messages":"No Messages"]</a><br>"
|
|
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'>[(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</a><br>"
|
|
dat += "<b>Ghost Whispers:</b> <a href='?_src_=prefs;preference=ghost_whispers'>[(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]</a><br>"
|
|
dat += "<b>Ghost PDA:</b> <a href='?_src_=prefs;preference=ghost_pda'>[(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]</a><br>"
|
|
|
|
dat += "</td>"
|
|
|
|
dat += "<td width='300px' height='300px' valign='top'>"
|
|
|
|
dat += "<h2>Special Role Settings</h2>"
|
|
|
|
if(jobban_isbanned(user, ROLE_SYNDICATE))
|
|
dat += "<font color=red><b>You are banned from antagonist roles.</b></font>"
|
|
src.be_special = list()
|
|
|
|
dat += "<b>DISABLE ALL ANTAGONISM</b> <a href='?_src_=prefs;preference=disable_antag'>[(toggles & NO_ANTAG) ? "YES" : "NO"]</a><br>"
|
|
|
|
for (var/i in GLOB.special_roles)
|
|
if(jobban_isbanned(user, i))
|
|
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;jobbancheck=[i]'>BANNED</a><br>"
|
|
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 += "<b>Be [capitalize(i)]:</b> <font color=red> \[IN [days_remaining] DAYS\]</font><br>"
|
|
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 += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[enabled_text]</a><br>"
|
|
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Enabled" : "Disabled"]</a><br>"
|
|
|
|
dat += "</td></tr></table>"
|
|
|
|
if(OOC_PREFS_TAB)
|
|
dat += "<table>"
|
|
dat += "<tr><td width='340px' height='300px' valign='top'>"
|
|
dat += "<h2>OOC Settings</h2>"
|
|
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(windowflashing) ? "Enabled":"Disabled"]</a><br>"
|
|
dat += "<br>"
|
|
dat += "<b>Play Admin MIDIs:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Enabled":"Disabled"]</a><br>"
|
|
dat += "<b>Play Lobby Music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Enabled":"Disabled"]</a><br>"
|
|
dat += "<b>See Pull Requests:</b> <a href='?_src_=prefs;preference=pull_requests'>[(chat_toggles & CHAT_PULLR) ? "Enabled":"Disabled"]</a><br>"
|
|
dat += "<br>"
|
|
if(user.client)
|
|
if(unlock_content)
|
|
dat += "<b>BYOND Membership Publicity:</b> <a href='?_src_=prefs;preference=publicity'>[(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]</a><br>"
|
|
if(unlock_content || check_rights_for(user.client, R_ADMIN))
|
|
dat += "<b>OOC Color:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : GLOB.normal_ooc_colour];'><font color='[color_hex2num(ooccolor ? ooccolor : GLOB.normal_ooc_colour) < 200 ? "FFFFFF" : "000000"]'>[ooccolor ? ooccolor : GLOB.normal_ooc_colour]</font></span> <a href='?_src_=prefs;preference=ooccolor;task=input'>Change</a><br>"
|
|
dat += "<b>Antag OOC Color:</b> <span style='border: 1px solid #161616; background-color: [aooccolor ? aooccolor : GLOB.normal_aooc_colour];'><font color='[color_hex2num(aooccolor ? aooccolor : GLOB.normal_aooc_colour) < 200 ? "FFFFFF" : "000000"]'>[aooccolor ? aooccolor : GLOB.normal_aooc_colour]</font></span> <a href='?_src_=prefs;preference=aooccolor;task=input'>Change</a><br>"
|
|
|
|
if(user.client.holder)
|
|
dat += "<h2>Admin Settings</h2>"
|
|
dat += "<b>Adminhelp Sounds:</b> <a href='?_src_=prefs;preference=hear_adminhelps'>[(toggles & SOUND_ADMINHELP)?"Enabled":"Disabled"]</a><br>"
|
|
dat += "<b>Announce Login:</b> <a href='?_src_=prefs;preference=announce_login'>[(toggles & ANNOUNCE_LOGIN)?"Enabled":"Disabled"]</a><br>"
|
|
dat += "<br>"
|
|
dat += "<b>Combo HUD Lighting:</b> <a href = '?_src_=prefs;preference=combohud_lighting'>[(toggles & COMBOHUD_LIGHTING)?"Full-bright":"No Change"]</a><br>"
|
|
dat += "<b>Use Modern Player Panel:</b> <a href='?_src_=prefs;preference=use_new_playerpanel'>[use_new_playerpanel ? "Yes" : "No"]</a><br>" //SPLURT Edit
|
|
|
|
//deadmin
|
|
dat += "<h2>Deadmin While Playing</h2>"
|
|
if(CONFIG_GET(flag/auto_deadmin_players))
|
|
dat += "<b>Always Deadmin:</b> FORCED</a><br>"
|
|
else
|
|
dat += "<b>Always Deadmin:</b> <a href = '?_src_=prefs;preference=toggle_deadmin_always'>[(deadmin & DEADMIN_ALWAYS)?"Enabled":"Disabled"]</a><br>"
|
|
if(!(deadmin & DEADMIN_ALWAYS))
|
|
dat += "<br>"
|
|
if(!CONFIG_GET(flag/auto_deadmin_antagonists))
|
|
dat += "<b>As Antag:</b> <a href = '?_src_=prefs;preference=toggle_deadmin_antag'>[(deadmin & DEADMIN_ANTAGONIST)?"Deadmin":"Keep Admin"]</a><br>"
|
|
else
|
|
dat += "<b>As Antag:</b> FORCED<br>"
|
|
|
|
if(!CONFIG_GET(flag/auto_deadmin_heads))
|
|
dat += "<b>As Command:</b> <a href = '?_src_=prefs;preference=toggle_deadmin_head'>[(deadmin & DEADMIN_POSITION_HEAD)?"Deadmin":"Keep Admin"]</a><br>"
|
|
else
|
|
dat += "<b>As Command:</b> FORCED<br>"
|
|
|
|
if(!CONFIG_GET(flag/auto_deadmin_security))
|
|
dat += "<b>As Security:</b> <a href = '?_src_=prefs;preference=toggle_deadmin_security'>[(deadmin & DEADMIN_POSITION_SECURITY)?"Deadmin":"Keep Admin"]</a><br>"
|
|
else
|
|
dat += "<b>As Security:</b> FORCED<br>"
|
|
|
|
if(!CONFIG_GET(flag/auto_deadmin_silicons))
|
|
dat += "<b>As Silicon:</b> <a href = '?_src_=prefs;preference=toggle_deadmin_silicon'>[(deadmin & DEADMIN_POSITION_SILICON)?"Deadmin":"Keep Admin"]</a><br>"
|
|
else
|
|
dat += "<b>As Silicon:</b> FORCED<br>"
|
|
|
|
dat += "</td>"
|
|
|
|
dat += "<td width='300px' height='300px' valign='top'>"
|
|
|
|
dat += "<h2>Citadel Preferences</h2>" //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
|
|
dat += "<b>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
|
|
dat += "<b>Long strip menu:</b> <a href='?_src_=prefs;preference=long_strip_menu'>[long_strip_menu ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Auto OOC:</b> <a href='?_src_=prefs;preference=auto_ooc'>[auto_ooc ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Force Slot Storage HUD:</b> <a href='?_src_=prefs;preference=no_tetris_storage'>[no_tetris_storage ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
|
|
if (user && user.client && !user.client.prefs.screenshake==0)
|
|
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
|
|
dat += "<b>Recoil Screen Push:</b> <a href='?_src_=prefs;preference=recoil_screenshake'>[(recoil_screenshake==100) ? "Full" : ((recoil_screenshake==0) ? "None" : "[screenshake]")]</a><br>"
|
|
var/p_chaos
|
|
if (!preferred_chaos)
|
|
p_chaos = "No preference"
|
|
else
|
|
p_chaos = preferred_chaos
|
|
dat += "<b>Preferred Chaos Amount:</b> <a href='?_src_=prefs;preference=preferred_chaos;task=input'>[p_chaos]</a><br>"
|
|
|
|
//SPLURT Edit
|
|
dat += "<h2>VENUS Preferences</h2>"
|
|
dat += "<b>Be Antagonist Victim:</b> <a href='?_src_=prefs;preference=be_victim;task=input'>[be_victim ? be_victim : BEVICTIM_ASK]</a><br>"
|
|
dat += "<b>Disable combat mode cursor:</b> <a href='?_src_=prefs;preference=disable_combat_cursor'>[disable_combat_cursor?"Yes":"No"]</a><br>"
|
|
dat += "<b>Splashscreen Player Panel Style:</b> <a href='?_src_=prefs;preference=tg_playerpanel'>[(toggles & TG_PLAYER_PANEL)?"TG":"Old"]</a><br>"
|
|
dat += "<b>Character Creation Menu Style:</b> <a href='?_src_=prefs;preference=charcreation_style'>[new_character_creator ? "New" : "Old"]</a><br>"
|
|
//SPLURT Edit end
|
|
|
|
dat += "<br>"
|
|
|
|
if(unlock_content)
|
|
dat += "<b>Ghost Form:</b> <a href='?_src_=prefs;task=input;preference=ghostform'>[ghost_form]</a><br>"
|
|
dat += "<B>Ghost Orbit: </B> <a href='?_src_=prefs;task=input;preference=ghostorbit'>[ghost_orbit]</a><br>"
|
|
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 += "<b>Ghost Accessories:</b> <a href='?_src_=prefs;task=input;preference=ghostaccs'>[button_name]</a><br>"
|
|
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 += "<b>Ghosts of Others:</b> <a href='?_src_=prefs;task=input;preference=ghostothers'>[button_name]</a><br>"
|
|
dat += "<br>"
|
|
|
|
dat += "<b>FPS:</b> <a href='?_src_=prefs;preference=clientfps;task=input'>[clientfps]</a><br>"
|
|
|
|
dat += "<b>Income Updates:</b> <a href='?_src_=prefs;preference=income_pings'>[(chat_toggles & CHAT_BANKCARD) ? "Allowed" : "Muted"]</a><br>"
|
|
dat += "<br>"
|
|
|
|
dat += "<b>Parallax (Fancy Space):</b> <a href='?_src_=prefs;preference=parallaxdown' oncontextmenu='window.location.href=\"?_src_=prefs;preference=parallaxup\";return false;'>"
|
|
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 += "</a><br>"
|
|
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'>[ambientocclusion ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>Fit Viewport:</b> <a href='?_src_=prefs;preference=auto_fit_viewport'>[auto_fit_viewport ? "Auto" : "Manual"]</a><br>"
|
|
dat += "<b>HUD Button Flashes:</b> <a href='?_src_=prefs;preference=hud_toggle_flash'>[hud_toggle_flash ? "Enabled" : "Disabled"]</a><br>"
|
|
dat += "<b>HUD Button Flash Color:</b> <span style='border: 1px solid #161616; background-color: [hud_toggle_color];'><font color='[color_hex2num(hud_toggle_color) < 200 ? "FFFFFF" : "000000"]'>[hud_toggle_color]</font></span> <a href='?_src_=prefs;preference=hud_toggle_color;task=input'>Change</a><br>"
|
|
|
|
|
|
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 += "<b>Preferred Map:</b> <a href='?_src_=prefs;preference=preferred_map;task=input'>[p_map]</a><br>"
|
|
|
|
dat += "</td></tr></table>"
|
|
|
|
if(CONTENT_PREFS_TAB)
|
|
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
|
dat += "<h2>Fetish content prefs</h2>"
|
|
dat += "<b>Allow Lewd Verbs:</b> <a href='?_src_=prefs;preference=verb_consent'>[(toggles & VERB_CONSENT) ? "Yes":"No"]</a><br>" // Skyrat - ERP Mechanic Addition
|
|
dat += "<b>Lewd Verb Sounds:</b> <a href='?_src_=prefs;preference=lewd_verb_sounds'>[(toggles & LEWD_VERB_SOUNDS) ? "Yes":"No"]</a><br>" // Sandstorm - ERP Mechanic Addition
|
|
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
|
|
dat += "<b>Genital examine text</b>:<a href='?_src_=prefs;preference=genital_examine'>[(cit_toggles & GENITAL_EXAMINE) ? "Enabled" : "Disabled"]</a><BR>"
|
|
dat += "<b>Vore examine text</b>:<a href='?_src_=prefs;preference=vore_examine'>[(cit_toggles & VORE_EXAMINE) ? "Enabled" : "Disabled"]</a><BR>"
|
|
dat += "<b>Voracious MediHound sleepers:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(cit_toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Allow trash forcefeeding (requires Trashcan quirk)</b> <a href='?_src_=prefs;preference=toggleforcefeedtrash'>[(cit_toggles & TRASH_FORCEFEED) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Forced Feminization:</b> <a href='?_src_=prefs;preference=feminization'>[(cit_toggles & FORCED_FEM) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Forced Masculinization:</b> <a href='?_src_=prefs;preference=masculinization'>[(cit_toggles & FORCED_MASC) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Lewd Hypno:</b> <a href='?_src_=prefs;preference=hypno'>[(cit_toggles & HYPNO) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Bimbofication:</b> <a href='?_src_=prefs;preference=bimbo'>[(cit_toggles & BIMBOFICATION) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "</td>"
|
|
dat +="<td width='300px' height='300px' valign='top'>"
|
|
dat += "<h2>Other content prefs</h2>"
|
|
dat += "<b>Breast Enlargement:</b> <a href='?_src_=prefs;preference=breast_enlargement'>[(cit_toggles & BREAST_ENLARGEMENT) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Penis Enlargement:</b> <a href='?_src_=prefs;preference=penis_enlargement'>[(cit_toggles & PENIS_ENLARGEMENT) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Butt Enlargement:</b> <a href='?_src_=prefs;preference=butt_enlargement'>[(cit_toggles & BUTT_ENLARGEMENT) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Belly Inflation:</b> <a href='?_src_=prefs;preference=belly_inflation'>[(cit_toggles & BELLY_INFLATION) ? "Allowed" : "Disallowed"]</a><br>" //SPLURT Edit
|
|
dat += "<b>Hypno:</b> <a href='?_src_=prefs;preference=never_hypno'>[(cit_toggles & NEVER_HYPNO) ? "Disallowed" : "Allowed"]</a><br>"
|
|
dat += "<b>Aphrodisiacs:</b> <a href='?_src_=prefs;preference=aphro'>[(cit_toggles & NO_APHRO) ? "Disallowed" : "Allowed"]</a><br>"
|
|
dat += "<b>Ass Slapping:</b> <a href='?_src_=prefs;preference=ass_slap'>[(cit_toggles & NO_ASS_SLAP) ? "Disallowed" : "Allowed"]</a><br>"
|
|
//SPLURT EDIT
|
|
dat += "<b>Chastity Interactions :</b> <a href='?_src_=prefs;preference=chastitypref'>[(cit_toggles & CHASTITY) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Genital Stimulation Modifiers :</b> <a href='?_src_=prefs;preference=stimulationpref'>[(cit_toggles & STIMULATION) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Edging :</b> <a href='?_src_=prefs;preference=edgingpref'>[(cit_toggles & EDGING) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<b>Receive Cum Covering :</b> <a href='?_src_=prefs;preference=cumontopref'>[(cit_toggles & CUM_ONTO) ? "Allowed" : "Disallowed"]</a><br>"
|
|
dat += "<span style='border-radius: 2px;border:1px dotted white;cursor:help;' title='Enables verbs involving farts, shit and piss.'>?</span> "
|
|
dat += "<b>Unholy ERP verbs :</b> <a href='?_src_=prefs;preference=unholypref'>[unholypref]</a><br>" //https://www.youtube.com/watch?v=OHKARc-GObU
|
|
dat += "<span style='border-radius: 2px;border:1px dotted white;cursor:help;' title='Enables macro / micro stepping and stomping interactions.'>?</span> "
|
|
dat += "<b>Stomping Interactions :</b> <a href='?_src_=prefs;preference=stomppref'>[stomppref ? "Yes" : "No"]</a><br>"
|
|
//END OF SPLURT EDIT
|
|
dat += "<span style='border-radius: 2px;border:1px dotted white;cursor:help;' title='Enables verbs involving ear/brain fucking.'>?</span> " //SPLURT Edit (wow! editception???)
|
|
//SANDSTORM EDIT
|
|
dat += "<b>Extreme ERP verbs :</b> <a href='?_src_=prefs;preference=extremepref'>[extremepref]</a><br>" // https://youtu.be/0YrU9ASVw6w
|
|
if(extremepref != "No")
|
|
dat += "<span style='border-radius: 2px;border:1px dotted white;cursor:help;' title='Enables verbs involving ear/brain fucking.'>?</span> " //SPLURT Edit
|
|
dat += "<b><span style='color: #e60000;'>Harmful ERP verbs :</b> <a href='?_src_=prefs;preference=extremeharm'>[extremeharm]</a><br>"
|
|
//END OF SANDSTORM EDIT
|
|
dat += "<b>Automatic Wagging:</b> <a href='?_src_=prefs;preference=auto_wag'>[(cit_toggles & NO_AUTO_WAG) ? "Disabled" : "Enabled"]</a><br>"
|
|
//SPLURT EDIT
|
|
dat += "<span style='border-radius: 2px;border:1px dotted white;cursor:help;' title='If anyone cums a blacklisted fluid into you, it uses the default fluid for that genital.'>?</span> "
|
|
dat += "<b><a href='?_src_=prefs;preference=gfluid_black;task=input'>Genital Fluid Blacklist</a></b><br>"
|
|
if(gfluid_blacklist?.len)
|
|
dat += "<span style='border-radius: 2px;border:1px dotted white;cursor:help;' title='Remove a genital fluid from your blacklist.'>?</span> "
|
|
dat += "<b><a href='?_src_=prefs;preference=gfluid_unblack;task=input'>Genital Fluid Un-Blacklist</a></b><br>"
|
|
//SPLURT Edit end
|
|
dat += "</tr></table>"
|
|
|
|
if(KEYBINDINGS_TAB) // Custom keybindings
|
|
dat += "<b>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Input"]</a><br>"
|
|
dat += "Keybindings mode controls how the game behaves with tab and map/input focus.<br>If it is on <b>Hotkeys</b>, 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.<br>\
|
|
If it is on <b>Input</b>, 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.<br>\
|
|
Input mode is the closest thing to the old input system.<br>\
|
|
<b>IMPORTANT:</b> 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.<br>"
|
|
dat += "<br><b>Modifier-Independent binding</b> - 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. <b>Each keybind can only have one independent binding, and each key can only have one keybind independently bound to it.</b>"
|
|
// 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 += {"
|
|
<style>
|
|
span.bindname { display: inline-block; position: absolute; width: 20% ; left: 5px; padding: 5px; } \
|
|
span.bindings { display: inline-block; position: relative; width: auto; left: 20%; width: auto; right: 20%; padding: 5px; } \
|
|
span.independent { display: inline-block; position: absolute; width: 20%; right: 5px; padding: 5px; } \
|
|
</style><body>
|
|
"}
|
|
|
|
for (var/category in kb_categories)
|
|
dat += "<h3>[category]</h3>"
|
|
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 += "<span class='bindname'>[kb.full_name]</span><span class='bindings'><a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=["Unbound"]'>Unbound</a>"
|
|
var/list/default_keys = hotkeys ? kb.hotkey_keys : kb.classic_keys
|
|
if(LAZYLEN(default_keys))
|
|
dat += "| Default: [default_keys.Join(", ")]"
|
|
dat += "</span>"
|
|
if(!kb.special && !kb.clientside)
|
|
dat += "<span class='independent'>Independent Binding: <a href='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[current_independent_binding];independent=1'>[current_independent_binding]</a></span>"
|
|
dat += "<br>"
|
|
else
|
|
var/bound_key = user_binds[kb.name][1]
|
|
dat += "<span class='bindname'l>[kb.full_name]</span><span class='bindings'><a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[bound_key]'>[bound_key]</a>"
|
|
for(var/bound_key_index in 2 to length(user_binds[kb.name]))
|
|
bound_key = user_binds[kb.name][bound_key_index]
|
|
dat += " | <a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[bound_key]'>[bound_key]</a>"
|
|
if(length(user_binds[kb.name]) < MAX_KEYS_PER_KEYBIND)
|
|
dat += "| <a href ='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name]'>Add Secondary</a>"
|
|
var/list/default_keys = hotkeys ? kb.classic_keys : kb.hotkey_keys
|
|
if(LAZYLEN(default_keys))
|
|
dat += "| Default: [default_keys.Join(", ")]"
|
|
dat += "</span>"
|
|
if(!kb.special && !kb.clientside)
|
|
dat += "<span class='independent'>Independent Binding: <a href='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[current_independent_binding];independent=1'>[current_independent_binding]</a></span>"
|
|
dat += "<br>"
|
|
|
|
dat += "<br><br>"
|
|
dat += "<a href ='?_src_=prefs;preference=keybindings_reset'>\[Reset to default\]</a>"
|
|
dat += "</body>"
|
|
|
|
|
|
dat += "<hr><center>"
|
|
|
|
if(!IsGuestKey(user.key))
|
|
dat += "<a href='?_src_=prefs;preference=load'>Undo</a> "
|
|
dat += "<a href='?_src_=prefs;preference=save'>Save Setup</a> "
|
|
|
|
dat += "<a href='?_src_=prefs;preference=reset_all'>Reset Setup</a>"
|
|
dat += "</center>"
|
|
|
|
winshow(user, "preferences_window", TRUE)
|
|
var/datum/browser/popup = new(user, "preferences_browser", "<div align='center'>Character Setup</div>", 640, 770)
|
|
popup.set_content(dat.Join())
|
|
popup.open(FALSE)
|
|
onclose(user, "preferences_window", src)
|
|
|
|
#undef APPEARANCE_CATEGORY_COLUMN
|
|
#undef MAX_MUTANT_ROWS
|
|
|
|
/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, old_key, independent = FALSE, special = FALSE)
|
|
var/HTML = {"
|
|
<div id='focus' style="outline: 0;" tabindex=0>Keybinding: [kb.full_name]<br>[kb.description]<br><br><b>Press any key to change<br>Press ESC to clear</b></div>
|
|
<script>
|
|
var deedDone = false;
|
|
document.onkeyup = function(e) {
|
|
if(deedDone){ return; }
|
|
var alt = e.altKey ? 1 : 0;
|
|
var ctrl = e.ctrlKey ? 1 : 0;
|
|
var shift = e.shiftKey ? 1 : 0;
|
|
var numpad = (95 < e.keyCode && e.keyCode < 112) ? 1 : 0;
|
|
var escPressed = e.keyCode == 27 ? 1 : 0;
|
|
var url = 'byond://?_src_=prefs;preference=keybindings_set;keybinding=[kb.name];old_key=[old_key];[independent?"independent=1;":""][special?"special=1;":""]clear_key='+escPressed+';key='+e.key+';alt='+alt+';ctrl='+ctrl+';shift='+shift+';numpad='+numpad+';key_code='+e.keyCode;
|
|
window.location=url;
|
|
deedDone = true;
|
|
}
|
|
document.getElementById('focus').focus();
|
|
</script>
|
|
"}
|
|
winshow(user, "capturekeypress", TRUE)
|
|
var/datum/browser/popup = new(user, "capturekeypress", "<div align='center'>Keybindings</div>", 350, 300)
|
|
popup.set_content(HTML)
|
|
popup.open(FALSE)
|
|
onclose(user, "capturekeypress", src)
|
|
|
|
/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 = "<center>"
|
|
if(SSjob.occupations.len <= 0)
|
|
HTML += "The job SSticker is not yet finished creating jobs, please try again later"
|
|
HTML += "<center><a href='?_src_=prefs;preference=job;task=close'>Done</a></center><br>" // Easier to press up here.
|
|
|
|
else
|
|
HTML += "<b>Choose occupation chances</b><br>"
|
|
HTML += "<div align='center'>Left-click to raise an occupation preference, right-click to lower it.<br></div>"
|
|
HTML += "<center><a href='?_src_=prefs;preference=job;task=close'>Done</a></center><br>" // Easier to press up here.
|
|
HTML += "<script type='text/javascript'>function setJobPrefRedirect(level, rank) { window.location.href='?_src_=prefs;preference=job;task=setJobLevel;level=' + level + ';text=' + encodeURIComponent(rank); return false; }</script>"
|
|
HTML += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more colomns.
|
|
HTML += "<table width='100%' cellpadding='1' cellspacing='0'>"
|
|
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 sort_list(SSjob.occupations, GLOBAL_PROC_REF(cmp_job_display_asc)))
|
|
|
|
index += 1
|
|
if((index >= limit) || (job.title in splitJobs))
|
|
width += widthPerColumn
|
|
if((index < limit) && (lastJob != null))
|
|
//If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with
|
|
//the last job's selection color. Creating a rather nice effect.
|
|
for(var/i = 0, i < (limit - index), i += 1)
|
|
HTML += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'> </td><td> </td></tr>"
|
|
HTML += "</table></td><td width='20%'><table width='100%' cellpadding='1' cellspacing='0'>"
|
|
index = 0
|
|
|
|
HTML += "<tr bgcolor='[job.selection_color]'><td width='60%' align='right'>"
|
|
var/rank = job.title
|
|
//Skyrat changes
|
|
var/displayed_rank = rank
|
|
if(job.alt_titles.len && (rank in alt_titles_preferences))
|
|
displayed_rank = alt_titles_preferences[rank]
|
|
//End of skyrat changes
|
|
lastJob = job
|
|
if(jobban_isbanned(user, rank))
|
|
HTML += "<font color=red>[rank]</font></td><td><a href='?_src_=prefs;bancheck=[rank]'> BANNED</a></td></tr>"
|
|
continue
|
|
var/required_playtime_remaining = job.required_playtime_remaining(user.client)
|
|
if(required_playtime_remaining)
|
|
HTML += "<font color=red>[rank]</font></td><td><font color=red> \[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \] </font></td></tr>"
|
|
continue
|
|
if(!job.player_old_enough(user.client))
|
|
var/available_in_days = job.available_in_days(user.client)
|
|
HTML += "<font color=red>[rank]</font></td><td><font color=red> \[IN [(available_in_days)] DAYS\]</font></td></tr>"
|
|
continue
|
|
if(!user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features))
|
|
if(user.client.prefs.pref_species.id == "human")
|
|
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[MUTANT\]</b></font></td></tr>"
|
|
else
|
|
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[NON-HUMAN\]</b></font></td></tr>"
|
|
continue
|
|
if((job_preferences["[SSjob.overflow_role]"] == JP_LOW) && (rank != SSjob.overflow_role) && !jobban_isbanned(user, SSjob.overflow_role))
|
|
HTML += "<font color=orange>[rank]</font></td><td></td></tr>"
|
|
continue
|
|
//Skyrat changes
|
|
var/rank_title_line = "[displayed_rank]"
|
|
if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs
|
|
rank_title_line = "<b>[rank_title_line]</b>"
|
|
if(job.alt_titles.len)
|
|
rank_title_line = "<a href='?_src_=prefs;preference=job;task=alt_title;job_title=[job.title]'>[rank_title_line]</a>"
|
|
else
|
|
rank_title_line = "<span class='dark'>[rank_title_line]</span>" //Make it dark if we're not adding a button for alt titles
|
|
HTML += rank_title_line
|
|
//End of skyrat changes
|
|
|
|
HTML += "</td><td width='40%'>"
|
|
|
|
var/prefLevelLabel = "ERROR"
|
|
var/prefLevelColor = "pink"
|
|
var/prefUpperLevel = -1 // level to assign on left click
|
|
var/prefLowerLevel = -1 // level to assign on right click
|
|
|
|
switch(job_preferences["[job.title]"])
|
|
if(JP_HIGH)
|
|
prefLevelLabel = "High"
|
|
prefLevelColor = "slateblue"
|
|
prefUpperLevel = 4
|
|
prefLowerLevel = 2
|
|
if(JP_MEDIUM)
|
|
prefLevelLabel = "Medium"
|
|
prefLevelColor = "green"
|
|
prefUpperLevel = 1
|
|
prefLowerLevel = 3
|
|
if(JP_LOW)
|
|
prefLevelLabel = "Low"
|
|
prefLevelColor = "orange"
|
|
prefUpperLevel = 2
|
|
prefLowerLevel = 4
|
|
else
|
|
prefLevelLabel = "NEVER"
|
|
prefLevelColor = "red"
|
|
prefUpperLevel = 3
|
|
prefLowerLevel = 1
|
|
|
|
HTML += "<a class='white' href='?_src_=prefs;preference=job;task=setJobLevel;level=[prefUpperLevel];text=[rank]' oncontextmenu='javascript:return setJobPrefRedirect([prefLowerLevel], \"[rank]\");'>"
|
|
|
|
if(rank == SSjob.overflow_role)//Overflow is special
|
|
if(job_preferences["[SSjob.overflow_role]"] == JP_LOW)
|
|
HTML += "<font color=green>Yes</font>"
|
|
else
|
|
HTML += "<font color=red>No</font>"
|
|
HTML += "</a></td></tr>"
|
|
continue
|
|
|
|
HTML += "<font color=[prefLevelColor]>[prefLevelLabel]</font>"
|
|
HTML += "</a></td></tr>"
|
|
|
|
for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even
|
|
HTML += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'> </td><td> </td></tr>"
|
|
|
|
HTML += "</td'></tr></table>"
|
|
HTML += "</center></table>"
|
|
|
|
var/message = "Be an [SSjob.overflow_role] if preferences unavailable"
|
|
if(joblessrole == BERANDOMJOB)
|
|
message = "Get random job if preferences unavailable"
|
|
else if(joblessrole == RETURNTOLOBBY)
|
|
message = "Return to lobby if preferences unavailable"
|
|
HTML += "<center><br><a href='?_src_=prefs;preference=job;task=random'>[message]</a></center>"
|
|
HTML += "<center><a href='?_src_=prefs;preference=job;task=reset'>Reset Preferences</a></center>"
|
|
|
|
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Occupation Preferences</div>", width, height)
|
|
popup.set_window_options("can_close=0")
|
|
popup.set_content(HTML)
|
|
popup.open(FALSE)
|
|
|
|
/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level)
|
|
if (!job)
|
|
return FALSE
|
|
|
|
if (level == JP_HIGH) // to high
|
|
//Set all other high to medium
|
|
for(var/j in job_preferences)
|
|
if(job_preferences["[j]"] == JP_HIGH)
|
|
job_preferences["[j]"] = JP_MEDIUM
|
|
//technically break here
|
|
|
|
job_preferences["[job.title]"] = level
|
|
return TRUE
|
|
|
|
/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl)
|
|
if(!SSjob || SSjob.occupations.len <= 0)
|
|
return
|
|
var/datum/job/job = SSjob.GetJob(role)
|
|
|
|
if(!job)
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
return
|
|
|
|
if (!isnum(desiredLvl))
|
|
to_chat(user, "<span class='danger'>UpdateJobPreference - desired level was not a number. Please notify coders!</span>")
|
|
ShowChoices(user)
|
|
return
|
|
|
|
var/jpval = null
|
|
switch(desiredLvl)
|
|
if(3)
|
|
jpval = JP_LOW
|
|
if(2)
|
|
jpval = JP_MEDIUM
|
|
if(1)
|
|
jpval = JP_HIGH
|
|
|
|
if(role == SSjob.overflow_role)
|
|
if(job_preferences["[job.title]"] == JP_LOW)
|
|
jpval = null
|
|
else
|
|
jpval = JP_LOW
|
|
|
|
SetJobPreferenceLevel(job, jpval)
|
|
SetChoices(user)
|
|
|
|
return TRUE
|
|
|
|
|
|
/datum/preferences/proc/ResetJobs()
|
|
job_preferences = list()
|
|
|
|
/datum/preferences/proc/SetQuirks(mob/user)
|
|
if(!SSquirks)
|
|
to_chat(user, "<span class='danger'>The quirk subsystem is still initializing! Try again in a minute.</span>")
|
|
return
|
|
|
|
var/list/dat = list()
|
|
if(!SSquirks.quirks.len)
|
|
dat += "The quirk subsystem hasn't finished initializing, please hold..."
|
|
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center><br>"
|
|
|
|
else
|
|
dat += "<center><b>Choose quirk setup</b></center><br>"
|
|
dat += "<div align='center'>Left-click to add or remove quirks. You need negative quirks to have positive ones.<br>\
|
|
Quirks are applied at roundstart and cannot normally be removed.</div>"
|
|
dat += "<center><a href='?_src_=prefs;preference=trait;task=close'>Done</a></center>"
|
|
dat += "<hr>"
|
|
dat += "<center><b>Current quirks:</b> [all_quirks.len ? all_quirks.Join(", ") : "None"]</center>"
|
|
dat += "<center>[GetPositiveQuirkCount()] / [MAX_QUIRKS] max positive quirks<br>\
|
|
<b>Quirk balance remaining:</b> [GetQuirkBalance()]<br>"
|
|
dat += " <a href='?_src_=prefs;quirk_category=[QUIRK_POSITIVE]' [quirk_category == QUIRK_POSITIVE ? "class='linkOn'" : ""]>[QUIRK_POSITIVE]</a> "
|
|
dat += " <a href='?_src_=prefs;quirk_category=[QUIRK_NEUTRAL]' [quirk_category == QUIRK_NEUTRAL ? "class='linkOn'" : ""]>[QUIRK_NEUTRAL]</a> "
|
|
dat += " <a href='?_src_=prefs;quirk_category=[QUIRK_NEGATIVE]' [quirk_category == QUIRK_NEGATIVE ? "class='linkOn'" : ""]>[QUIRK_NEGATIVE]</a> "
|
|
dat += "</center><br>"
|
|
for(var/V in SSquirks.quirks)
|
|
var/datum/quirk/T = SSquirks.quirks[V]
|
|
var/value = initial(T.value)
|
|
if((value > 0 && quirk_category != QUIRK_POSITIVE) || (value < 0 && quirk_category != QUIRK_NEGATIVE) || (value == 0 && quirk_category != QUIRK_NEUTRAL))
|
|
continue
|
|
|
|
var/quirk_name = initial(T.name)
|
|
var/has_quirk
|
|
var/quirk_cost = initial(T.value) * -1
|
|
var/lock_reason = "This trait is unavailable."
|
|
var/quirk_conflict = FALSE
|
|
for(var/_V in all_quirks)
|
|
if(_V == quirk_name)
|
|
has_quirk = TRUE
|
|
if(initial(T.mood_quirk) && CONFIG_GET(flag/disable_human_mood))
|
|
lock_reason = "Mood is disabled."
|
|
quirk_conflict = TRUE
|
|
if(has_quirk)
|
|
if(quirk_conflict)
|
|
all_quirks -= quirk_name
|
|
has_quirk = FALSE
|
|
else
|
|
quirk_cost *= -1 //invert it back, since we'd be regaining this amount
|
|
if(quirk_cost > 0)
|
|
quirk_cost = "+[quirk_cost]"
|
|
var/font_color = "#AAAAFF"
|
|
if(initial(T.value) != 0)
|
|
font_color = value > 0 ? "#AAFFAA" : "#FFAAAA"
|
|
if(quirk_conflict)
|
|
dat += "<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)] \
|
|
<font color='red'><b>LOCKED: [lock_reason]</b></font><br>"
|
|
else
|
|
if(has_quirk)
|
|
dat += "<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.)</a> \
|
|
<b><font color='[font_color]'>[quirk_name]</font></b> - [initial(T.desc)]<br>"
|
|
else
|
|
dat += "<a href='?_src_=prefs;preference=trait;task=update;trait=[quirk_name]'>[has_quirk ? "Remove" : "Take"] ([quirk_cost] pts.)</a> \
|
|
<font color='[font_color]'>[quirk_name]</font> - [initial(T.desc)]<br>"
|
|
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Quirks</a></center>"
|
|
|
|
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Quirk Preferences</div>", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
|
|
popup.set_window_options("can_close=0")
|
|
popup.set_content(dat.Join())
|
|
popup.open(FALSE)
|
|
|
|
/datum/preferences/proc/GetQuirkBalance()
|
|
var/bal = 0
|
|
for(var/V in all_quirks)
|
|
var/datum/quirk/T = SSquirks.quirks[V]
|
|
bal -= initial(T.value)
|
|
for(var/modification in modified_limbs)
|
|
if(modified_limbs[modification][1] == LOADOUT_LIMB_PROSTHETIC)
|
|
return bal + 1 //max 1 point regardless of how many prosthetics
|
|
return bal
|
|
|
|
/datum/preferences/proc/GetPositiveQuirkCount()
|
|
. = 0
|
|
for(var/q in all_quirks)
|
|
if(SSquirks.quirk_points[q] > 0)
|
|
.++
|
|
|
|
/datum/preferences/Topic(href, href_list, hsrc) //yeah, gotta do this I guess..
|
|
. = ..()
|
|
if(href_list["close"])
|
|
var/client/C = usr.client
|
|
if(C)
|
|
C.clear_character_previews()
|
|
|
|
/datum/preferences/proc/process_link(mob/user, list/href_list)
|
|
if(href_list["jobbancheck"])
|
|
var/job = href_list["jobbancheck"]
|
|
var/datum/db_query/query_get_jobban = SSdbcore.NewQuery({"
|
|
SELECT reason, bantime, duration, expiration_time, IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey)
|
|
FROM [format_table_name("ban")] WHERE ckey = :ckey AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = :job
|
|
"}, list("ckey" = user.ckey, "job" = job))
|
|
if(!query_get_jobban.warn_execute())
|
|
qdel(query_get_jobban)
|
|
return
|
|
if(query_get_jobban.NextRow())
|
|
var/reason = query_get_jobban.item[1]
|
|
var/bantime = query_get_jobban.item[2]
|
|
var/duration = query_get_jobban.item[3]
|
|
var/expiration_time = query_get_jobban.item[4]
|
|
var/admin_key = query_get_jobban.item[5]
|
|
var/text
|
|
text = "<span class='redtext'>You, or another user of this computer, ([user.key]) is banned from playing [job]. The ban reason is:<br>[reason]<br>This ban was applied by [admin_key] on [bantime]"
|
|
if(text2num(duration) > 0)
|
|
text += ". The ban is for [duration] minutes and expires on [expiration_time] (server time)"
|
|
text += ".</span>"
|
|
to_chat(user, text, confidential = TRUE)
|
|
qdel(query_get_jobban)
|
|
return
|
|
|
|
if(href_list["preference"] == "job")
|
|
switch(href_list["task"])
|
|
if("close")
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
if("reset")
|
|
ResetJobs()
|
|
SetChoices(user)
|
|
if("random")
|
|
switch(joblessrole)
|
|
if(RETURNTOLOBBY)
|
|
if(jobban_isbanned(user, SSjob.overflow_role))
|
|
joblessrole = BERANDOMJOB
|
|
else
|
|
joblessrole = BEOVERFLOW
|
|
if(BEOVERFLOW)
|
|
joblessrole = BERANDOMJOB
|
|
if(BERANDOMJOB)
|
|
joblessrole = RETURNTOLOBBY
|
|
SetChoices(user)
|
|
if("setJobLevel")
|
|
UpdateJobPreference(user, href_list["text"], text2num(href_list["level"]))
|
|
//SKYRAT CHANGES
|
|
if("alt_title")
|
|
var/job_title = href_list["job_title"]
|
|
var/titles_list = list(job_title)
|
|
var/datum/job/J = SSjob.GetJob(job_title)
|
|
for(var/i in J.alt_titles)
|
|
titles_list += i
|
|
var/chosen_title
|
|
chosen_title = input(user, "Choose your job's title:", "Job Preference") as null|anything in titles_list
|
|
if(chosen_title)
|
|
if(chosen_title == job_title)
|
|
if(alt_titles_preferences[job_title])
|
|
alt_titles_preferences.Remove(job_title)
|
|
else
|
|
alt_titles_preferences[job_title] = chosen_title
|
|
SetChoices(user)
|
|
//END OF SKYRAT CHANGES
|
|
else
|
|
SetChoices(user)
|
|
return TRUE
|
|
|
|
else if(href_list["preference"] == "trait")
|
|
switch(href_list["task"])
|
|
if("close")
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
if("update")
|
|
var/quirk = href_list["trait"]
|
|
if(!SSquirks.quirks[quirk])
|
|
return
|
|
for(var/V in SSquirks.quirk_blacklist) //V is a list
|
|
var/list/L = V
|
|
for(var/Q in all_quirks)
|
|
if((quirk in L) && (Q in L) && !(Q == quirk)) //two quirks have lined up in the list of the list of quirks that conflict with each other, so return (see quirks.dm for more details)
|
|
to_chat(user, "<span class='danger'>[quirk] is incompatible with [Q].</span>")
|
|
return
|
|
var/value = SSquirks.quirk_points[quirk]
|
|
var/balance = GetQuirkBalance()
|
|
if(quirk in all_quirks)
|
|
if(balance + value < 0)
|
|
to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>")
|
|
return
|
|
all_quirks -= quirk
|
|
else
|
|
if(GetPositiveQuirkCount() >= MAX_QUIRKS)
|
|
to_chat(user, "<span class='warning'>You can't have more than [MAX_QUIRKS] positive quirks!</span>")
|
|
return
|
|
if(balance - value < 0)
|
|
to_chat(user, "<span class='warning'>You don't have enough balance to gain this quirk!</span>")
|
|
return
|
|
all_quirks += quirk
|
|
SetQuirks(user)
|
|
if("reset")
|
|
all_quirks = list()
|
|
SetQuirks(user)
|
|
else
|
|
SetQuirks(user)
|
|
return TRUE
|
|
|
|
else if(href_list["quirk_category"])
|
|
var/temp_quirk_category = href_list["quirk_category"]
|
|
if(temp_quirk_category == QUIRK_POSITIVE || temp_quirk_category == QUIRK_NEUTRAL || temp_quirk_category == QUIRK_NEGATIVE)
|
|
quirk_category = temp_quirk_category
|
|
SetQuirks(user)
|
|
|
|
else if(href_list["preference"] == "language")
|
|
switch(href_list["task"])
|
|
if("close")
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
return TRUE
|
|
if("update")
|
|
var/lang = href_list["language"]
|
|
if(!SSlanguage.languages_by_name[lang])
|
|
return
|
|
if(!toggle_language(lang))
|
|
return
|
|
language = sort_list(language)
|
|
if("reset")
|
|
language = list()
|
|
SetLanguage(user)
|
|
return TRUE
|
|
|
|
switch(href_list["task"])
|
|
if("random")
|
|
switch(href_list["preference"])
|
|
if("name")
|
|
real_name = pref_species.random_name(gender,1)
|
|
if("age")
|
|
age = rand(AGE_MIN, AGE_MAX)
|
|
if("hair")
|
|
hair_color = random_short_color()
|
|
if("hair_style")
|
|
hair_style = random_hair_style(gender)
|
|
if("facial")
|
|
facial_hair_color = random_short_color()
|
|
if("facial_hair_style")
|
|
facial_hair_style = random_facial_hair_style(gender)
|
|
/*
|
|
if("underwear")
|
|
underwear = random_underwear(gender)
|
|
undie_color = random_short_color()
|
|
if("undershirt")
|
|
undershirt = random_undershirt(gender)
|
|
shirt_color = random_short_color()
|
|
if("socks")
|
|
socks = random_socks()
|
|
socks_color = random_short_color()
|
|
*/
|
|
if(BODY_ZONE_PRECISE_EYES)
|
|
var/random_eye_color = random_eye_color()
|
|
left_eye_color = random_eye_color
|
|
right_eye_color = random_eye_color
|
|
if("s_tone")
|
|
skin_tone = random_skin_tone()
|
|
use_custom_skin_tone = null
|
|
if("bag")
|
|
backbag = pick(GLOB.backbaglist)
|
|
if("suit")
|
|
jumpsuit_style = pick(GLOB.jumpsuitlist)
|
|
if("all")
|
|
random_character()
|
|
|
|
if("input")
|
|
|
|
if(href_list["preference"] in GLOB.preferences_custom_names)
|
|
ask_for_custom_name(user,href_list["preference"])
|
|
|
|
|
|
switch(href_list["preference"])
|
|
if("ghostform")
|
|
if(unlock_content)
|
|
var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in GLOB.ghost_forms
|
|
if(new_form)
|
|
ghost_form = new_form
|
|
if("ghostorbit")
|
|
if(unlock_content)
|
|
var/new_orbit = input(user, "Thanks for supporting BYOND - Choose your ghostly orbit:","Thanks for supporting BYOND", null) as null|anything in GLOB.ghost_orbits
|
|
if(new_orbit)
|
|
ghost_orbit = new_orbit
|
|
|
|
if("ghostaccs")
|
|
var/new_ghost_accs = alert("Do you want your ghost to show full accessories where possible, hide accessories but still use the directional sprites where possible, or also ignore the directions and stick to the default sprites?",,GHOST_ACCS_FULL_NAME, GHOST_ACCS_DIR_NAME, GHOST_ACCS_NONE_NAME)
|
|
switch(new_ghost_accs)
|
|
if(GHOST_ACCS_FULL_NAME)
|
|
ghost_accs = GHOST_ACCS_FULL
|
|
if(GHOST_ACCS_DIR_NAME)
|
|
ghost_accs = GHOST_ACCS_DIR
|
|
if(GHOST_ACCS_NONE_NAME)
|
|
ghost_accs = GHOST_ACCS_NONE
|
|
|
|
if("ghostothers")
|
|
var/new_ghost_others = alert("Do you want the ghosts of others to show up as their own setting, as their default sprites or always as the default white ghost?",,GHOST_OTHERS_THEIR_SETTING_NAME, GHOST_OTHERS_DEFAULT_SPRITE_NAME, GHOST_OTHERS_SIMPLE_NAME)
|
|
switch(new_ghost_others)
|
|
if(GHOST_OTHERS_THEIR_SETTING_NAME)
|
|
ghost_others = GHOST_OTHERS_THEIR_SETTING
|
|
if(GHOST_OTHERS_DEFAULT_SPRITE_NAME)
|
|
ghost_others = GHOST_OTHERS_DEFAULT_SPRITE
|
|
if(GHOST_OTHERS_SIMPLE_NAME)
|
|
ghost_others = GHOST_OTHERS_SIMPLE
|
|
|
|
if("name")
|
|
var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null
|
|
if(new_name)
|
|
new_name = reject_bad_name(new_name, allow_numbers = TRUE)
|
|
if(new_name)
|
|
real_name = new_name
|
|
else
|
|
to_chat(user, "<font color='red'>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 .</font>")
|
|
|
|
if("age")
|
|
var/new_age = tgui_input_number(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX_INPUT])", "Character Preference", null, AGE_MAX_INPUT, AGE_MIN)
|
|
if(new_age)
|
|
age = max(min( round(text2num(new_age)), AGE_MAX_INPUT),AGE_MIN)
|
|
|
|
if("security_records")
|
|
var/rec = stripped_multiline_input(usr, "Set your security record note section. This should be IC!", "Security Records", html_decode(security_records), MAX_FLAVOR_LEN, TRUE)
|
|
if(!isnull(rec))
|
|
security_records = rec
|
|
|
|
if("medical_records")
|
|
var/rec = stripped_multiline_input(usr, "Set your medical record note section. This should be IC!", "Security Records", html_decode(medical_records), MAX_FLAVOR_LEN, TRUE)
|
|
if(!isnull(rec))
|
|
medical_records = rec
|
|
|
|
if("flavor_text")
|
|
var/msg = input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", features["flavor_text"]) as message|null //Skyrat edit, removed stripped_multiline_input()
|
|
if(!isnull(msg))
|
|
features["flavor_text"] = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE) //Skyrat edit, removed strip_html_simple()
|
|
|
|
//SPLURT edit
|
|
if("naked_flavor_text")
|
|
var/msg = input(usr, "Set the naked flavor text in your 'examine' verb. This should be IC, describing how your character would look like if naked.", "Naked Flavor Text", features["naked_flavor_text"]) as message|null
|
|
if(!isnull(msg))
|
|
features["naked_flavor_text"] = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE)
|
|
//SPLURT edit end
|
|
if("silicon_flavor_text")
|
|
var/msg = input(usr, "Set the silicon flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Silicon Flavor Text", features["silicon_flavor_text"]) as message|null //Skyrat edit, removed stripped_multiline_input()
|
|
if(!isnull(msg))
|
|
features["silicon_flavor_text"] = strip_html_simple(msg, MAX_FLAVOR_LEN, TRUE) //Skyrat edit, uses strip_html_simple()
|
|
|
|
if("ooc_notes")
|
|
var/msg = stripped_multiline_input(usr, "Set always-visible OOC notes related to content preferences. THIS IS NOT FOR CHARACTER DESCRIPTIONS!", "OOC notes", html_decode(features["ooc_notes"]), MAX_FLAVOR_LEN, TRUE)
|
|
if(!isnull(msg))
|
|
features["ooc_notes"] = msg
|
|
|
|
if("hide_ckey")
|
|
hide_ckey = !hide_ckey
|
|
if(user)
|
|
user.mind?.hide_ckey = hide_ckey
|
|
|
|
//SPLURT EDIT BEGIN - gregnancy
|
|
if("virility")
|
|
var/viri = input(user, "Set the chance of you impregnating something (set to 0 to disable). \n(0 = minimum, 100 = maximum)", "Character Preference", virility) as num|null
|
|
virility = clamp(viri, 0, 100)
|
|
|
|
if("fertility")
|
|
var/fert = input(user, "Set the chance of you getting impregnated (set to 0 to disable). \n(0 = minimum, 100 = maximum)", "Character Preference", fertility) as num|null
|
|
fertility = clamp(fert, 0, 100)
|
|
|
|
if("egg_shell")
|
|
var/shell = input(user, "Pick a shell for your eggs", "Character Preferences") as null|anything in GLOB.egg_skins
|
|
if(shell)
|
|
egg_shell = shell
|
|
|
|
if("pregnancy_inflation")
|
|
pregnancy_inflation = !pregnancy_inflation
|
|
|
|
if("pregnancy_breast_growth")
|
|
pregnancy_breast_growth = !pregnancy_breast_growth
|
|
|
|
//SPLURT EDIT END
|
|
|
|
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, 6)
|
|
|
|
if("hair_style")
|
|
var/new_hair_style
|
|
new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_list
|
|
if(new_hair_style)
|
|
hair_style = new_hair_style
|
|
|
|
if("next_hair_style")
|
|
hair_style = next_list_item(hair_style, GLOB.hair_styles_list)
|
|
|
|
if("previous_hair_style")
|
|
hair_style = previous_list_item(hair_style, GLOB.hair_styles_list)
|
|
|
|
if("facial")
|
|
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference","#"+facial_hair_color) as color|null
|
|
if(new_facial)
|
|
facial_hair_color = sanitize_hexcolor(new_facial, 6)
|
|
|
|
if("facial_hair_style")
|
|
var/new_facial_hair_style
|
|
new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_list
|
|
if(new_facial_hair_style)
|
|
facial_hair_style = new_facial_hair_style
|
|
|
|
if("next_facehair_style")
|
|
facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_list)
|
|
|
|
if("previous_facehair_style")
|
|
facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_list)
|
|
|
|
if("grad_color")
|
|
var/new_grad_color = input(user, "Choose your character's gradient colour:", "Character Preference","#"+grad_color) as color|null
|
|
if(new_grad_color)
|
|
grad_color = sanitize_hexcolor(new_grad_color, 6)
|
|
|
|
if("grad_style")
|
|
var/new_grad_style
|
|
new_grad_style = input(user, "Choose your character's hair gradient style:", "Character Preference") as null|anything in GLOB.hair_gradients_list
|
|
if(new_grad_style)
|
|
grad_style = new_grad_style
|
|
|
|
if("next_grad_style")
|
|
grad_style = next_list_item(grad_style, GLOB.hair_gradients_list)
|
|
|
|
if("previous_grad_style")
|
|
grad_style = previous_list_item(grad_style, GLOB.hair_gradients_list)
|
|
|
|
if("cycle_bg")
|
|
bgstate = next_list_item(bgstate, bgstate_options)
|
|
|
|
if("modify_limbs")
|
|
var/limb_type = input(user, "Choose the limb to modify:", "Character Preference") as null|anything in LOADOUT_ALLOWED_LIMB_TARGETS
|
|
if(limb_type)
|
|
var/modification_type = input(user, "Choose the modification to the limb:", "Character Preference") as null|anything in LOADOUT_LIMBS
|
|
if(modification_type)
|
|
if(modification_type == LOADOUT_LIMB_PROSTHETIC)
|
|
var/prosthetic_type = input(user, "Choose the type of prosthetic", "Character Preference") as null|anything in (list("prosthetic") + GLOB.prosthetic_limb_types)
|
|
if(prosthetic_type)
|
|
var/number_of_prosthetics = 0
|
|
for(var/modified_limb in modified_limbs)
|
|
if(modified_limbs[modified_limb][1] == LOADOUT_LIMB_PROSTHETIC && modified_limb != limb_type)
|
|
number_of_prosthetics += 1
|
|
if(number_of_prosthetics == MAXIMUM_LOADOUT_PROSTHETICS)
|
|
to_chat(user, "<span class='danger'>You can only have up to two prosthetic limbs!</span>")
|
|
else
|
|
//save the actual prosthetic data
|
|
modified_limbs[limb_type] = list(modification_type, prosthetic_type)
|
|
else
|
|
if(modification_type == LOADOUT_LIMB_NORMAL)
|
|
modified_limbs -= limb_type
|
|
else
|
|
modified_limbs[limb_type] = list(modification_type)
|
|
|
|
/*
|
|
if("underwear")
|
|
var/new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_list
|
|
if(new_underwear)
|
|
underwear = new_underwear
|
|
|
|
if("undie_color")
|
|
var/n_undie_color = input(user, "Choose your underwear's color.", "Character Preference", "#[undie_color]") as color|null
|
|
if(n_undie_color)
|
|
undie_color = sanitize_hexcolor(n_undie_color, 6)
|
|
|
|
if("undershirt")
|
|
var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_list
|
|
if(new_undershirt)
|
|
undershirt = new_undershirt
|
|
|
|
if("shirt_color")
|
|
var/n_shirt_color = input(user, "Choose your undershirt's color.", "Character Preference", "#[shirt_color]") as color|null
|
|
if(n_shirt_color)
|
|
shirt_color = sanitize_hexcolor(n_shirt_color, 6)
|
|
|
|
if("socks")
|
|
var/new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list
|
|
if(new_socks)
|
|
socks = new_socks
|
|
|
|
if("socks_color")
|
|
var/n_socks_color = input(user, "Choose your socks' color.", "Character Preference", "#[socks_color]") as color|null
|
|
if(n_socks_color)
|
|
socks_color = sanitize_hexcolor(n_socks_color, 6)
|
|
*/
|
|
|
|
if("eyes")
|
|
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+left_eye_color) as color|null
|
|
if(new_eyes)
|
|
left_eye_color = sanitize_hexcolor(new_eyes, 6)
|
|
right_eye_color = sanitize_hexcolor(new_eyes, 6)
|
|
|
|
if("eye_left")
|
|
var/new_eyes = input(user, "Choose your character's left eye colour:", "Character Preference","#"+left_eye_color) as color|null
|
|
if(new_eyes)
|
|
left_eye_color = sanitize_hexcolor(new_eyes, 6)
|
|
|
|
if("eye_right")
|
|
var/new_eyes = input(user, "Choose your character's right eye colour:", "Character Preference","#"+right_eye_color) as color|null
|
|
if(new_eyes)
|
|
right_eye_color = sanitize_hexcolor(new_eyes, 6)
|
|
|
|
if("eye_type")
|
|
var/new_eye_type = input(user, "Choose your character's eye type.", "Character Preference") as null|anything in GLOB.eye_types
|
|
if(new_eye_type)
|
|
eye_type = new_eye_type
|
|
|
|
if("toggle_split_eyes")
|
|
split_eye_colors = !split_eye_colors
|
|
right_eye_color = left_eye_color
|
|
|
|
if("species")
|
|
var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_race_names
|
|
if(result)
|
|
var/newtype = GLOB.species_list[GLOB.roundstart_race_names[result]]
|
|
pref_species = new newtype()
|
|
//let's ensure that no weird shit happens on species swapping.
|
|
custom_species = null
|
|
if(!parent.can_have_part("mam_body_markings"))
|
|
features["mam_body_markings"] = list()
|
|
if(parent.can_have_part("mam_body_markings"))
|
|
if(features["mam_body_markings"] == "None")
|
|
features["mam_body_markings"] = list()
|
|
if(parent.can_have_part("tail_lizard"))
|
|
features["tail_lizard"] = "Smooth"
|
|
if(pref_species.id == "felinid")
|
|
features["mam_tail"] = "Cat"
|
|
features["mam_ears"] = "Cat"
|
|
|
|
//Now that we changed our species, we must verify that the mutant colour is still allowed.
|
|
var/temp_hsv = RGBtoHSV(features["mcolor"])
|
|
if(features["mcolor"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
|
features["mcolor"] = pref_species.default_color
|
|
if(features["mcolor2"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
|
features["mcolor2"] = pref_species.default_color
|
|
if(features["mcolor3"] == "#000000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
|
features["mcolor3"] = pref_species.default_color
|
|
|
|
//switch to the type of eyes the species uses
|
|
eye_type = pref_species.eye_type
|
|
|
|
if("custom_species")
|
|
var/new_species = reject_bad_name(input(user, "Choose your species subtype, if unique. This will show up on examinations and health scans. Do not abuse this:", "Character Preference", custom_species) as null|text, TRUE)
|
|
if(new_species)
|
|
custom_species = new_species
|
|
else
|
|
custom_species = null
|
|
|
|
if("mutant_color")
|
|
var/new_mutantcolor = input(user, "Choose your character's alien/mutant color:", "Character Preference","#"+features["mcolor"]) as color|null
|
|
if(new_mutantcolor)
|
|
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
|
if(new_mutantcolor == "#000000" && features["mcolor"] != pref_species.default_color) //SPLURT EDIT
|
|
features["mcolor"] = pref_species.default_color
|
|
else 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 //SPLURT EDIT
|
|
features["mcolor"] = sanitize_hexcolor(new_mutantcolor, 6)
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("mutant_color2")
|
|
var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference","#"+features["mcolor2"]) as color|null
|
|
if(new_mutantcolor)
|
|
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
|
if(new_mutantcolor == "#000000" && features["mcolor2"] != pref_species.default_color) //SPLURT EDIT
|
|
features["mcolor2"] = pref_species.default_color
|
|
else 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 //SPLURT EDIT
|
|
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor, 6)
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("mutant_color3")
|
|
var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference","#"+features["mcolor3"]) as color|null
|
|
if(new_mutantcolor)
|
|
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
|
if(new_mutantcolor == "#000000" && features["mcolor3"] != pref_species.default_color) //SPLURT EDIT
|
|
features["mcolor3"] = pref_species.default_color
|
|
else 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 //SPLURT EDIT
|
|
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor, 6)
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("mismatched_markings")
|
|
show_mismatched_markings = !show_mismatched_markings
|
|
|
|
if("has_neckfire")
|
|
features["neckfire"] = !features["neckfire"]
|
|
if("has_neckfire_color")
|
|
var/new_neckfire_color = input(user, "Choose your fire's color:", "Character Preference", "#"+features["neckfire_color"]) as color|null
|
|
if(new_neckfire_color)
|
|
var/temp_hsv = RGBtoHSV(new_neckfire_color)
|
|
if(new_neckfire_color == "#000000" && features["neckfire_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["neckfire_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["neckfire_color"] = sanitize_hexcolor(new_neckfire_color, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("ipc_screen")
|
|
var/new_ipc_screen
|
|
new_ipc_screen = input(user, "Choose your character's screen:", "Character Preference") as null|anything in GLOB.ipc_screens_list
|
|
if(new_ipc_screen)
|
|
features["ipc_screen"] = new_ipc_screen
|
|
|
|
if("ipc_antenna")
|
|
var/list/snowflake_antenna_list = list()
|
|
//Potential todo: turn all of THIS into a define to reduce copypasta.
|
|
for(var/path in GLOB.ipc_antennas_list)
|
|
var/datum/sprite_accessory/antenna/instance = GLOB.ipc_antennas_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_antenna_list[S.name] = path
|
|
var/new_ipc_antenna
|
|
new_ipc_antenna = input(user, "Choose your character's antenna:", "Character Preference") as null|anything in snowflake_antenna_list
|
|
if(new_ipc_antenna)
|
|
features["ipc_antenna"] = new_ipc_antenna
|
|
|
|
if("arachnid_legs")
|
|
var/new_arachnid_legs
|
|
new_arachnid_legs = input(user, "Choose your character's variant of arachnid legs:", "Character Preference") as null|anything in GLOB.arachnid_legs_list
|
|
if(new_arachnid_legs)
|
|
features["arachnid_legs"] = new_arachnid_legs
|
|
|
|
if("arachnid_spinneret")
|
|
var/new_arachnid_spinneret
|
|
new_arachnid_spinneret = input(user, "Choose your character's spinneret markings:", "Character Preference") as null|anything in GLOB.arachnid_spinneret_list
|
|
if(new_arachnid_spinneret)
|
|
features["arachnid_spinneret"] = new_arachnid_spinneret
|
|
|
|
if("arachnid_mandibles")
|
|
var/new_arachnid_mandibles
|
|
new_arachnid_mandibles = input(user, "Choose your character's variant of mandibles:", "Character Preference") as null|anything in GLOB.arachnid_mandibles_list
|
|
if (new_arachnid_mandibles)
|
|
features["arachnid_mandibles"] = new_arachnid_mandibles
|
|
|
|
if("tail_lizard")
|
|
var/new_tail
|
|
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_lizard
|
|
if(new_tail)
|
|
features["tail_lizard"] = new_tail
|
|
if(new_tail != "None")
|
|
features["taur"] = "None"
|
|
features["tail_human"] = "None"
|
|
features["mam_tail"] = "None"
|
|
|
|
if("tail_human")
|
|
var/list/snowflake_tails_list = list()
|
|
for(var/path in GLOB.tails_list_human)
|
|
var/datum/sprite_accessory/tails/human/instance = GLOB.tails_list_human[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_tails_list[S.name] = path
|
|
var/new_tail
|
|
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list
|
|
if(new_tail)
|
|
features["tail_human"] = new_tail
|
|
if(new_tail != "None")
|
|
features["taur"] = "None"
|
|
features["tail_lizard"] = "None"
|
|
features["mam_tail"] = "None"
|
|
|
|
if("mam_tail")
|
|
var/list/snowflake_tails_list = list()
|
|
for(var/path in GLOB.mam_tails_list)
|
|
var/datum/sprite_accessory/tails/mam_tails/instance = GLOB.mam_tails_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_tails_list[S.name] = path
|
|
var/new_tail
|
|
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in snowflake_tails_list
|
|
if(new_tail)
|
|
features["mam_tail"] = new_tail
|
|
if(new_tail != "None")
|
|
features["taur"] = "None"
|
|
features["tail_human"] = "None"
|
|
features["tail_lizard"] = "None"
|
|
|
|
if("meat_type")
|
|
var/new_meat
|
|
new_meat = input(user, "Choose your character's meat type:", "Character Preference") as null|anything in GLOB.meat_types
|
|
if(new_meat)
|
|
features["meat_type"] = new_meat
|
|
|
|
if("snout")
|
|
var/list/snowflake_snouts_list = list()
|
|
for(var/path in GLOB.snouts_list)
|
|
var/datum/sprite_accessory/snouts/mam_snouts/instance = GLOB.snouts_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_snouts_list[S.name] = path
|
|
var/new_snout
|
|
new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in snowflake_snouts_list
|
|
if(new_snout)
|
|
features["snout"] = new_snout
|
|
features["mam_snouts"] = "None"
|
|
|
|
|
|
if("mam_snouts")
|
|
var/list/snowflake_mam_snouts_list = list()
|
|
for(var/path in GLOB.mam_snouts_list)
|
|
var/datum/sprite_accessory/snouts/mam_snouts/instance = GLOB.mam_snouts_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_mam_snouts_list[S.name] = path
|
|
var/new_mam_snouts
|
|
new_mam_snouts = input(user, "Choose your character's snout:", "Character Preference") as null|anything in snowflake_mam_snouts_list
|
|
if(new_mam_snouts)
|
|
features["mam_snouts"] = new_mam_snouts
|
|
features["snout"] = "None"
|
|
|
|
if("horns")
|
|
var/new_horns
|
|
new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list
|
|
if(new_horns)
|
|
features["horns"] = new_horns
|
|
|
|
if("horns_color")
|
|
var/new_horn_color = input(user, "Choose your character's horn colour:", "Character Preference","#"+features["horns_color"]) as color|null
|
|
if(new_horn_color)
|
|
if (new_horn_color == "#000000" && features["horns_color"] != "85615A") //SPLURT EDIT
|
|
features["horns_color"] = "85615A"
|
|
else
|
|
features["horns_color"] = sanitize_hexcolor(new_horn_color, 6)
|
|
|
|
if("wings")
|
|
var/new_wings
|
|
new_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.r_wings_list
|
|
if(new_wings)
|
|
features["wings"] = new_wings
|
|
|
|
if("wings_color")
|
|
var/new_wing_color = input(user, "Choose your character's wing colour:", "Character Preference","#"+features["wings_color"]) as color|null
|
|
if(new_wing_color)
|
|
if (new_wing_color == "#000000" && features["wings_color"] != "#FFFFFF") //SPLURT EDIT
|
|
features["wings_color"] = "#FFFFFF"
|
|
else
|
|
features["wings_color"] = sanitize_hexcolor(new_wing_color, 6)
|
|
|
|
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("legs")
|
|
var/new_legs
|
|
new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in GLOB.legs_list
|
|
if(new_legs)
|
|
features["legs"] = new_legs
|
|
|
|
if("insect_wings")
|
|
var/new_insect_wings
|
|
new_insect_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_wings_list
|
|
if(new_insect_wings)
|
|
features["insect_wings"] = new_insect_wings
|
|
|
|
if("deco_wings")
|
|
var/new_deco_wings
|
|
new_deco_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.deco_wings_list
|
|
if(new_deco_wings)
|
|
features["deco_wings"] = new_deco_wings
|
|
|
|
if("insect_fluff")
|
|
var/new_insect_fluff
|
|
new_insect_fluff = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_fluffs_list
|
|
if(new_insect_fluff)
|
|
features["insect_fluff"] = new_insect_fluff
|
|
|
|
if("insect_markings")
|
|
var/new_insect_markings
|
|
new_insect_markings = input(user, "Choose your character's markings:", "Character Preference") as null|anything in GLOB.insect_markings_list
|
|
if(new_insect_markings)
|
|
features["insect_markings"] = new_insect_markings
|
|
|
|
if("arachnid_legs")
|
|
var/new_arachnid_legs
|
|
new_arachnid_legs = input(user, "Choose your character's variant of arachnid legs:", "Character Preference") as null|anything in GLOB.arachnid_legs_list
|
|
if(new_arachnid_legs)
|
|
features["arachnid_legs"] = new_arachnid_legs
|
|
|
|
if("arachnid_spinneret")
|
|
var/new_arachnid_spinneret
|
|
new_arachnid_spinneret = input(user, "Choose your character's spinneret markings:", "Character Preference") as null|anything in GLOB.arachnid_spinneret_list
|
|
if(new_arachnid_spinneret)
|
|
features["arachnid_spinneret"] = new_arachnid_spinneret
|
|
|
|
if("arachnid_mandibles")
|
|
var/new_arachnid_mandibles
|
|
new_arachnid_mandibles = input(user, "Choose your character's variant of mandibles:", "Character Preference") as null|anything in GLOB.arachnid_mandibles_list
|
|
if (new_arachnid_mandibles)
|
|
features["arachnid_mandibles"] = new_arachnid_mandibles
|
|
|
|
if("s_tone")
|
|
var/list/choices = GLOB.skin_tones - GLOB.nonstandard_skin_tones
|
|
if(CONFIG_GET(flag/allow_custom_skintones))
|
|
choices += "custom"
|
|
var/new_s_tone = input(user, "Choose your character's skin tone:", "Character Preference") as null|anything in choices
|
|
if(new_s_tone)
|
|
if(new_s_tone == "custom")
|
|
var/default = use_custom_skin_tone ? skin_tone : null
|
|
var/custom_tone = input(user, "Choose your custom skin tone:", "Character Preference", default) as color|null
|
|
if(custom_tone)
|
|
var/temp_hsv = RGBtoHSV(custom_tone)
|
|
if(ReadHSV(temp_hsv)[3] < ReadHSV("#333333")[3] && CONFIG_GET(flag/character_color_limits)) // rgb(50,50,50) //SPLURT EDIT
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
else
|
|
use_custom_skin_tone = TRUE
|
|
skin_tone = custom_tone
|
|
else
|
|
use_custom_skin_tone = FALSE
|
|
skin_tone = new_s_tone
|
|
|
|
if("taur")
|
|
var/list/snowflake_taur_list = list()
|
|
for(var/path in GLOB.taur_list)
|
|
var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if(S.ignore)
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_taur_list[S.name] = path
|
|
var/new_taur
|
|
new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in snowflake_taur_list
|
|
if(new_taur)
|
|
features["taur"] = new_taur
|
|
if(new_taur != "None")
|
|
features["mam_tail"] = "None"
|
|
features["xenotail"] = "None"
|
|
features["tail_human"] = "None"
|
|
features["tail_lizard"] = "None"
|
|
features["arachnid_spinneret"] = "None"
|
|
|
|
if("ears")
|
|
var/list/snowflake_ears_list = list()
|
|
for(var/path in GLOB.ears_list)
|
|
var/datum/sprite_accessory/ears/instance = GLOB.ears_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_ears_list[S.name] = path
|
|
var/new_ears
|
|
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list
|
|
if(new_ears)
|
|
features["ears"] = new_ears
|
|
|
|
if("mam_ears")
|
|
var/list/snowflake_ears_list = list()
|
|
for(var/path in GLOB.mam_ears_list)
|
|
var/datum/sprite_accessory/ears/mam_ears/instance = GLOB.mam_ears_list[path]
|
|
if(istype(instance, /datum/sprite_accessory))
|
|
var/datum/sprite_accessory/S = instance
|
|
if(!show_mismatched_markings && S.recommended_species && !S.recommended_species.Find(pref_species.id))
|
|
continue
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_ears_list[S.name] = path
|
|
var/new_ears
|
|
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in snowflake_ears_list
|
|
if(new_ears)
|
|
features["mam_ears"] = new_ears
|
|
|
|
//Xeno Bodyparts
|
|
if("xenohead")//Head or caste type
|
|
var/new_head
|
|
new_head = input(user, "Choose your character's caste:", "Character Preference") as null|anything in GLOB.xeno_head_list
|
|
if(new_head)
|
|
features["xenohead"] = new_head
|
|
|
|
if("xenotail")//Currently one one type, more maybe later if someone sprites them. Might include animated variants in the future.
|
|
var/new_tail
|
|
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.xeno_tail_list
|
|
if(new_tail)
|
|
features["xenotail"] = new_tail
|
|
if(new_tail != "None")
|
|
features["mam_tail"] = "None"
|
|
features["taur"] = "None"
|
|
features["tail_human"] = "None"
|
|
features["tail_lizard"] = "None"
|
|
|
|
if("xenodorsal")
|
|
var/new_dors
|
|
new_dors = input(user, "Choose your character's dorsal tube type:", "Character Preference") as null|anything in GLOB.xeno_dorsal_list
|
|
if(new_dors)
|
|
features["xenodorsal"] = new_dors
|
|
|
|
//every single primary/secondary/tertiary colouring done at once
|
|
if("xenodorsal_primary","xenodorsal_secondary","xenodorsal_tertiary","xhead_primary","xhead_secondary","xhead_tertiary","tail_primary","tail_secondary","tail_tertiary","insect_markings_primary","insect_markings_secondary","insect_markings_tertiary","insect_fluff_primary","insect_fluff_secondary","insect_fluff_tertiary","ears_primary","ears_secondary","ears_tertiary","frills_primary","frills_secondary","frills_tertiary","ipc_antenna_primary","ipc_antenna_secondary","ipc_antenna_tertiary","taur_primary","taur_secondary","taur_tertiary","snout_primary","snout_secondary","snout_tertiary","spines_primary","spines_secondary","spines_tertiary", "mam_body_markings_primary", "mam_body_markings_secondary", "mam_body_markings_tertiary")
|
|
var/the_feature = features[href_list["preference"]]
|
|
if(!the_feature)
|
|
features[href_list["preference"]] = "FFFFFF"
|
|
the_feature = "FFFFFF"
|
|
var/new_feature_color = input(user, "Choose your character's mutant part colour:", "Character Preference","#"+features[href_list["preference"]]) as color|null
|
|
if(new_feature_color)
|
|
var/temp_hsv = RGBtoHSV(new_feature_color)
|
|
if(new_feature_color == "#000000" && features[href_list["preference"]] != pref_species.default_color) //SPLURT EDIT
|
|
features[href_list["preference"]] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features[href_list["preference"]] = sanitize_hexcolor(new_feature_color, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
|
|
//advanced color mode toggle
|
|
if("color_scheme")
|
|
if(features["color_scheme"] == ADVANCED_CHARACTER_COLORING)
|
|
features["color_scheme"] = OLD_CHARACTER_COLORING
|
|
else
|
|
features["color_scheme"] = ADVANCED_CHARACTER_COLORING
|
|
|
|
//Genital code
|
|
if("lust_tolerance")
|
|
var/lust_tol = input(user, "Set how long you can last without climaxing. \n(75 = minimum, 200 = maximum.)", "Character Preference", lust_tolerance) as num|null
|
|
if(lust_tol)
|
|
lust_tolerance = clamp(lust_tol, 75, 200)
|
|
if("sexual_potency")
|
|
var/sexual_pot = input(user, "Set your sexual potency. \n(-1 = minimum, 25 = maximum.) This determines the number of times your character can orgasm before becoming impotent, use -1 for no impotency.", "Character Preference", sexual_potency) as num|null
|
|
if(sexual_pot)
|
|
sexual_potency = clamp(sexual_pot, -1, 25)
|
|
|
|
if("cock_color")
|
|
var/new_cockcolor = input(user, "Penis color:", "Character Preference","#"+features["cock_color"]) as color|null
|
|
if(new_cockcolor)
|
|
var/temp_hsv = RGBtoHSV(new_cockcolor)
|
|
if(new_cockcolor == "#000000" && features["cock_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["cock_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["cock_color"] = sanitize_hexcolor(new_cockcolor, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("cock_length")
|
|
var/min_D = CONFIG_GET(number/penis_min_inches_prefs)
|
|
var/max_D = CONFIG_GET(number/penis_max_inches_prefs)
|
|
var/new_length = input(user, "Penis length in inches:\n([min_D]-[max_D])\nReminder that your sprite size will affect this.", "Character Preference") as num|null
|
|
if(new_length)
|
|
features["cock_length"] = clamp(round(new_length), min_D, max_D)
|
|
|
|
if("cock_shape")
|
|
var/new_shape
|
|
var/list/hockeys = list()
|
|
if(parent.can_have_part("taur"))
|
|
var/datum/sprite_accessory/taur/T = GLOB.taur_list[features["taur"]]
|
|
for(var/A in GLOB.cock_shapes_list)
|
|
var/datum/sprite_accessory/penis/P = GLOB.cock_shapes_list[A]
|
|
if(P.taur_icon && T.taur_mode & P.accepted_taurs)
|
|
LAZYSET(hockeys, "[A] (Taur)", A)
|
|
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in (GLOB.cock_shapes_list + hockeys)
|
|
if(new_shape)
|
|
features["cock_taur"] = FALSE
|
|
if(hockeys[new_shape])
|
|
new_shape = hockeys[new_shape]
|
|
features["cock_taur"] = TRUE
|
|
features["cock_shape"] = new_shape
|
|
|
|
if("cock_diameter_ratio")
|
|
var/min_diameter_ratio = CONFIG_GET(number/diameter_ratio_min_size_prefs)
|
|
var/max_diameter_ratio = CONFIG_GET(number/diameter_ratio_max_size_prefs)
|
|
var/new_ratio = input(user, "Penis diameter ratio:\n([min_diameter_ratio]-[max_diameter_ratio])\nReminder that your sprite size will affect this.", "Character Preference") as num|null
|
|
if(new_ratio)
|
|
features["cock_diameter_ratio"] = clamp(round(new_ratio, 0.01), min_diameter_ratio, max_diameter_ratio)
|
|
|
|
if("cock_visibility")
|
|
var/n_vis = input(user, "Penis Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["cock_visibility"] = n_vis
|
|
|
|
if("balls_color")
|
|
var/new_ballscolor = input(user, "Testicles Color:", "Character Preference","#"+features["balls_color"]) as color|null
|
|
if(new_ballscolor)
|
|
var/temp_hsv = RGBtoHSV(new_ballscolor)
|
|
if(new_ballscolor == "#000000" && features["balls_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["balls_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["balls_color"] = sanitize_hexcolor(new_ballscolor, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("balls_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Testicle Shape", "Character Preference") as null|anything in GLOB.balls_shapes_list
|
|
if(new_shape)
|
|
features["balls_shape"] = new_shape
|
|
|
|
if("balls_visibility")
|
|
var/n_vis = input(user, "Testicles Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["balls_visibility"] = n_vis
|
|
|
|
if("balls_fluid")
|
|
var/datum/reagent/new_fluid
|
|
var/list/full_options = list()
|
|
LAZYADD(full_options, GLOB.genital_fluids_list)
|
|
LAZYREMOVE(full_options, find_reagent_object_from_type(/datum/reagent/consumable/semen))
|
|
full_options = list(find_reagent_object_from_type(/datum/reagent/consumable/semen)) + full_options
|
|
new_fluid = tgui_input_list(user, "Balls Fluid", "Character Preference", full_options)
|
|
if(new_fluid)
|
|
features["balls_fluid"] = new_fluid.type
|
|
|
|
if("breasts_size")
|
|
var/new_size = input(user, "Breast Size", "Character Preference") as null|anything in CONFIG_GET(keyed_list/breasts_cups_prefs)
|
|
if(new_size)
|
|
features["breasts_size"] = new_size
|
|
|
|
if("breasts_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list
|
|
if(new_shape)
|
|
features["breasts_shape"] = new_shape
|
|
|
|
if("breasts_color")
|
|
var/new_breasts_color = input(user, "Breast Color:", "Character Preference","#"+features["breasts_color"]) as color|null
|
|
if(new_breasts_color)
|
|
var/temp_hsv = RGBtoHSV(new_breasts_color)
|
|
if(new_breasts_color == "#000000" && features["breasts_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["breasts_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["breasts_color"] = sanitize_hexcolor(new_breasts_color, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("breasts_visibility")
|
|
var/n_vis = input(user, "Breasts Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["breasts_visibility"] = n_vis
|
|
|
|
if("breasts_fluid")
|
|
var/datum/reagent/new_fluid
|
|
var/list/full_options = list()
|
|
LAZYADD(full_options, GLOB.genital_fluids_list)
|
|
LAZYREMOVE(full_options, find_reagent_object_from_type(/datum/reagent/consumable/milk))
|
|
full_options = list(find_reagent_object_from_type(/datum/reagent/consumable/milk)) + full_options
|
|
new_fluid = tgui_input_list(user, "Breast Fluid", "Character Preference", full_options)
|
|
if(new_fluid)
|
|
features["breasts_fluid"] = new_fluid.type
|
|
|
|
if("vag_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list
|
|
if(new_shape)
|
|
features["vag_shape"] = new_shape
|
|
|
|
if("vag_color")
|
|
var/new_vagcolor = input(user, "Vagina color:", "Character Preference","#"+features["vag_color"]) as color|null
|
|
if(new_vagcolor)
|
|
var/temp_hsv = RGBtoHSV(new_vagcolor)
|
|
if(new_vagcolor == "#000000" && features["vag_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["vag_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["vag_color"] = sanitize_hexcolor(new_vagcolor, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("vag_visibility")
|
|
var/n_vis = input(user, "Vagina Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["vag_visibility"] = n_vis
|
|
|
|
if("womb_fluid")
|
|
var/datum/reagent/new_fluid
|
|
var/list/full_options = list()
|
|
LAZYADD(full_options, GLOB.genital_fluids_list)
|
|
LAZYREMOVE(full_options, find_reagent_object_from_type(/datum/reagent/consumable/semen/femcum))
|
|
full_options = list(find_reagent_object_from_type(/datum/reagent/consumable/semen/femcum)) + full_options
|
|
new_fluid = tgui_input_list(user, "Womb Fluid", "Character Preference", full_options)
|
|
if(new_fluid)
|
|
features["womb_fluid"] = new_fluid.type
|
|
|
|
if("belly_color")
|
|
var/new_bellycolor = input(user, "Belly Color:", "Character Preference", "#"+features["belly_color"]) as color|null
|
|
if(new_bellycolor)
|
|
var/temp_hsv = RGBtoHSV(new_bellycolor)
|
|
if(new_bellycolor == "#000000" && features["belly_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["belly_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["belly_color"] = sanitize_hexcolor(new_bellycolor, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("butt_color")
|
|
var/new_buttcolor = input(user, "Butt color:", "Character Preference","#"+features["butt_color"]) as color|null
|
|
if(new_buttcolor)
|
|
var/temp_hsv = RGBtoHSV(new_buttcolor)
|
|
if(new_buttcolor == "#000000" && features["butt_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["butt_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["butt_color"] = sanitize_hexcolor(new_buttcolor, 6)
|
|
else
|
|
to_chat(user,"<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("anus_color")
|
|
var/new_anuscolor = input(user, "Butthole color:", "Character Preference", "#"+features["anus_color"]) as color|null
|
|
if(new_anuscolor)
|
|
var/temp_hsv = RGBtoHSV(new_anuscolor)
|
|
if(new_anuscolor == "#000000" && features["anus_color"] != pref_species.default_color) //SPLURT EDIT
|
|
features["anus_color"] = pref_species.default_color
|
|
else if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3] || !CONFIG_GET(flag/character_color_limits)) //SPLURT EDIT
|
|
features["anus_color"] = sanitize_hexcolor(new_anuscolor, 6)
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
if("anus_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Butthole Shape", "Character Preference") as null|anything in GLOB.anus_shapes_list
|
|
if(new_shape)
|
|
features["anus_shape"] = new_shape
|
|
|
|
if("belly_size")
|
|
var/min_belly = CONFIG_GET(number/belly_min_size_prefs)
|
|
var/max_belly = CONFIG_GET(number/belly_max_size_prefs)
|
|
var/new_bellysize = input(user, "Belly size :\n([min_belly]-[max_belly])", "Character Preference") as num|null
|
|
if(!isnull(new_bellysize))
|
|
features["belly_size"] = clamp(new_bellysize, min_belly, max_belly)
|
|
|
|
if("butt_size")
|
|
var/min_B = CONFIG_GET(number/butt_min_size_prefs)
|
|
var/max_B = CONFIG_GET(number/butt_max_size_prefs)
|
|
var/new_length = input(user, "Butt size:\n([min_B]-[max_B])", "Character Preference") as num|null
|
|
if(new_length)
|
|
features["butt_size"] = clamp(round(new_length), min_B, max_B)
|
|
|
|
if("butt_visibility")
|
|
var/n_vis = input(user, "Butt Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["butt_visibility"] = n_vis
|
|
|
|
if("anus_visibility")
|
|
var/n_vis = input(user, "Butthole Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["anus_visibility"] = n_vis
|
|
|
|
if("belly_visibility")
|
|
var/n_vis = input(user, "Belly Visibility", "Character Preference") as null|anything in CONFIG_GET(str_list/safe_visibility_toggles)
|
|
if(n_vis)
|
|
features["belly_visibility"] = n_vis
|
|
|
|
if("cock_max_length")
|
|
var/max_B = CONFIG_GET(number/penis_max_inches_prefs)
|
|
var/new_size = input(user, "Max size:\n([features["cock_length"]]-[max_B])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["cock_max_length"] = clamp(round(new_size), features["cock_length"], max_B)
|
|
else
|
|
features -= "cock_max_length"
|
|
|
|
if("balls_max_size")
|
|
var/new_size = input(user, "Max size:\n([BALLS_SIZE_MIN]-[BALLS_SIZE_MAX])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["balls_max_size"] = clamp(round(new_size), BALLS_SIZE_MIN, BALLS_SIZE_MAX)
|
|
else
|
|
features -= "balls_max_size"
|
|
|
|
if("breasts_max_size")
|
|
var/new_size = input(user, "Breast Max Size (cancel to disable)", "Character Preference") as null|anything in GLOB.breast_values
|
|
if(new_size)
|
|
features["breasts_max_size"] = new_size
|
|
else
|
|
features -= "breasts_max_size"
|
|
|
|
if("belly_max_size")
|
|
var/max_B = CONFIG_GET(number/belly_max_size_prefs)
|
|
var/new_size = input(user, "Max size:\n([features["belly_size"]]-[max_B])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["belly_max_size"] = clamp(round(new_size), features["belly_size"], max_B)
|
|
else
|
|
features -= "belly_max_size"
|
|
|
|
if("butt_max_size")
|
|
var/max_B = CONFIG_GET(number/butt_max_size_prefs)
|
|
var/new_size = input(user, "Max size:\n([features["butt_size"]]-[max_B])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["butt_max_size"] = clamp(round(new_size), features["butt_size"], max_B)
|
|
else
|
|
features -= "butt_max_size"
|
|
|
|
if("cock_min_length")
|
|
var/min_B = CONFIG_GET(number/penis_min_inches_prefs)
|
|
var/new_size = input(user, "Min size:\n([min_B]-[features["cock_length"]])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["cock_min_length"] = clamp(round(new_size), min_B, features["cock_length"])
|
|
else
|
|
features -= "cock_min_length"
|
|
|
|
if("balls_min_size")
|
|
var/new_size = input(user, "Min size:\n([BALLS_SIZE_MIN]-[BALLS_SIZE_MAX])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["balls_min_size"] = clamp(round(new_size), BALLS_SIZE_MIN, BALLS_SIZE_MAX)
|
|
else
|
|
features -= "balls_min_size"
|
|
|
|
if("breasts_min_size")
|
|
var/new_size = input(user, "Breast Min Size (cancel to disable)", "Character Preference") as null|anything in GLOB.breast_values
|
|
if(new_size)
|
|
features["breasts_min_size"] = new_size
|
|
else
|
|
features -= "breasts_min_size"
|
|
|
|
if("belly_min_size")
|
|
var/min_B = CONFIG_GET(number/belly_min_size_prefs)
|
|
var/new_size = input(user, "Min size:\n([min_B]-[features["belly_size"]])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["belly_min_size"] = clamp(round(new_size), min_B, features["belly_size"])
|
|
else
|
|
features -= "belly_min_size"
|
|
|
|
if("butt_min_size")
|
|
var/min_B = CONFIG_GET(number/butt_min_size_prefs)
|
|
var/new_size = input(user, "Min size:\n([min_B]-[features["butt_size"]])(0 = disabled)", "Character Preference") as num|null
|
|
if(new_size)
|
|
features["butt_min_size"] = clamp(round(new_size), min_B, features["butt_size"])
|
|
else
|
|
features -= "butt_min_size"
|
|
|
|
if("ooccolor")
|
|
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null
|
|
if(new_ooccolor)
|
|
ooccolor = sanitize_ooccolor(new_ooccolor)
|
|
|
|
if("aooccolor")
|
|
var/new_aooccolor = input(user, "Choose your Antag OOC colour:", "Game Preference",ooccolor) as color|null
|
|
if(new_aooccolor)
|
|
aooccolor = sanitize_ooccolor(new_aooccolor)
|
|
|
|
if("bag")
|
|
var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist
|
|
if(new_backbag)
|
|
backbag = new_backbag
|
|
|
|
if("suit")
|
|
if(jumpsuit_style == PREF_SUIT)
|
|
jumpsuit_style = PREF_SKIRT
|
|
else
|
|
jumpsuit_style = PREF_SUIT
|
|
|
|
|
|
if("uplink_loc")
|
|
var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in GLOB.uplink_spawn_loc_list
|
|
if(new_loc)
|
|
uplink_spawn_loc = new_loc
|
|
|
|
if("ai_core_icon")
|
|
var/ai_core_icon = input(user, "Choose your preferred AI core display screen:", "AI Core Display Screen Selection") as null|anything in GLOB.ai_core_display_screens
|
|
if(ai_core_icon)
|
|
preferred_ai_core_display = ai_core_icon
|
|
|
|
if("sec_dept")
|
|
var/department = input(user, "Choose your preferred security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs
|
|
if(department)
|
|
prefered_security_department = department
|
|
|
|
if ("preferred_map")
|
|
var/maplist = list()
|
|
var/default = "Default"
|
|
if (config.defaultmap)
|
|
default += " ([config.defaultmap.map_name])"
|
|
for (var/M in config.maplist)
|
|
var/datum/map_config/VM = config.maplist[M]
|
|
var/friendlyname = "[VM.map_name] "
|
|
if (VM.voteweight <= 0)
|
|
friendlyname += " (disabled)"
|
|
maplist[friendlyname] = VM.map_name
|
|
maplist[default] = null
|
|
var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in maplist
|
|
if (pickedmap)
|
|
preferred_map = maplist[pickedmap]
|
|
|
|
if ("preferred_chaos")
|
|
var/pickedchaos = input(user, "Choose your preferred level of chaos. This will help with dynamic threat level ratings.", "Character Preference") as null|anything in list(CHAOS_NONE,CHAOS_LOW,CHAOS_MED,CHAOS_HIGH,CHAOS_MAX)
|
|
preferred_chaos = pickedchaos
|
|
if ("be_victim")
|
|
var/pickedvictim = input(user, "Are you ok with antagonists interacting with you (e.g. kidnapping)? ERP consent is seperate: This setting does NOT mean they are allowed to rape you.", "Antag Victim Consent") as null|anything in list(BEVICTIM_NO,BEVICTIM_ASK,BEVICTIM_YES)
|
|
be_victim = pickedvictim
|
|
if ("clientfps")
|
|
var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
|
|
if (!isnull(desiredfps))
|
|
clientfps = desiredfps
|
|
parent.fps = desiredfps
|
|
if("ui")
|
|
var/pickedui = input(user, "Choose your UI style.", "Character Preference", UI_style) as null|anything in GLOB.available_ui_styles
|
|
if(pickedui)
|
|
UI_style = pickedui
|
|
if (pickedui && parent && parent.mob && parent.mob.hud_used)
|
|
QDEL_NULL(parent.mob.hud_used)
|
|
parent.mob.create_mob_hud()
|
|
parent.mob.hud_used.show_hud(1, parent.mob)
|
|
//Added by SPLURT (Custom Blood Color)
|
|
if("toggle_custom_blood_color")
|
|
custom_blood_color = !custom_blood_color
|
|
if("blood_color")
|
|
var/pickedBloodColor = input(user, "Choose your blood color.", "Character Preference", blood_color) as color|null
|
|
if(!pickedBloodColor)
|
|
return
|
|
if(pickedBloodColor)
|
|
blood_color = sanitize_hexcolor(pickedBloodColor, 6, 1, initial(blood_color))
|
|
if(!custom_blood_color)
|
|
custom_blood_color = TRUE
|
|
///
|
|
if("pda_style")
|
|
var/pickedPDAStyle = input(user, "Choose your PDA style.", "Character Preference", pda_style) as null|anything in GLOB.pda_styles
|
|
if(pickedPDAStyle)
|
|
pda_style = pickedPDAStyle
|
|
if("pda_color")
|
|
var/pickedPDAColor = input(user, "Choose your PDA Interface color.", "Character Preference",pda_color) as color|null
|
|
if(pickedPDAColor)
|
|
pda_color = pickedPDAColor
|
|
if("pda_skin")
|
|
var/pickedPDASkin = input(user, "Choose your PDA reskin.", "Character Preference", pda_skin) as null|anything in GLOB.pda_reskins
|
|
if(pickedPDASkin)
|
|
pda_skin = pickedPDASkin
|
|
if("silicon_lawset")
|
|
var/picked_lawset = input(user, "Choose your preferred lawset", "Silicon preference", silicon_lawset) as null|anything in list("None") + CONFIG_GET(keyed_list/choosable_laws)
|
|
if(picked_lawset)
|
|
if(picked_lawset == "None")
|
|
picked_lawset = null
|
|
silicon_lawset = picked_lawset
|
|
if ("max_chat_length")
|
|
var/desiredlength = input(user, "Choose the max character length of shown Runechat messages. Valid range is 1 to [CHAT_MESSAGE_MAX_LENGTH] (default: [initial(max_chat_length)]))", "Character Preference", max_chat_length) as null|num
|
|
if (!isnull(desiredlength))
|
|
max_chat_length = clamp(desiredlength, 1, CHAT_MESSAGE_MAX_LENGTH)
|
|
|
|
//Sandstorm changes begin
|
|
if("personal_chat_color")
|
|
var/new_chat_color = input(user, "Choose your character's runechat color:", "Character Preference",personal_chat_color) as color|null
|
|
if(new_chat_color)
|
|
if(color_hex2num(new_chat_color) > 200)
|
|
personal_chat_color = sanitize_hexcolor(new_chat_color, 6, TRUE)
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
//End of sandstorm changes
|
|
|
|
if("hud_toggle_color")
|
|
var/new_toggle_color = input(user, "Choose your HUD toggle flash color:", "Game Preference",hud_toggle_color) as color|null
|
|
if(new_toggle_color)
|
|
hud_toggle_color = new_toggle_color
|
|
|
|
if("gender")
|
|
var/chosengender = input(user, "Select your character's gender.", "Gender Selection", gender) as null|anything in list(MALE,FEMALE,"nonbinary","object")
|
|
if(!chosengender)
|
|
return
|
|
switch(chosengender)
|
|
if("nonbinary")
|
|
chosengender = PLURAL
|
|
features["body_model"] = pick(MALE, FEMALE)
|
|
if("object")
|
|
chosengender = NEUTER
|
|
features["body_model"] = MALE
|
|
else
|
|
features["body_model"] = chosengender
|
|
gender = chosengender
|
|
|
|
if("body_size")
|
|
var/new_body_size = input(user, "Choose your desired sprite size: ([CONFIG_GET(number/body_size_min)*100]-[CONFIG_GET(number/body_size_max)*100]%)\nWarning: This may make your character look distorted. Additionally, any size under 100% takes a 10% maximum health penalty", "Character Preference", features["body_size"]*100) as num|null
|
|
if(new_body_size)
|
|
features["body_size"] = clamp(new_body_size * 0.01, CONFIG_GET(number/body_size_min), CONFIG_GET(number/body_size_max))
|
|
|
|
if("toggle_fuzzy")
|
|
fuzzy = !fuzzy
|
|
|
|
if("tongue")
|
|
var/selected_custom_tongue = input(user, "Choose your desired tongue (none means your species tongue)", "Character Preference") as null|anything in GLOB.roundstart_tongues
|
|
if(selected_custom_tongue)
|
|
custom_tongue = selected_custom_tongue
|
|
if("speech_verb")
|
|
var/selected_custom_speech_verb = input(user, "Choose your desired speech verb (none means your species speech verb)", "Character Preference") as null|anything in GLOB.speech_verbs
|
|
if(selected_custom_speech_verb)
|
|
custom_speech_verb = selected_custom_speech_verb
|
|
|
|
if("barksound")
|
|
var/list/woof_woof = list()
|
|
for(var/path in GLOB.bark_list)
|
|
var/datum/bark/B = GLOB.bark_list[path]
|
|
if(initial(B.ignore))
|
|
continue
|
|
if(initial(B.ckeys_allowed))
|
|
var/list/allowed = initial(B.ckeys_allowed)
|
|
if(!allowed.Find(user.client.ckey))
|
|
continue
|
|
woof_woof[initial(B.name)] = initial(B.id)
|
|
var/new_bork = input(user, "Choose your desired vocal bark", "Character Preference") as null|anything in woof_woof
|
|
if(new_bork)
|
|
bark_id = woof_woof[new_bork]
|
|
var/datum/bark/B = GLOB.bark_list[bark_id] //Now we need sanitization to take into account bark-specific min/max values
|
|
bark_speed = round(clamp(bark_speed, initial(B.minspeed), initial(B.maxspeed)), 1)
|
|
bark_pitch = clamp(bark_pitch, initial(B.minpitch), initial(B.maxpitch))
|
|
bark_variance = clamp(bark_variance, initial(B.minvariance), initial(B.maxvariance))
|
|
|
|
if("barkspeed")
|
|
var/datum/bark/B = GLOB.bark_list[bark_id]
|
|
var/borkset = input(user, "Choose your desired bark speed (Higher is slower, lower is faster). Min: [initial(B.minspeed)]. Max: [initial(B.maxspeed)]", "Character Preference") as null|num
|
|
if(!isnull(borkset))
|
|
bark_speed = round(clamp(borkset, initial(B.minspeed), initial(B.maxspeed)), 1)
|
|
|
|
if("barkpitch")
|
|
var/datum/bark/B = GLOB.bark_list[bark_id]
|
|
var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minpitch)]. Max: [initial(B.maxpitch)]", "Character Preference") as null|num
|
|
if(!isnull(borkset))
|
|
bark_pitch = clamp(borkset, initial(B.minpitch), initial(B.maxpitch))
|
|
|
|
if("barkvary")
|
|
var/datum/bark/B = GLOB.bark_list[bark_id]
|
|
var/borkset = input(user, "Choose your desired baseline bark pitch. Min: [initial(B.minvariance)]. Max: [initial(B.maxvariance)]", "Character Preference") as null|num
|
|
if(!isnull(borkset))
|
|
bark_variance = clamp(borkset, initial(B.minvariance), initial(B.maxvariance))
|
|
|
|
if("bodysprite")
|
|
var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids
|
|
if(selected_body_sprite)
|
|
chosen_limb_id = selected_body_sprite //this gets sanitized before loading
|
|
|
|
if("marking_down")
|
|
// move the specified marking down
|
|
var/index = text2num(href_list["marking_index"])
|
|
var/marking_type = href_list["marking_type"]
|
|
if(index && marking_type && features[marking_type] && index != length(features[marking_type]))
|
|
var/index_down = index + 1
|
|
var/markings = features[marking_type]
|
|
var/first_marking = markings[index]
|
|
var/second_marking = markings[index_down]
|
|
markings[index] = second_marking
|
|
markings[index_down] = first_marking
|
|
|
|
if("marking_up")
|
|
// move the specified marking up
|
|
var/index = text2num(href_list["marking_index"])
|
|
var/marking_type = href_list["marking_type"]
|
|
if(index && marking_type && features[marking_type] && index != 1)
|
|
var/index_up = index - 1
|
|
var/markings = features[marking_type]
|
|
var/first_marking = markings[index]
|
|
var/second_marking = markings[index_up]
|
|
markings[index] = second_marking
|
|
markings[index_up] = first_marking
|
|
|
|
if("marking_remove")
|
|
// move the specified marking up
|
|
var/index = text2num(href_list["marking_index"])
|
|
var/marking_type = href_list["marking_type"]
|
|
if(index && marking_type && features[marking_type])
|
|
// because linters are just absolutely awful:
|
|
var/list/L = features[marking_type]
|
|
L.Cut(index, index + 1)
|
|
|
|
if("marking_add")
|
|
// add a marking
|
|
var/marking_type = href_list["marking_type"]
|
|
if(marking_type && features[marking_type])
|
|
var/selected_limb = input(user, "Choose the limb to apply to.", "Character Preference") as null|anything in list("Head", "Chest", "Left Arm", "Right Arm", "Left Leg", "Right Leg", "All")
|
|
if(selected_limb)
|
|
var/list/marking_list = GLOB.mam_body_markings_list
|
|
var/list/snowflake_markings_list = list()
|
|
for(var/path in marking_list)
|
|
var/datum/sprite_accessory/S = marking_list[path]
|
|
if(istype(S))
|
|
if(istype(S, /datum/sprite_accessory/mam_body_markings))
|
|
var/datum/sprite_accessory/mam_body_markings/marking = S
|
|
if(!(selected_limb in marking.covered_limbs) && selected_limb != "All")
|
|
continue
|
|
|
|
if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(user.client.ckey)))
|
|
snowflake_markings_list[S.name] = path
|
|
|
|
var/selected_marking = input(user, "Select the marking to apply to the limb.") as null|anything in snowflake_markings_list
|
|
if(selected_marking)
|
|
if(selected_limb != "All")
|
|
var/limb_value = text2num(GLOB.bodypart_values[selected_limb])
|
|
features[marking_type] += list(list(limb_value, selected_marking))
|
|
else
|
|
var/datum/sprite_accessory/mam_body_markings/S = marking_list[selected_marking]
|
|
for(var/limb in S.covered_limbs)
|
|
var/limb_value = text2num(GLOB.bodypart_values[limb])
|
|
features[marking_type] += list(list(limb_value, selected_marking))
|
|
|
|
if("marking_color_specific")
|
|
var/index = text2num(href_list["marking_index"])
|
|
var/marking_type = href_list["marking_type"]
|
|
var/color_number = text2num(href_list["number_color"])
|
|
if(index && marking_type && color_number && features[marking_type])
|
|
// 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 //SPLURT EDIT
|
|
color_list[color_number] = "#[sanitize_hexcolor(new_marking_color, 6)]"
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
//SPLURT Edit
|
|
if("gfluid_black")
|
|
var/list/datum/reagent/fluid_list = GLOB.genital_fluids_list.Copy()
|
|
var/list/blacklisted = list()
|
|
for(var/r in gfluid_blacklist)
|
|
LAZYADD(blacklisted, find_reagent_object_from_type(r))
|
|
LAZYREMOVE(fluid_list, GLOB.default_genital_fluids + blacklisted) //these are already blacklisted/are defaults
|
|
var/datum/reagent/selected = tgui_input_list(user, "Blacklist a fluid:", "Genital Fluid Blacklist", fluid_list)
|
|
if(selected)
|
|
LAZYADD(gfluid_blacklist, selected.type)
|
|
if("gfluid_unblack")
|
|
var/list/datum/reagent/fluid_list
|
|
for(var/r in gfluid_blacklist)
|
|
LAZYADD(fluid_list, find_reagent_object_from_type(r))
|
|
if(fluid_list)
|
|
var/datum/reagent/selected = tgui_input_list(user, "Remove a fluid from your blacklist:", "Genital Fluid Blacklist", fluid_list)
|
|
if(selected)
|
|
LAZYREMOVE(gfluid_blacklist, selected.type)
|
|
else
|
|
to_chat(user, span_warning("You do not have blacklisted reagents!"))
|
|
//SPLURT Edit end
|
|
else
|
|
switch(href_list["preference"])
|
|
if("disable_combat_cursor")
|
|
disable_combat_cursor = !disable_combat_cursor
|
|
if("tg_playerpanel")
|
|
toggles ^= TG_PLAYER_PANEL
|
|
to_chat(user, span_warning("Please relog in order to apply the changes"))
|
|
save_preferences()
|
|
//CITADEL PREFERENCES EDIT - I can't figure out how to modularize these, so they have to go here. :c -Pooj
|
|
if("genital_colour")
|
|
features["genitals_use_skintone"] = !features["genitals_use_skintone"]
|
|
if("arousable")
|
|
arousable = !arousable
|
|
if("has_cock")
|
|
features["has_cock"] = !features["has_cock"]
|
|
if(features["has_cock"] == FALSE)
|
|
features["has_balls"] = FALSE
|
|
if("cock_accessible")
|
|
features["cock_accessible"] = !features["cock_accessible"]
|
|
if("has_belly")
|
|
features["has_belly"] = !features["has_belly"]
|
|
if(features["has_belly"] == FALSE)
|
|
features["belly_size"] = 1
|
|
if("has_balls")
|
|
features["has_balls"] = !features["has_balls"]
|
|
if("balls_accessible")
|
|
features["balls_accessible"] = !features["balls_accessible"]
|
|
if("has_breasts")
|
|
features["has_breasts"] = !features["has_breasts"]
|
|
if(features["has_breasts"] == FALSE)
|
|
features["breasts_producing"] = FALSE
|
|
if("breasts_producing")
|
|
features["breasts_producing"] = !features["breasts_producing"]
|
|
if("breasts_accessible")
|
|
features["breasts_accessible"] = !features["breasts_accessible"]
|
|
if("has_vag")
|
|
features["has_vag"] = !features["has_vag"]
|
|
if(features["has_vag"] == FALSE)
|
|
features["has_womb"] = FALSE
|
|
if("vag_accessible")
|
|
features["vag_accessible"] = !features["vag_accessible"]
|
|
if("has_womb")
|
|
features["has_womb"] = !features["has_womb"]
|
|
if("has_butt")
|
|
features["has_butt"] = !features["has_butt"]
|
|
if(features["has_butt"] == FALSE)
|
|
features["has_anus"] = FALSE
|
|
if("has_anus")
|
|
features["has_anus"] = !features["has_anus"]
|
|
if("butt_accessible")
|
|
features["butt_accessible"] = !features["butt_accessible"]
|
|
if("anus_accessible")
|
|
features["anus_accessible"] = !features["anus_accessible"]
|
|
if("belly_accessible")
|
|
features["belly_accessible"] = !features["belly_accessible"]
|
|
if("widescreenpref")
|
|
widescreenpref = !widescreenpref
|
|
user.client.view_size.setDefault(getScreenSize(widescreenpref))
|
|
if("long_strip_menu")
|
|
long_strip_menu = !long_strip_menu
|
|
if("cock_stuffing")
|
|
features["cock_stuffing"] = !features["cock_stuffing"]
|
|
if("balls_stuffing")
|
|
features["balls_stuffing"] = !features["balls_stuffing"]
|
|
if("vag_stuffing")
|
|
features["vag_stuffing"] = !features["vag_stuffing"]
|
|
if("breasts_stuffing")
|
|
features["breasts_stuffing"] = !features["breasts_stuffing"]
|
|
if("butt_stuffing")
|
|
features["butt_stuffing"] = !features["butt_stuffing"]
|
|
if("anus_stuffing")
|
|
features["anus_stuffing"] = !features["anus_stuffing"]
|
|
if("belly_stuffing")
|
|
features["belly_stuffing"] = !features["belly_stuffing"]
|
|
if("inert_eggs")
|
|
features["inert_eggs"] = !features["inert_eggs"]
|
|
if("pixel_size")
|
|
switch(pixel_size)
|
|
if(PIXEL_SCALING_AUTO)
|
|
pixel_size = PIXEL_SCALING_1X
|
|
if(PIXEL_SCALING_1X)
|
|
pixel_size = PIXEL_SCALING_1_2X
|
|
if(PIXEL_SCALING_1_2X)
|
|
pixel_size = PIXEL_SCALING_2X
|
|
if(PIXEL_SCALING_2X)
|
|
pixel_size = PIXEL_SCALING_3X
|
|
if(PIXEL_SCALING_3X)
|
|
pixel_size = PIXEL_SCALING_AUTO
|
|
user.client.view_size.apply() //Let's winset() it so it actually works
|
|
|
|
if("scaling_method")
|
|
switch(scaling_method)
|
|
if(SCALING_METHOD_NORMAL)
|
|
scaling_method = SCALING_METHOD_DISTORT
|
|
if(SCALING_METHOD_DISTORT)
|
|
scaling_method = SCALING_METHOD_BLUR
|
|
if(SCALING_METHOD_BLUR)
|
|
scaling_method = SCALING_METHOD_NORMAL
|
|
user.client.view_size.setZoomMode()
|
|
|
|
if("autostand")
|
|
autostand = !autostand
|
|
if("auto_ooc")
|
|
auto_ooc = !auto_ooc
|
|
if("no_tetris_storage")
|
|
no_tetris_storage = !no_tetris_storage
|
|
if ("screenshake")
|
|
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num
|
|
if (!isnull(desiredshake))
|
|
screenshake = desiredshake
|
|
if("damagescreenshake")
|
|
switch(damagescreenshake)
|
|
if(0)
|
|
damagescreenshake = 1
|
|
if(1)
|
|
damagescreenshake = 2
|
|
if(2)
|
|
damagescreenshake = 0
|
|
else
|
|
damagescreenshake = 1
|
|
if ("recoil_screenshake")
|
|
var/desiredshake = input(user, "Set the amount of recoil screenshake/push you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num
|
|
if (!isnull(desiredshake))
|
|
recoil_screenshake = desiredshake
|
|
if("nameless")
|
|
nameless = !nameless
|
|
|
|
//Skyrat begin
|
|
if("erp_pref")
|
|
switch(erppref)
|
|
if("Yes")
|
|
erppref = "Ask"
|
|
if("Ask")
|
|
erppref = "No"
|
|
if("No")
|
|
erppref = "Yes"
|
|
if("noncon_pref")
|
|
switch(nonconpref)
|
|
if("Yes")
|
|
nonconpref = "Ask"
|
|
if("Ask")
|
|
nonconpref = "No"
|
|
if("No")
|
|
nonconpref = "Yes"
|
|
if("vore_pref")
|
|
switch(vorepref)
|
|
if("Yes")
|
|
vorepref = "Ask"
|
|
if("Ask")
|
|
vorepref = "No"
|
|
if("No")
|
|
vorepref = "Yes"
|
|
if("unholypref") //...
|
|
switch(unholypref)
|
|
if("Yes")
|
|
unholypref = "Ask"
|
|
if("Ask")
|
|
unholypref = "No"
|
|
if("No")
|
|
unholypref = "Yes"
|
|
if("stomppref") // What the fuck is this?
|
|
stomppref = !stomppref
|
|
//Skyrat edit - *someone* offered me actual money for this shit
|
|
if("extremepref") //i hate myself for doing this
|
|
switch(extremepref) //why the fuck did this need to use cycling instead of input from a list
|
|
if("Yes") //seriously this confused me so fucking much
|
|
extremepref = "Ask"
|
|
if("Ask")
|
|
extremepref = "No"
|
|
extremeharm = "No"
|
|
if("No")
|
|
extremepref = "Yes"
|
|
if("extremeharm")
|
|
switch(extremeharm)
|
|
if("Yes") //this is cursed code
|
|
extremeharm = "No"
|
|
if("No")
|
|
extremeharm = "Yes"
|
|
if(extremepref == "No")
|
|
extremeharm = "No"
|
|
//END CITADEL EDIT
|
|
if("publicity")
|
|
if(unlock_content)
|
|
toggles ^= MEMBER_PUBLIC
|
|
|
|
if("body_model")
|
|
features["body_model"] = features["body_model"] == MALE ? FEMALE : MALE
|
|
|
|
if("hotkeys")
|
|
hotkeys = !hotkeys
|
|
user.client.ensure_keys_set(src)
|
|
|
|
if("keybindings_capture")
|
|
var/datum/keybinding/kb = GLOB.keybindings_by_name[href_list["keybinding"]]
|
|
CaptureKeybinding(user, kb, href_list["old_key"], text2num(href_list["independent"]), kb.special || kb.clientside)
|
|
return
|
|
|
|
if("keybindings_set")
|
|
var/kb_name = href_list["keybinding"]
|
|
if(!kb_name)
|
|
user << browse(null, "window=capturekeypress")
|
|
ShowChoices(user)
|
|
return
|
|
|
|
var/independent = href_list["independent"]
|
|
|
|
var/clear_key = text2num(href_list["clear_key"])
|
|
var/old_key = href_list["old_key"]
|
|
if(clear_key)
|
|
if(independent)
|
|
modless_key_bindings -= old_key
|
|
else
|
|
if(key_bindings[old_key])
|
|
key_bindings[old_key] -= kb_name
|
|
LAZYADD(key_bindings["Unbound"], kb_name)
|
|
if(!length(key_bindings[old_key]))
|
|
key_bindings -= old_key
|
|
user << browse(null, "window=capturekeypress")
|
|
if(href_list["special"]) // special keys need a full reset
|
|
user.client.ensure_keys_set(src)
|
|
save_preferences()
|
|
ShowChoices(user)
|
|
return
|
|
|
|
var/new_key = uppertext(href_list["key"])
|
|
var/AltMod = text2num(href_list["alt"]) ? "Alt" : ""
|
|
var/CtrlMod = text2num(href_list["ctrl"]) ? "Ctrl" : ""
|
|
var/ShiftMod = text2num(href_list["shift"]) ? "Shift" : ""
|
|
var/numpad = text2num(href_list["numpad"]) ? "Numpad" : ""
|
|
// var/key_code = text2num(href_list["key_code"])
|
|
|
|
if(GLOB._kbMap[new_key])
|
|
new_key = GLOB._kbMap[new_key]
|
|
|
|
var/full_key
|
|
switch(new_key)
|
|
if("Alt")
|
|
full_key = "[new_key][CtrlMod][ShiftMod]"
|
|
if("Ctrl")
|
|
full_key = "[AltMod][new_key][ShiftMod]"
|
|
if("Shift")
|
|
full_key = "[AltMod][CtrlMod][new_key]"
|
|
else
|
|
full_key = "[AltMod][CtrlMod][ShiftMod][numpad][new_key]"
|
|
if(independent)
|
|
modless_key_bindings -= old_key
|
|
modless_key_bindings[full_key] = kb_name
|
|
else
|
|
if(key_bindings[old_key])
|
|
key_bindings[old_key] -= kb_name
|
|
if(!length(key_bindings[old_key]))
|
|
key_bindings -= old_key
|
|
key_bindings[full_key] += list(kb_name)
|
|
key_bindings[full_key] = sort_list(key_bindings[full_key])
|
|
if(href_list["special"]) // special keys need a full reset
|
|
user.client.ensure_keys_set(src)
|
|
user << browse(null, "window=capturekeypress")
|
|
save_preferences()
|
|
|
|
if("keybindings_reset")
|
|
var/choice = tgalert(user, "Would you prefer 'hotkey' or 'classic' defaults?", "Setup keybindings", "Hotkey", "Classic", "Cancel")
|
|
if(choice == "Cancel")
|
|
ShowChoices(user)
|
|
return
|
|
hotkeys = (choice == "Hotkey")
|
|
key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key)
|
|
modless_key_bindings = list()
|
|
user.client.ensure_keys_set(src)
|
|
|
|
if("chat_on_map")
|
|
chat_on_map = !chat_on_map
|
|
if("see_chat_non_mob")
|
|
see_chat_non_mob = !see_chat_non_mob
|
|
//Sandstorm changes begin
|
|
if("see_chat_emotes")
|
|
see_chat_emotes = !see_chat_emotes
|
|
if("enable_personal_chat_color")
|
|
enable_personal_chat_color = !enable_personal_chat_color
|
|
//End of sandstorm changes
|
|
if("view_pixelshift") //SPLURT Edit
|
|
view_pixelshift = !view_pixelshift
|
|
if("tgui_fancy")
|
|
tgui_fancy = !tgui_fancy
|
|
if("tgui_input_mode")
|
|
tgui_input_mode = !tgui_input_mode
|
|
if("tgui_large_buttons")
|
|
tgui_large_buttons = !tgui_large_buttons
|
|
if("tgui_swapped_buttons")
|
|
tgui_swapped_buttons = !tgui_swapped_buttons
|
|
if("outline_enabled")
|
|
outline_enabled = !outline_enabled
|
|
if("outline_color")
|
|
var/pickedOutlineColor = input(user, "Choose your outline color.", "General Preference", outline_color) as color|null
|
|
if(pickedOutlineColor != outline_color)
|
|
outline_color = pickedOutlineColor // nullable
|
|
if("screentip_pref")
|
|
var/choice = input(user, "Choose your screentip preference", "Screentipping?", screentip_pref) as null|anything in GLOB.screentip_pref_options
|
|
if(choice)
|
|
screentip_pref = choice
|
|
if("screentip_color")
|
|
var/pickedScreentipColor = input(user, "Choose your screentip color.", "General Preference", screentip_color) as color|null
|
|
if(pickedScreentipColor)
|
|
screentip_color = pickedScreentipColor
|
|
if("screentip_images")
|
|
screentip_images = !screentip_images
|
|
if("tgui_lock")
|
|
tgui_lock = !tgui_lock
|
|
if("winflash")
|
|
windowflashing = !windowflashing
|
|
if("hear_adminhelps")
|
|
toggles ^= SOUND_ADMINHELP
|
|
if("announce_login")
|
|
toggles ^= ANNOUNCE_LOGIN
|
|
if("combohud_lighting")
|
|
toggles ^= COMBOHUD_LIGHTING
|
|
if("use_new_playerpanel")
|
|
use_new_playerpanel = !use_new_playerpanel
|
|
|
|
// Deadmin preferences
|
|
if("toggle_deadmin_always")
|
|
deadmin ^= DEADMIN_ALWAYS
|
|
if("toggle_deadmin_antag")
|
|
deadmin ^= DEADMIN_ANTAGONIST
|
|
if("toggle_deadmin_head")
|
|
deadmin ^= DEADMIN_POSITION_HEAD
|
|
if("toggle_deadmin_security")
|
|
deadmin ^= DEADMIN_POSITION_SECURITY
|
|
if("toggle_deadmin_silicon")
|
|
deadmin ^= DEADMIN_POSITION_SILICON
|
|
//
|
|
|
|
if("disable_antag")
|
|
toggles ^= NO_ANTAG
|
|
|
|
if("be_special")
|
|
var/be_special_type = href_list["be_special_type"]
|
|
if(be_special_type in be_special)
|
|
if(be_special[be_special_type] >= 1)
|
|
be_special -= be_special_type
|
|
else
|
|
be_special[be_special_type] = 1
|
|
else
|
|
be_special += be_special_type
|
|
be_special[be_special_type] = 0
|
|
|
|
if("name")
|
|
be_random_name = !be_random_name
|
|
|
|
if("all")
|
|
be_random_body = !be_random_body
|
|
|
|
if("hear_midis")
|
|
toggles ^= SOUND_MIDI
|
|
|
|
if("verb_consent") // Skyrat - ERP Mechanic Addition
|
|
toggles ^= VERB_CONSENT // Skyrat - ERP Mechanic Addition
|
|
|
|
if("lewd_verb_sounds") // Skyrat - ERP Mechanic Addition
|
|
toggles ^= LEWD_VERB_SOUNDS // Skyrat - ERP Mechanic Addition
|
|
|
|
if("persistent_scars")
|
|
persistent_scars = !persistent_scars
|
|
|
|
if("clear_scars")
|
|
to_chat(user, "<span class='notice'>All scar slots cleared. Please save character to confirm.</span>")
|
|
scars_list["1"] = ""
|
|
scars_list["2"] = ""
|
|
scars_list["3"] = ""
|
|
scars_list["4"] = ""
|
|
scars_list["5"] = ""
|
|
|
|
if("lobby_music")
|
|
toggles ^= SOUND_LOBBY
|
|
if((toggles & SOUND_LOBBY) && user.client && isnewplayer(user))
|
|
user.client.playtitlemusic()
|
|
else
|
|
user.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
|
|
|
if("ghost_ears")
|
|
chat_toggles ^= CHAT_GHOSTEARS
|
|
|
|
if("ghost_sight")
|
|
chat_toggles ^= CHAT_GHOSTSIGHT
|
|
|
|
if("ghost_whispers")
|
|
chat_toggles ^= CHAT_GHOSTWHISPER
|
|
|
|
if("ghost_radio")
|
|
chat_toggles ^= CHAT_GHOSTRADIO
|
|
|
|
if("ghost_pda")
|
|
chat_toggles ^= CHAT_GHOSTPDA
|
|
|
|
if("income_pings")
|
|
chat_toggles ^= CHAT_BANKCARD
|
|
|
|
if("pull_requests")
|
|
chat_toggles ^= CHAT_PULLR
|
|
|
|
if("allow_midround_antag")
|
|
toggles ^= MIDROUND_ANTAG
|
|
|
|
if("parallaxup")
|
|
parallax = WRAP(parallax + 1, PARALLAX_DISABLE, PARALLAX_INSANE + 1)
|
|
parent?.parallax_holder?.Reset()
|
|
|
|
if("parallaxdown")
|
|
parallax = WRAP(parallax - 1, PARALLAX_DISABLE, PARALLAX_INSANE + 1)
|
|
parent?.parallax_holder?.Reset()
|
|
|
|
// Citadel edit - Prefs don't work outside of this. :c
|
|
|
|
if("genital_examine")
|
|
cit_toggles ^= GENITAL_EXAMINE
|
|
|
|
if("vore_examine")
|
|
cit_toggles ^= VORE_EXAMINE
|
|
|
|
if("hound_sleeper")
|
|
cit_toggles ^= MEDIHOUND_SLEEPER
|
|
|
|
if("toggleeatingnoise")
|
|
cit_toggles ^= EATING_NOISES
|
|
|
|
if("toggledigestionnoise")
|
|
cit_toggles ^= DIGESTION_NOISES
|
|
|
|
if("toggleforcefeedtrash")
|
|
cit_toggles ^= TRASH_FORCEFEED
|
|
|
|
if("breast_enlargement")
|
|
cit_toggles ^= BREAST_ENLARGEMENT
|
|
|
|
if("penis_enlargement")
|
|
cit_toggles ^= PENIS_ENLARGEMENT
|
|
|
|
if("butt_enlargement")
|
|
cit_toggles ^= BUTT_ENLARGEMENT
|
|
|
|
if("belly_inflation")
|
|
cit_toggles ^= BELLY_INFLATION
|
|
|
|
if("feminization")
|
|
cit_toggles ^= FORCED_FEM
|
|
|
|
if("masculinization")
|
|
cit_toggles ^= FORCED_MASC
|
|
|
|
if("hypno")
|
|
cit_toggles ^= HYPNO
|
|
|
|
if("never_hypno")
|
|
cit_toggles ^= NEVER_HYPNO
|
|
|
|
if("aphro")
|
|
cit_toggles ^= NO_APHRO
|
|
|
|
if("ass_slap")
|
|
cit_toggles ^= NO_ASS_SLAP
|
|
|
|
if("bimbo")
|
|
cit_toggles ^= BIMBOFICATION
|
|
|
|
if("auto_wag")
|
|
cit_toggles ^= NO_AUTO_WAG
|
|
|
|
//END CITADEL EDIT
|
|
|
|
if("ambientocclusion")
|
|
ambientocclusion = !ambientocclusion
|
|
if(parent && parent.screen && parent.screen.len)
|
|
var/atom/movable/screen/plane_master/game_world/G = parent.mob.hud_used.plane_masters["[GAME_PLANE]"]
|
|
var/atom/movable/screen/plane_master/above_wall/A = parent.mob.hud_used.plane_masters["[ABOVE_WALL_PLANE]"]
|
|
var/atom/movable/screen/plane_master/wall/W = parent.mob.hud_used.plane_masters["[WALL_PLANE]"]
|
|
G.backdrop(parent.mob)
|
|
A.backdrop(parent.mob)
|
|
W.backdrop(parent.mob)
|
|
|
|
if("auto_fit_viewport")
|
|
auto_fit_viewport = !auto_fit_viewport
|
|
if(auto_fit_viewport && parent)
|
|
parent.fit_viewport()
|
|
|
|
if("hud_toggle_flash")
|
|
hud_toggle_flash = !hud_toggle_flash
|
|
|
|
if("barkpreview")
|
|
if(SSticker.current_state == GAME_STATE_STARTUP) //Timers don't tick at all during game startup, so let's just give an error message
|
|
to_chat(user, "<span class='warning'>Bark previews can't play during initialization!</span>")
|
|
return
|
|
if(!COOLDOWN_FINISHED(src, bark_previewing))
|
|
return
|
|
if(!parent || !parent.mob)
|
|
return
|
|
COOLDOWN_START(src, bark_previewing, (5 SECONDS))
|
|
var/atom/movable/barkbox = new(get_turf(parent.mob))
|
|
barkbox.set_bark(bark_id)
|
|
var/total_delay
|
|
for(var/i in 1 to (round((32 / bark_speed)) + 1))
|
|
addtimer(CALLBACK(barkbox, TYPE_PROC_REF(/atom/movable, bark), list(parent.mob), 7, 70, BARK_DO_VARY(bark_pitch, bark_variance)), total_delay)
|
|
total_delay += rand(DS2TICKS(bark_speed/4), DS2TICKS(bark_speed/4) + DS2TICKS(bark_speed/4)) TICKS
|
|
QDEL_IN(barkbox, total_delay)
|
|
|
|
if("save")
|
|
save_preferences()
|
|
save_character()
|
|
|
|
if("load")
|
|
load_preferences()
|
|
load_character()
|
|
|
|
if("changeslot")
|
|
if(char_queue)
|
|
deltimer(char_queue) // Do not dare.
|
|
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"])
|
|
//SPLURT edit
|
|
if("headshot")
|
|
var/usr_input = input(user, "Input the image link: (For Discord links, try putting the file's type at the end of the link, after the '&'. for example '&.jpg/.png/.jpeg')", "Headshot Image", features["headshot_link"]) as text|null
|
|
if(isnull(usr_input))
|
|
return
|
|
if(!usr_input)
|
|
features["headshot_link"] = null
|
|
return
|
|
|
|
var/static/link_regex = regex("^(https?|ftp):\\/\\/\[^\\s\\/$.?#].\[^\\s]*$") //Do not touch the damn duplicates.
|
|
var/static/end_regex = regex(".jpg|.jpg|.png|.jpeg|.jpeg") //Regex is terrible, don't touch the duplicate extensions
|
|
|
|
if(!findtext(usr_input, link_regex))
|
|
to_chat(usr, span_warning("You need a valid link!"))
|
|
return
|
|
if(!findtext(usr_input, end_regex, -8))
|
|
to_chat(usr, span_warning("You need either \".png\", \".jpg\", or \".jpeg\" in the link!"))
|
|
return
|
|
|
|
if(features["headshot_link"] != usr_input)
|
|
to_chat(usr, span_notice("If the photo doesn't show up properly in-game, ensure that it's a direct image link that opens properly in a browser."))
|
|
to_chat(usr, span_notice("Keep in mind that the photo will be downsized to 250x250 pixels, so the more square the photo, the better it will look."))
|
|
features["headshot_link"] = usr_input
|
|
|
|
if("character_preview")
|
|
preview_pref = href_list["tab"]
|
|
|
|
if("character_tab")
|
|
if(href_list["tab"])
|
|
character_settings_tab = text2num(href_list["tab"])
|
|
|
|
if("preferences_tab")
|
|
if(href_list["tab"])
|
|
preferences_tab = text2num(href_list["tab"])
|
|
|
|
if("chastitypref")
|
|
cit_toggles ^= CHASTITY
|
|
if("stimulationpref")
|
|
cit_toggles ^= STIMULATION
|
|
if("edgingpref")
|
|
cit_toggles ^= EDGING
|
|
if("cumontopref")
|
|
cit_toggles ^= CUM_ONTO
|
|
//
|
|
if("export_slot")
|
|
var/savefile/S = save_character(export = TRUE)
|
|
if(istype(S, /savefile))
|
|
user.client.Export(S)
|
|
tgui_alert_async(user, "Successfully saved character slot")
|
|
else
|
|
tgui_alert_async(user, "Failed saving character slot")
|
|
return
|
|
|
|
if("import_slot")
|
|
var/savefile/S = new(user.client.Import())
|
|
if(istype(S, /savefile))
|
|
if(load_character(provided = S))
|
|
tgui_alert_async(user, "Successfully loaded character slot.")
|
|
save_character(TRUE)
|
|
else
|
|
tgui_alert_async(user, "Failed loading character slot")
|
|
return
|
|
else
|
|
tgui_alert_async(user, "Failed loading character slot")
|
|
return
|
|
|
|
if("delete_local_copy")
|
|
user.client.clear_export()
|
|
tgui_alert_async(user, "Local save data erased.")
|
|
|
|
if("give_slot")
|
|
if(!QDELETED(offer))
|
|
var/datum/character_offer_instance/offer_datum = LAZYACCESS(GLOB.character_offers, offer.redemption_code)
|
|
if(!offer_datum)
|
|
return
|
|
qdel(offer_datum)
|
|
else
|
|
var/savefile/S = save_character(export = TRUE)
|
|
if(istype(S, /savefile))
|
|
var/datum/character_offer_instance/offer_datum = new(usr.ckey, S)
|
|
if(QDELETED(offer_datum))
|
|
tgui_alert_async(usr, "Could not set up offer, try again later")
|
|
return
|
|
offer_datum.RegisterSignal(usr, COMSIG_MOB_CLIENT_LOGOUT, TYPE_PROC_REF(/datum/character_offer_instance, on_quit))
|
|
offer = offer_datum
|
|
tgui_alert_async(usr, "The redemption code is [offer_datum.redemption_code], give it to the receiver")
|
|
|
|
if("retrieve_slot")
|
|
if(!LAZYLEN(GLOB.character_offers))
|
|
tgui_alert_async(usr, "There are no active offers")
|
|
return
|
|
var/retrieve_code = input(usr, "Input the 5 digit redemption code") as text|null
|
|
if(!retrieve_code)
|
|
return
|
|
if(!text2num(retrieve_code))
|
|
tgui_alert_async(usr, "Only numbers allowed")
|
|
return
|
|
if(length(retrieve_code) != 5)
|
|
tgui_alert_async(usr, "Exactly 5 digits, no less, no more, try again")
|
|
return
|
|
var/datum/character_offer_instance/offer_datum = LAZYACCESS(GLOB.character_offers, retrieve_code)
|
|
if(!offer_datum)
|
|
tgui_alert_async(usr, "This is an invalid code!")
|
|
return
|
|
if(offer == offer_datum)
|
|
tgui_alert_async(usr, "You cannot accept your own offer")
|
|
return
|
|
var/savefile/savefile = offer_datum.character_savefile
|
|
var/mob/living/the_owner = get_mob_by_ckey(offer_datum.owner_ckey)
|
|
if(savefile_needs_update(savefile) == -2)
|
|
tgui_alert_async(usr, "Something's wrong, this savefile is corrupted.")
|
|
to_chat(the_owner, span_boldwarning("Something went wrong with the trade, it's been canceled."))
|
|
qdel(offer_datum)
|
|
return
|
|
var/character_name = savefile["real_name"]
|
|
if(alert(usr, "You are overwriting the currently selected slot with the character [character_name]", "Are you sure?", "Yes, load this character deleting the currently selected slot", "No") == "No")
|
|
return
|
|
if(QDELETED(offer_datum))
|
|
tgui_alert_async(usr, "This character is no longer available, such a shame!")
|
|
return
|
|
to_chat(the_owner, span_boldwarning("[usr.key] has retrieved your character, [character_name]!"))
|
|
if(!load_character(provided = savefile))
|
|
tgui_alert_async(usr, "Something went wrong loading the savefile, even though it has already been checked, please report this issue!")
|
|
to_chat(the_owner, span_boldwarning("Something went wrong at the final step of the trade, report this."))
|
|
qdel(offer_datum)
|
|
return
|
|
tgui_alert_async(usr, "Successfully received [character_name]!")
|
|
save_character(TRUE)
|
|
qdel(offer_datum)
|
|
|
|
if(href_list["preference"] == "gear")
|
|
if(href_list["clear_loadout"])
|
|
loadout_data["SAVE_[loadout_slot]"] = list()
|
|
save_preferences()
|
|
if(href_list["select_category"])
|
|
gear_category = html_decode(href_list["select_category"])
|
|
gear_subcategory = GLOB.loadout_categories[gear_category][1]
|
|
if(href_list["select_subcategory"])
|
|
gear_subcategory = html_decode(href_list["select_subcategory"])
|
|
if(href_list["toggle_gear_path"])
|
|
var/name = html_decode(href_list["toggle_gear_path"])
|
|
var/datum/gear/G = GLOB.loadout_items[gear_category][gear_subcategory][name]
|
|
if(!G)
|
|
return
|
|
var/toggle = text2num(href_list["toggle_gear"])
|
|
if(!toggle && has_loadout_gear(loadout_slot, "[G.type]"))//toggling off and the item effectively is in chosen gear)
|
|
remove_gear_from_loadout(loadout_slot, "[G.type]")
|
|
else if(toggle && !(has_loadout_gear(loadout_slot, "[G.type]")))
|
|
if(!is_loadout_slot_available(G.category))
|
|
to_chat(user, "<span class='danger'>You cannot take this loadout, as you've already chosen too many of the same category!</span>")
|
|
return
|
|
if(G.donoritem && !G.donator_ckey_check(user.ckey))
|
|
to_chat(user, "<span class='danger'>This is an item intended for donator use only. You are not authorized to use this item.</span>")
|
|
return
|
|
if(istype(G, /datum/gear/unlockable) && !can_use_unlockable(G))
|
|
to_chat(user, "<span class='danger'>To use this item, you need to meet the defined requirements!</span>")
|
|
return
|
|
if(gear_points >= initial(G.cost))
|
|
var/list/new_loadout_data = list(LOADOUT_ITEM = "[G.type]")
|
|
if(length(G.loadout_initial_colors))
|
|
new_loadout_data[LOADOUT_COLOR] = G.loadout_initial_colors
|
|
else
|
|
new_loadout_data[LOADOUT_COLOR] = list("#FFFFFF")
|
|
if(loadout_data["SAVE_[loadout_slot]"])
|
|
loadout_data["SAVE_[loadout_slot]"] += list(new_loadout_data) //double packed because it does the union of the CONTENTS of the lists
|
|
else
|
|
loadout_data["SAVE_[loadout_slot]"] = list(new_loadout_data) //double packed because you somehow had no save slot in your loadout?
|
|
if(href_list["clear_invalid_gear"])
|
|
var/thing_to_remove = html_decode(href_list["clear_invalid_gear"])
|
|
if(!thing_to_remove)
|
|
return
|
|
var/list/sanitize_current_slot = loadout_data["SAVE_[loadout_slot]"]
|
|
for(var/list/entry in sanitize_current_slot)
|
|
if(entry["loadout_item"] == thing_to_remove)
|
|
sanitize_current_slot.Remove(list(entry))
|
|
break
|
|
|
|
if(href_list["loadout_color"] || href_list["loadout_color_polychromic"] || href_list["loadout_color_HSV"] || href_list["loadout_rename"] || href_list["loadout_redescribe"])
|
|
//if the gear doesn't exist, or they don't have it, ignore the request
|
|
var/name = html_decode(href_list["loadout_gear_name"])
|
|
var/datum/gear/G = GLOB.loadout_items[gear_category][gear_subcategory][name]
|
|
if(!G)
|
|
return
|
|
var/user_gear = has_loadout_gear(loadout_slot, "[G.type]")
|
|
if(!user_gear)
|
|
return
|
|
|
|
//possible requests: recolor, recolor (polychromic), rename, redescribe
|
|
//always make sure the gear allows said request before proceeding
|
|
|
|
//non-poly coloring can only be done by non-poly items
|
|
if(href_list["loadout_color"] && !(G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC))
|
|
if(!length(user_gear[LOADOUT_COLOR]))
|
|
user_gear[LOADOUT_COLOR] = list("#FFFFFF")
|
|
var/current_color = user_gear[LOADOUT_COLOR][1]
|
|
var/new_color = input(user, "Polychromic options", "Choose Color", current_color) as color|null
|
|
user_gear[LOADOUT_COLOR][1] = sanitize_hexcolor(new_color, 6, TRUE, current_color)
|
|
|
|
// HSV Coloring (SPLURT EDIT)
|
|
if(href_list["loadout_color_HSV"] && !(G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC))
|
|
var/hue = input(user, "Enter Hue (0-360)", "HSV options") as num|null
|
|
var/saturation = input(user, "Enter Saturation (-10 to 10)", "HSV options") as num|null
|
|
var/value = input(user, "Enter Value (-10 to 10)", "HSV options") as num|null
|
|
if(hue && saturation && value)
|
|
saturation = clamp(saturation, -10, 10)
|
|
value = clamp(value, -10, 10)
|
|
var/color_to_use = color_matrix_hsv(hue, saturation, value)
|
|
user_gear[LOADOUT_COLOR][1] = color_to_use
|
|
|
|
//poly coloring can only be done by poly items
|
|
if(href_list["loadout_color_polychromic"] && (G.loadout_flags & LOADOUT_CAN_COLOR_POLYCHROMIC))
|
|
var/list/color_options = list()
|
|
for(var/i=1, i<=length(G.loadout_initial_colors), i++)
|
|
color_options += "Color [i]"
|
|
var/color_to_change = input(user, "Polychromic options", "Recolor [name]") as null|anything in color_options
|
|
if(color_to_change)
|
|
var/color_index = text2num(copytext(color_to_change, 7))
|
|
var/current_color = user_gear[LOADOUT_COLOR][color_index]
|
|
var/new_color = input(user, "Polychromic options", "Choose [color_to_change] Color", current_color) as color|null
|
|
if(new_color)
|
|
user_gear[LOADOUT_COLOR][color_index] = sanitize_hexcolor(new_color, 6, TRUE, current_color)
|
|
|
|
//both renaming and redescribing strip the input to stop html injection
|
|
|
|
//renaming is only allowed if it has the flag for it
|
|
if(href_list["loadout_rename"] && (G.loadout_flags & LOADOUT_CAN_NAME))
|
|
var/new_name = stripped_input(user, "Enter new name for item. Maximum [MAX_NAME_LEN] characters.", "Loadout Item Naming", null, MAX_NAME_LEN)
|
|
if(new_name)
|
|
user_gear[LOADOUT_CUSTOM_NAME] = new_name
|
|
|
|
//redescribing is only allowed if it has the flag for it
|
|
if(href_list["loadout_redescribe"] && (G.loadout_flags & LOADOUT_CAN_DESCRIPTION)) //redescribe isnt a real word but i can't think of the right term to use
|
|
var/new_description = stripped_input(user, "Enter new description for item. Maximum 500 characters.", "Loadout Item Redescribing", null, 500)
|
|
if(new_description)
|
|
user_gear[LOADOUT_CUSTOM_DESCRIPTION] = new_description
|
|
|
|
ShowChoices(user)
|
|
return TRUE
|
|
|
|
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1, roundstart_checks = TRUE, initial_spawn = FALSE)
|
|
if(be_random_name)
|
|
real_name = pref_species.random_name(gender)
|
|
|
|
if(be_random_body)
|
|
random_character(gender)
|
|
|
|
if(roundstart_checks)
|
|
if(CONFIG_GET(flag/humans_need_surnames) && (pref_species.id == "human"))
|
|
var/firstspace = findtext(real_name, " ")
|
|
var/name_length = length(real_name)
|
|
if(!firstspace) //we need a surname
|
|
real_name += " [pick(GLOB.last_names)]"
|
|
else if(firstspace == name_length)
|
|
real_name += "[pick(GLOB.last_names)]"
|
|
|
|
//reset size if applicable
|
|
if(character.dna.features["body_size"])
|
|
var/initial_old_size = character.dna.features["body_size"]
|
|
character.update_size(RESIZE_DEFAULT_SIZE, initial_old_size)
|
|
|
|
character.real_name = nameless ? "[real_name] #[rand(10000, 99999)]" : real_name
|
|
character.name = character.real_name
|
|
character.nameless = nameless
|
|
character.custom_species = custom_species
|
|
|
|
character.gender = gender
|
|
character.age = age
|
|
|
|
character.left_eye_color = left_eye_color
|
|
character.right_eye_color = right_eye_color
|
|
var/obj/item/organ/eyes/organ_eyes = character.getorgan(/obj/item/organ/eyes)
|
|
if(organ_eyes)
|
|
if(!initial(organ_eyes.left_eye_color))
|
|
organ_eyes.left_eye_color = left_eye_color
|
|
organ_eyes.right_eye_color = right_eye_color
|
|
organ_eyes.old_left_eye_color = left_eye_color
|
|
organ_eyes.old_right_eye_color = right_eye_color
|
|
character.hair_color = hair_color
|
|
character.facial_hair_color = facial_hair_color
|
|
character.skin_tone = skin_tone
|
|
character.dna.skin_tone_override = use_custom_skin_tone ? skin_tone : null
|
|
character.hair_style = hair_style
|
|
character.facial_hair_style = facial_hair_style
|
|
character.grad_style = grad_style
|
|
character.grad_color = grad_color
|
|
/* skyrat edit
|
|
character.underwear = underwear
|
|
|
|
character.saved_underwear = underwear
|
|
character.undershirt = undershirt
|
|
character.saved_undershirt = undershirt
|
|
character.socks = socks
|
|
character.saved_socks = socks
|
|
*/
|
|
character.undie_color = undie_color
|
|
character.shirt_color = shirt_color
|
|
character.socks_color = socks_color
|
|
|
|
var/datum/species/chosen_species
|
|
if(!roundstart_checks || (pref_species.id in GLOB.roundstart_races))
|
|
chosen_species = pref_species.type
|
|
else
|
|
chosen_species = /datum/species/human
|
|
pref_species = new /datum/species/human
|
|
save_character()
|
|
|
|
character.dna.features = features.Copy()
|
|
|
|
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
|
|
character.dna.species.eye_type = eye_type
|
|
if(chosen_limb_id && (chosen_limb_id in character.dna.species.allowed_limb_ids))
|
|
character.dna.species.mutant_bodyparts["limbs_id"] = chosen_limb_id
|
|
character.dna.real_name = character.real_name
|
|
character.dna.nameless = character.nameless
|
|
character.dna.custom_species = character.custom_species
|
|
// Added by SPLURT (Custom Blood Color)
|
|
if(custom_blood_color)
|
|
character.dna.species.exotic_blood_color = blood_color
|
|
|
|
var/old_size = RESIZE_DEFAULT_SIZE
|
|
if(isdwarf(character))
|
|
character.dna.features["body_size"] = RESIZE_DEFAULT_SIZE
|
|
|
|
if((parent && parent.can_have_part("meat_type")) || pref_species.mutant_bodyparts["meat_type"])
|
|
character.type_of_meat = GLOB.meat_types[features["meat_type"]]
|
|
|
|
if(((parent && parent.can_have_part("legs")) || pref_species.mutant_bodyparts["legs"]) && (character.dna.features["legs"] == "Digitigrade" || character.dna.features["legs"] == "Avian"))
|
|
pref_species.species_traits |= DIGITIGRADE
|
|
else
|
|
pref_species.species_traits -= DIGITIGRADE
|
|
|
|
if(DIGITIGRADE in pref_species.species_traits)
|
|
character.Digitigrade_Leg_Swap(FALSE)
|
|
else
|
|
character.Digitigrade_Leg_Swap(TRUE)
|
|
|
|
character.dna.features["lust_tolerance"] = lust_tolerance
|
|
character.dna.features["sexual_potency"] = sexual_potency
|
|
|
|
if(features["anus_accessible"])
|
|
character.toggle_anus_always_accessible(TRUE)
|
|
|
|
character.give_genitals(TRUE) //character.update_genitals() is already called on genital.update_appearance()
|
|
|
|
character.update_size(get_size(character), old_size)
|
|
|
|
//speech stuff
|
|
if(custom_tongue != "default")
|
|
var/new_tongue = GLOB.roundstart_tongues[custom_tongue]
|
|
if(new_tongue)
|
|
character.dna.species.mutanttongue = new_tongue //this means we get our tongue when we clone
|
|
var/obj/item/organ/tongue/T = character.getorganslot(ORGAN_SLOT_TONGUE)
|
|
if(T)
|
|
qdel(T)
|
|
var/obj/item/organ/tongue/new_custom_tongue = new new_tongue
|
|
new_custom_tongue.Insert(character)
|
|
if(custom_speech_verb != "default")
|
|
character.dna.species.say_mod = custom_speech_verb
|
|
|
|
character.set_bark(bark_id)
|
|
character.vocal_speed = bark_speed
|
|
character.vocal_pitch = bark_pitch
|
|
character.vocal_pitch_range = bark_variance
|
|
|
|
//limb stuff, only done when initially spawning in
|
|
if(initial_spawn)
|
|
//delete any existing prosthetic limbs to make sure no remnant prosthetics are left over - But DO NOT delete those that are species-related
|
|
for(var/obj/item/bodypart/part in character.bodyparts)
|
|
if(part.is_robotic_limb(FALSE))
|
|
qdel(part)
|
|
character.regenerate_limbs() //regenerate limbs so now you only have normal limbs
|
|
for(var/modified_limb in modified_limbs)
|
|
var/modification = modified_limbs[modified_limb][1]
|
|
var/obj/item/bodypart/old_part = character.get_bodypart(modified_limb)
|
|
if(modification == LOADOUT_LIMB_PROSTHETIC)
|
|
var/obj/item/bodypart/new_limb
|
|
switch(modified_limb)
|
|
if(BODY_ZONE_L_ARM)
|
|
new_limb = new/obj/item/bodypart/l_arm/robot/surplus(character)
|
|
if(BODY_ZONE_R_ARM)
|
|
new_limb = new/obj/item/bodypart/r_arm/robot/surplus(character)
|
|
if(BODY_ZONE_L_LEG)
|
|
new_limb = new/obj/item/bodypart/l_leg/robot/surplus(character)
|
|
if(BODY_ZONE_R_LEG)
|
|
new_limb = new/obj/item/bodypart/r_leg/robot/surplus(character)
|
|
var/prosthetic_type = modified_limbs[modified_limb][2]
|
|
if(prosthetic_type != "prosthetic") //lets just leave the old sprites as they are
|
|
new_limb.icon = file("icons/mob/augmentation/cosmetic_prosthetic/[prosthetic_type].dmi")
|
|
new_limb.replace_limb(character)
|
|
qdel(old_part)
|
|
|
|
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
|
|
|
|
//let's be sure the character updates
|
|
if(icon_updates)
|
|
character.update_body()
|
|
character.update_hair()
|
|
|
|
/datum/preferences/proc/post_copy_to(mob/living/carbon/human/character)
|
|
//if no legs, and not a paraplegic or a slime, give them a free wheelchair
|
|
if(modified_limbs[BODY_ZONE_L_LEG] == LOADOUT_LIMB_AMPUTATED && modified_limbs[BODY_ZONE_R_LEG] == LOADOUT_LIMB_AMPUTATED && !character.has_quirk(/datum/quirk/paraplegic) && !isjellyperson(character))
|
|
if(character.buckled)
|
|
character.buckled.unbuckle_mob(character)
|
|
var/turf/T = get_turf(character)
|
|
var/obj/structure/chair/spawn_chair = locate() in T
|
|
var/obj/vehicle/ridden/wheelchair/wheels = new(T)
|
|
if(spawn_chair) // Makes spawning on the arrivals shuttle more consistent looking
|
|
wheels.setDir(spawn_chair.dir)
|
|
wheels.buckle_mob(character)
|
|
|
|
/datum/preferences/proc/get_default_name(name_id)
|
|
switch(name_id)
|
|
if("human")
|
|
return random_unique_name()
|
|
if("ai")
|
|
return pick(GLOB.ai_names)
|
|
if("cyborg")
|
|
return DEFAULT_CYBORG_NAME
|
|
if("clown")
|
|
return pick(GLOB.clown_names)
|
|
if("mime")
|
|
return pick(GLOB.mime_names)
|
|
return random_unique_name()
|
|
|
|
/datum/preferences/proc/ask_for_custom_name(mob/user,name_id)
|
|
var/namedata = GLOB.preferences_custom_names[name_id]
|
|
if(!namedata)
|
|
return
|
|
|
|
var/raw_name = input(user, "Choose your character's [namedata["qdesc"]]:","Character Preference") as text|null
|
|
if(!raw_name)
|
|
if(namedata["allow_null"])
|
|
custom_names[name_id] = get_default_name(name_id)
|
|
else
|
|
return
|
|
else
|
|
var/sanitized_name = reject_bad_name(raw_name,namedata["allow_numbers"])
|
|
if(!sanitized_name)
|
|
to_chat(user, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z,[namedata["allow_numbers"] ? ",0-9," : ""] -, ' and .</font>")
|
|
return
|
|
else
|
|
custom_names[name_id] = sanitized_name
|
|
|
|
/datum/preferences/proc/get_filtered_holoform(filter_type)
|
|
if(!custom_holoform_icon)
|
|
return
|
|
LAZYINITLIST(cached_holoform_icons)
|
|
if(!cached_holoform_icons[filter_type])
|
|
cached_holoform_icons[filter_type] = process_holoform_icon_filter(custom_holoform_icon, filter_type)
|
|
return cached_holoform_icons[filter_type]
|
|
|
|
/// Resets the client's keybindings. Asks them for which
|
|
/datum/preferences/proc/force_reset_keybindings()
|
|
var/choice = tgalert(parent.mob, "Your basic keybindings need to be reset, emotes will remain as before. Would you prefer 'hotkey' or 'classic' mode?", "Reset keybindings", "Hotkey", "Classic")
|
|
hotkeys = (choice != "Classic")
|
|
force_reset_keybindings_direct(hotkeys)
|
|
|
|
/// Does the actual reset
|
|
/datum/preferences/proc/force_reset_keybindings_direct(hotkeys = TRUE)
|
|
var/list/oldkeys = key_bindings
|
|
key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key)
|
|
|
|
for(var/key in oldkeys)
|
|
if(!key_bindings[key])
|
|
key_bindings[key] = oldkeys[key]
|
|
parent?.ensure_keys_set(src)
|
|
|
|
/datum/preferences/proc/is_loadout_slot_available(slot)
|
|
var/list/L
|
|
LAZYINITLIST(L)
|
|
for(var/i in loadout_data["SAVE_[loadout_slot]"])
|
|
var/datum/gear/G = i[LOADOUT_ITEM]
|
|
var/occupied_slots = L[initial(G.category)] ? L[initial(G.category)] + 1 : 1
|
|
LAZYSET(L, initial(G.category), occupied_slots)
|
|
switch(slot)
|
|
if(ITEM_SLOT_BACKPACK)
|
|
if(L[LOADOUT_CATEGORY_BACKPACK] < BACKPACK_SLOT_AMT)
|
|
return TRUE
|
|
if(ITEM_SLOT_HANDS)
|
|
if(L[LOADOUT_CATEGORY_HANDS] < HANDS_SLOT_AMT)
|
|
return TRUE
|
|
else
|
|
if(L[slot] < DEFAULT_SLOT_AMT)
|
|
return TRUE
|
|
|
|
/datum/preferences/proc/has_loadout_gear(save_slot, gear_type)
|
|
var/list/gear_list = loadout_data["SAVE_[save_slot]"]
|
|
for(var/loadout_gear in gear_list)
|
|
if(loadout_gear[LOADOUT_ITEM] == gear_type)
|
|
return loadout_gear
|
|
return FALSE
|
|
|
|
/datum/preferences/proc/remove_gear_from_loadout(save_slot, gear_type)
|
|
var/find_gear = has_loadout_gear(save_slot, gear_type)
|
|
if(find_gear)
|
|
loadout_data["SAVE_[save_slot]"] -= list(find_gear)
|
|
|
|
/datum/preferences/proc/can_use_unlockable(datum/gear/unlockable/unlockable_gear)
|
|
if(unlockable_loadout_data[unlockable_gear.progress_key] >= unlockable_gear.progress_required)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
#undef DEFAULT_SLOT_AMT
|
|
#undef HANDS_SLOT_AMT
|
|
#undef BACKPACK_SLOT_AMT
|