* part 1 - resist out of resting, move and interact with the world while resting, and stamina regen nerf * makes beepsky check for stuns instead of knockdowns, adds message for getting up, makes gravity reduce standup time, and more * sprinting, staminacrit, balance changes, and more * adds stamina modifier to clickdelay, makes items deal stamina damage to the user when attacking, buffs resting stamina regen * combat mode, ability to toggle right-click context menu on/off, basic combat mode QOL, lays groundwork for 2-handing any item combat mode toggle sound is from Interbay. * commits dme changes * unarmed combat stamina, ability to right click in combat mode, balance changes * tosses in the HUD icons for later-ish * rolls back admin.txt * lotsa UI stuff * stamina checks, some balance stuff * adds support for best ui, adds right click to flush disposals, removes aggressive grab pinning in favor of neckgrab chokeholding * quick dogborg patch while i figure out what do do with them * oops - fixes prefbreaking for screenshake * trying to sprint from an elevated surface onto lower ground will now knock you down * right click to pull fire alarm, lets you bully people by pulling chairs out form under them, makes attacking objects cost stamina * makes accidents during slipping less likely to occur while combat mode is active, makes tripping off elevated surfaces cause accidents * makes pumping shotguns cost a tiiiny bit of stamina * makes eyestabbing and batoning cost stamina * makes failing stamina checks error out properly, adds stamina check to shotgun pumping * adds stamina check for chair pulling * readds aggressive grab pinning * fixes bug with being buckled preventing interaction * adds recoveringstam check to incapacitated * reduces stamina cost for attacking * oh this too * fixes bug where you can get stuck in recoveringstam if your stamina suddenly becomes 0 while you're in staminacrit * makes monkey transformation inherit staminaloss * adds the ability to wave or shake your fist at someone via right click * grammar and span closing * 99 annoying little bugs on the wall, 99 annoying little bugs. take one down, pass it around, 864 gamebreaking bugs on the wall * more distant right-click emotes. * buffs standing stamina regen a tiiiiiiny bit * adds aiming down sights for guns, makes firing guns cause trace amounts of staminaloss * crusher powercreep - gives crushers the ability to heal staminaloss * item throwing buff * adds 1:1 HUD layout * hopefully fixes issue with recoveringstamcrit not updating * giant hipfire nerf * halves the effect of staminaloss on movement speed * makes stamina recover faster in staminacrit, makes it easier to get disarmed out of combat mode * get_weight(), movedelay health_deficiency tweaking, combat and resting checks for item attacking * makes staminacrit automatically disable combat mode, it's now impossible to enter combat mode while in stamcrit * adds stamina buffer, halves the time needed to stand up after resting, increases stam penalty for firing weapons, and more * tweaks stamina buffer drain rate a little * makes buffered staminaloss redirect stamina to the actual stamloss proc when empty, makes stamina buffer stat() more precise * removes stamina modifier for clickdelays, makes stunbatons deal extra staminaloss * makes electrodes deal a lil extra staminaloss * drones cannot resist a rest, so now only carbons are forced to rest * restricts aiming down sights to carbon mobs, adds stamina display to stat() * makes gun accuracy and stamcosts more flexible, decreases base inaccuracy penalty, makes borgs immune to inaccuracy penalties * nerfs inaccuracy penalties just a lil more, fixes blooddrunk miner eye depleting all your stamina * getting used to tortoisegit * readds temp dogborg buff * stamina and stamina buffer HUD displays. Stamina sprite from hippiestation * makes afterattack call properly again * decreases stamina buffer regen time to 3 seconds * Yknow what? decreases it to 2 seconds. That's 3 entire attacks worth of waiting * makes stamina buffer influence movespeed a lil * nerfs compiling errors * tweaks the icons a little * adds autostanding, adds delimiters to attempts to stand * makes automatic standup attempts a little clearer * rest button now toggles intent to rest, fixes perma rest * oop - quick fixes * Makes crushers ignore recoil stamina on lavaland, makes burstfiring weapons deal less staminaloss * buffs highlander sword * makes stamina have less of an impact on the health display * fixes dogborgs shoving other borgs into infinite stuns * You can no longer shoot over tables or shoot through windows while resting. Also buffs turrets
1932 lines
84 KiB
Plaintext
1932 lines
84 KiB
Plaintext
/* CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! *\
|
|
| THIS FILE CONTAINS A SHITTON OF |
|
|
| CHANGES SPECIFIC TO CITADEL. IF |
|
|
| YOU'RE FIXING A MERGE CONFLICT |
|
|
| HERE, PLEASE ASK FOR REVIEW FROM |
|
|
| ANOTHER MAINTAINER TO ENSURE YOU |
|
|
| DON'T INTRODUCE REGRESSIONS. |
|
|
\* */
|
|
|
|
GLOBAL_LIST_EMPTY(preferences_datums)
|
|
|
|
|
|
|
|
/datum/preferences
|
|
var/client/parent
|
|
//doohickeys for savefiles
|
|
var/path
|
|
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
|
|
var/max_save_slots = 10
|
|
|
|
//non-preference stuff
|
|
var/muted = 0
|
|
var/last_ip
|
|
var/last_id
|
|
|
|
//game-preferences
|
|
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
|
|
var/ooccolor = null
|
|
var/enable_tips = TRUE
|
|
var/tip_delay = 500 //tip delay in milliseconds
|
|
|
|
//Antag preferences
|
|
var/list/be_special = list() //Special role selection
|
|
var/tmp/old_be_special = 0 //Bitflag version of be_special, used to update old savefiles and nothing more
|
|
//If it's 0, that's good, if it's anything but 0, the owner of this prefs file's antag choices were,
|
|
//autocorrected this round, not that you'd need to check that.
|
|
|
|
|
|
var/UI_style = "Midnight"
|
|
var/buttons_locked = FALSE
|
|
var/hotkeys = FALSE
|
|
var/tgui_fancy = TRUE
|
|
var/tgui_lock = TRUE
|
|
var/windowflashing = TRUE
|
|
var/toggles = TOGGLES_DEFAULT
|
|
var/db_flags
|
|
var/chat_toggles = TOGGLES_DEFAULT_CHAT
|
|
var/ghost_form = "ghost"
|
|
var/ghost_orbit = GHOST_ORBIT_CIRCLE
|
|
var/ghost_accs = GHOST_ACCS_DEFAULT_OPTION
|
|
var/ghost_others = GHOST_OTHERS_DEFAULT_OPTION
|
|
var/ghost_hud = 1
|
|
var/inquisitive_ghost = 1
|
|
var/allow_midround_antag = 1
|
|
var/preferred_map = null
|
|
var/pda_style = MONO
|
|
var/pda_color = "#808000"
|
|
|
|
var/uses_glasses_colour = 0
|
|
|
|
//character preferences
|
|
var/real_name //our character's name
|
|
var/be_random_name = 0 //whether we'll have a random name every round
|
|
var/be_random_body = 0 //whether we'll have a random body every round
|
|
var/gender = MALE //gender of character (well duh)
|
|
var/age = 30 //age of character
|
|
var/underwear = "Nude" //underwear type
|
|
var/undershirt = "Nude" //undershirt type
|
|
var/socks = "Nude" //socks type
|
|
var/backbag = DBACKPACK //backpack type
|
|
var/hair_style = "Bald" //Hair type
|
|
var/hair_color = "000" //Hair color
|
|
var/facial_hair_style = "Shaved" //Face hair type
|
|
var/facial_hair_color = "000" //Facial hair color
|
|
var/skin_tone = "caucasian1" //Skin color
|
|
var/eye_color = "000" //Eye color
|
|
var/datum/species/pref_species = new /datum/species/human() //Mutant race
|
|
var/list/features = list("mcolor" = "FFF",
|
|
"tail_lizard" = "Smooth",
|
|
"tail_human" = "None",
|
|
"snout" = "Round",
|
|
"horns" = "None",
|
|
"ears" = "None",
|
|
"wings" = "None",
|
|
"frills" = "None",
|
|
"spines" = "None",
|
|
"body_markings" = "None",
|
|
"legs" = "Normal Legs",
|
|
"moth_wings" = "Plain",
|
|
"mcolor2" = "FFF",
|
|
"mcolor3" = "FFF",
|
|
"mam_body_markings" = "None",
|
|
"mam_ears" = "None",
|
|
"mam_tail" = "None",
|
|
"mam_tail_animated" = "None",
|
|
"xenodorsal" = "None",
|
|
"xenohead" = "None",
|
|
"xenotail" = "None",
|
|
"taur" = "None",
|
|
"exhibitionist" = FALSE,
|
|
"genitals_use_skintone" = FALSE,
|
|
"has_cock" = FALSE,
|
|
"cock_shape" = "Human",
|
|
"cock_length" = 6,
|
|
"cock_girth_ratio" = COCK_GIRTH_RATIO_DEF,
|
|
"cock_color" = "fff",
|
|
"has_sheath" = FALSE,
|
|
"sheath_color" = "fff",
|
|
"has_balls" = FALSE,
|
|
"balls_internal" = FALSE,
|
|
"balls_color" = "fff",
|
|
"balls_amount" = 2,
|
|
"balls_sack_size" = BALLS_SACK_SIZE_DEF,
|
|
"balls_size" = BALLS_SIZE_DEF,
|
|
"balls_cum_rate" = CUM_RATE,
|
|
"balls_cum_mult" = CUM_RATE_MULT,
|
|
"balls_efficiency" = CUM_EFFICIENCY,
|
|
"balls_fluid" = "semen",
|
|
"has_ovi" = FALSE,
|
|
"ovi_shape" = "knotted",
|
|
"ovi_length" = 6,
|
|
"ovi_color" = "fff",
|
|
"has_eggsack" = FALSE,
|
|
"eggsack_internal" = TRUE,
|
|
"eggsack_color" = "fff",
|
|
"eggsack_size" = BALLS_SACK_SIZE_DEF,
|
|
"eggsack_egg_color" = "fff",
|
|
"eggsack_egg_size" = EGG_GIRTH_DEF,
|
|
"has_breasts" = FALSE,
|
|
"breasts_color" = "fff",
|
|
"breasts_size" = "C",
|
|
"breasts_shape" = "Pair",
|
|
"breasts_fluid" = "milk",
|
|
"has_vag" = FALSE,
|
|
"vag_shape" = "Human",
|
|
"vag_color" = "fff",
|
|
"vag_clits" = 1,
|
|
"vag_clit_diam" = 0.25,
|
|
"has_womb" = FALSE,
|
|
"womb_cum_rate" = CUM_RATE,
|
|
"womb_cum_mult" = CUM_RATE_MULT,
|
|
"womb_efficiency" = CUM_EFFICIENCY,
|
|
"womb_fluid" = "femcum",
|
|
"flavor_text" = "")
|
|
|
|
var/list/custom_names = list("human", "clown", "mime", "ai", "cyborg", "religion", "deity")
|
|
var/prefered_security_department = SEC_DEPT_RANDOM
|
|
|
|
//Mob preview
|
|
var/icon/preview_icon = null
|
|
|
|
//Trait list
|
|
var/list/positive_traits = list()
|
|
var/list/negative_traits = list()
|
|
var/list/neutral_traits = list()
|
|
var/list/all_traits = list()
|
|
var/list/character_traits = list()
|
|
|
|
//Jobs, uses bitflags
|
|
var/job_civilian_high = 0
|
|
var/job_civilian_med = 0
|
|
var/job_civilian_low = 0
|
|
|
|
var/job_medsci_high = 0
|
|
var/job_medsci_med = 0
|
|
var/job_medsci_low = 0
|
|
|
|
var/job_engsec_high = 0
|
|
var/job_engsec_med = 0
|
|
var/job_engsec_low = 0
|
|
|
|
// Want randomjob if preferences already filled - Donkie
|
|
var/joblessrole = BERANDOMJOB //defaults to 1 for fewer assistants
|
|
|
|
// 0 = character settings, 1 = game preferences, 2 = character appearance
|
|
var/current_tab = 0
|
|
|
|
// OOC Metadata:
|
|
var/metadata = ""
|
|
|
|
var/unlock_content = 0
|
|
|
|
var/list/ignoring = list()
|
|
|
|
var/clientfps = 0
|
|
|
|
var/parallax
|
|
|
|
var/uplink_spawn_loc = UPLINK_PDA
|
|
|
|
var/list/exp = list()
|
|
var/list/menuoptions
|
|
|
|
var/action_buttons_screen_locs = list()
|
|
|
|
|
|
/datum/preferences/New(client/C)
|
|
parent = C
|
|
custom_names["human"] = random_unique_name()
|
|
custom_names["ai"] = pick(GLOB.ai_names)
|
|
custom_names["cyborg"] = pick(GLOB.ai_names)
|
|
custom_names["clown"] = pick(GLOB.clown_names)
|
|
custom_names["mime"] = pick(GLOB.mime_names)
|
|
if(istype(C))
|
|
if(!IsGuestKey(C.key))
|
|
load_path(C.ckey)
|
|
unlock_content = C.IsByondMember()
|
|
if(unlock_content)
|
|
max_save_slots = 16
|
|
var/loaded_preferences_successfully = load_preferences()
|
|
if(loaded_preferences_successfully)
|
|
if(load_character())
|
|
return
|
|
//we couldn't load character data so just randomize the character appearance + name
|
|
random_character() //let's create a random character then - rather than a fat, bald and naked man.
|
|
real_name = pref_species.random_name(gender,1)
|
|
if(!loaded_preferences_successfully)
|
|
save_preferences()
|
|
save_character() //let's save this new random character so it doesn't keep generating new ones.
|
|
menuoptions = list()
|
|
return
|
|
|
|
/datum/preferences/proc/ShowChoices(mob/user)
|
|
if(!user || !user.client)
|
|
return
|
|
if(current_tab == 2)
|
|
update_preview_icon(nude=TRUE)
|
|
else
|
|
update_preview_icon(nude=FALSE)
|
|
user << browse_rsc(preview_icon, "previewicon.png")
|
|
var/dat = "<center>"
|
|
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=0' [current_tab == 0 ? "class='linkOn'" : ""]>Character Settings</a>"
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=2' [current_tab == 2 ? "class='linkOn'" : ""]>Character Appearance</a>"
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=3' [current_tab == 3 ? "class='linkOn'" : ""]>Loadout</a>"
|
|
dat += "<a href='?_src_=prefs;preference=tab;tab=1' [current_tab == 1 ? "class='linkOn'" : ""]>Game Preferences</a>"
|
|
|
|
if(!path)
|
|
dat += "<div class='notice'>Please create an account to save your preferences</div>"
|
|
|
|
dat += "</center>"
|
|
|
|
dat += "<HR>"
|
|
|
|
switch(current_tab)
|
|
if (0) // Character Settings#
|
|
if(path)
|
|
var/savefile/S = new /savefile(path)
|
|
if(S)
|
|
dat += "<center>"
|
|
var/name
|
|
for(var/i=1, i<=max_save_slots, i++)
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
if(!name)
|
|
name = "Character[i]"
|
|
dat += "<a style='white-space:nowrap;' href='?_src_=prefs;preference=changeslot;num=[i];' [i == default_slot ? "class='linkOn'" : ""]>[name]</a> "
|
|
dat += "</center>"
|
|
|
|
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>Trait Setup</h2>"
|
|
dat += "<a href='?_src_=prefs;preference=trait;task=menu'>Configure Traits</a><br></center>"
|
|
dat += "<center><b>Current traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
|
|
dat += "<h2>Identity</h2>"
|
|
dat += "<table width='100%'><tr><td width='75%' 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 += "<a href='?_src_=prefs;preference=name;task=random'>Random Name</A> "
|
|
dat += "<a href='?_src_=prefs;preference=name'>Always Random Name: [be_random_name ? "Yes" : "No"]</a><BR>"
|
|
|
|
dat += "<b>Name:</b> "
|
|
dat += "<a href='?_src_=prefs;preference=name;task=input'>[real_name]</a><BR>"
|
|
|
|
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : "Female"]</a><BR>"
|
|
dat += "<b>Age:</b> <a href='?_src_=prefs;preference=age;task=input'>[age]</a><BR>"
|
|
dat += "<b>Arousal:</b><a href='?_src_=prefs;preference=arousable'>[arousable == TRUE ? "Enabled" : "Disabled"]</a><BR>"
|
|
dat += "<b>Exhibitionist:</b><a href='?_src_=prefs;preference=exhibitionist'>[features["exhibitionist"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
|
|
dat += "<b>Special Names:</b><BR>"
|
|
dat += "<a href ='?_src_=prefs;preference=human_name;task=input'><b>Backup Human Name:</b> [custom_names["human"]]</a> "
|
|
dat += "<a href ='?_src_=prefs;preference=clown_name;task=input'><b>Clown:</b> [custom_names["clown"]]</a> "
|
|
dat += "<a href ='?_src_=prefs;preference=mime_name;task=input'><b>Mime:</b>[custom_names["mime"]]</a><BR>"
|
|
dat += "<a href ='?_src_=prefs;preference=ai_name;task=input'><b>AI:</b> [custom_names["ai"]]</a> "
|
|
dat += "<a href ='?_src_=prefs;preference=cyborg_name;task=input'><b>Cyborg:</b> [custom_names["cyborg"]]</a><BR>"
|
|
dat += "<a href ='?_src_=prefs;preference=religion_name;task=input'><b>Chaplain religion:</b> [custom_names["religion"]] </a>"
|
|
dat += "<a href ='?_src_=prefs;preference=deity_name;task=input'><b>Chaplain deity:</b> [custom_names["deity"]]</a><BR>"
|
|
|
|
dat += "<b>Custom job preferences:</b><BR>"
|
|
dat += "<a href='?_src_=prefs;preference=sec_dept;task=input'><b>Prefered security department:</b> [prefered_security_department]</a><BR></td>"
|
|
|
|
dat += "<td valign='center'>"
|
|
|
|
dat += "<div class='statusDisplay'><center><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></center></div>"
|
|
|
|
dat += "</td></tr></table>"
|
|
dat += "<br>"
|
|
|
|
dat += "<b>Backpack:</b><BR><a href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a><BR>"
|
|
dat += "<b>Uplink Spawn Location:</b><BR><a href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a><BR></td>"
|
|
|
|
dat += "</tr></table>"
|
|
|
|
|
|
if (1) // Game Preferences
|
|
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>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Default"]</a><br>"
|
|
dat += "<b>Action Buttons:</b> <a href='?_src_=prefs;preference=action_buttons'>[(buttons_locked) ? "Locked In Place" : "Unlocked"]</a><br>"
|
|
dat += "<b>tgui Style:</b> <a href='?_src_=prefs;preference=tgui_fancy'>[(tgui_fancy) ? "Fancy" : "No Frills"]</a><br>"
|
|
dat += "<b>PDA Style:</b> <a href='?_src_=prefs;task=input;preference=pda_style'>[pda_style]</a><br>"
|
|
dat += "<b>PDA Color:</b> <span style='border:1px solid #161616; background-color: [pda_color];'> </span> <a href='?_src_=prefs;preference=pda_color;task=input'>Change</a><BR>"
|
|
dat += "<b>tgui Monitors:</b> <a href='?_src_=prefs;preference=tgui_lock'>[(tgui_lock) ? "Primary" : "All"]</a><br>"
|
|
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(windowflashing) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Play lobby music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Allow MediHound sleeper:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><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 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 radio:</b> <a href='?_src_=prefs;preference=ghost_radio'>[(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]</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 += "<b>Pull requests:</b> <a href='?_src_=prefs;preference=pull_requests'>[(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]</a><br>"
|
|
//VORE SOUNDS
|
|
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
|
|
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
|
|
if(CONFIG_GET(flag/allow_metadata))
|
|
dat += "<b>OOC Notes:</b> <a href='?_src_=prefs;preference=metadata;task=input'>Edit </a><br>"
|
|
|
|
if(user.client)
|
|
if(user.client.holder)
|
|
dat += "<b>Adminhelp Sound:</b> <a href='?_src_=prefs;preference=hear_adminhelps'>[(toggles & SOUND_ADMINHELP)?"On":"Off"]</a><br>"
|
|
dat += "<b>Announce Login:</b> <a href='?_src_=prefs;preference=announce_login'>[(toggles & ANNOUNCE_LOGIN)?"On":"Off"]</a><br>"
|
|
|
|
if(unlock_content || check_rights_for(user.client, R_ADMIN))
|
|
dat += "<b>OOC:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : GLOB.normal_ooc_colour];'> </span> <a href='?_src_=prefs;preference=ooccolor;task=input'>Change</a><br>"
|
|
|
|
if(unlock_content)
|
|
dat += "<b>BYOND Membership Publicity:</b> <a href='?_src_=prefs;preference=publicity'>[(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]</a><br>"
|
|
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>"
|
|
|
|
if (CONFIG_GET(flag/maprotation))
|
|
var/p_map = preferred_map
|
|
if (!p_map)
|
|
p_map = "Default"
|
|
if (config.defaultmap)
|
|
p_map += " ([config.defaultmap.map_name])"
|
|
else
|
|
if (p_map in config.maplist)
|
|
var/datum/map_config/VM = config.maplist[p_map]
|
|
if (!VM)
|
|
p_map += " (No longer exists)"
|
|
else
|
|
p_map = VM.map_name
|
|
else
|
|
p_map += " (No longer exists)"
|
|
if(CONFIG_GET(flag/allow_map_voting))
|
|
dat += "<b>Preferred Map:</b> <a href='?_src_=prefs;preference=preferred_map;task=input'>[p_map]</a><br>"
|
|
|
|
dat += "<b>FPS:</b> <a href='?_src_=prefs;preference=clientfps;task=input'>[clientfps]</a><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>Widescreen:</b> <a href='?_src_=prefs;preference=widescreenpref'>[widescreenpref ? "Enabled ([CONFIG_GET(string/default_view)])" : "Disabled (15x15)"]</a><br>"
|
|
|
|
dat += "<b>Auto stand:</b> <a href='?_src_=prefs;preference=autostand'>[autostand ? "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.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 += "</td><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()
|
|
|
|
|
|
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
|
|
dat += "<b>Be [capitalize(i)]:</b> <a href='?_src_=prefs;preference=be_special;be_special_type=[i]'>[(i in be_special) ? "Yes" : "No"]</a><br>"
|
|
|
|
dat += "</td></tr></table>"
|
|
|
|
//Character Appearance
|
|
if(2)
|
|
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
|
|
dat += "<div class='statusDisplay'><img src=previewicon.png width=[preview_icon.Width()] height=[preview_icon.Height()]></div><br>"
|
|
dat += "<a href='?_src_=prefs;preference=flavor_text;task=input'><b>Set Flavor Text</b></a><br>"
|
|
if(lentext(features["flavor_text"]) <= 40)
|
|
if(!lentext(features["flavor_text"]))
|
|
dat += "\[...\]"
|
|
else
|
|
dat += "[features["flavor_text"]]"
|
|
else
|
|
dat += "[TextPreview(features["flavor_text"])]...<BR>"
|
|
dat += "<h2>Body</h2>"
|
|
dat += "<b>Gender:</b> <a href='?_src_=prefs;preference=gender'>[gender == MALE ? "Male" : "Female"]</a><BR>"
|
|
dat += "<b>Species:</b><a href='?_src_=prefs;preference=species;task=input'>[pref_species.id]</a><BR>"
|
|
dat += "<a href='?_src_=prefs;preference=all;task=random'>Random Body</A><BR>"
|
|
dat += "<a href='?_src_=prefs;preference=all'>Always Random Body: [be_random_body ? "Yes" : "No"]</A><BR>"
|
|
if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
|
|
dat += "<b>Primary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor"]];'> </span> <a href='?_src_=prefs;preference=mutant_color;task=input'>Change</a><BR>"
|
|
dat += "<b>Secondary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor2"]];'> </span> <a href='?_src_=prefs;preference=mutant_color2;task=input'>Change</a><BR>"
|
|
dat += "<b>Tertiary Color: </b><span style='border: 1px solid #161616; background-color: #[features["mcolor3"]];'> </span> <a href='?_src_=prefs;preference=mutant_color3;task=input'>Change</a><BR>"
|
|
if(pref_species.use_skintones)
|
|
dat += "<b>Skin Tone: </b><a href='?_src_=prefs;preference=s_tone;task=input'>[skin_tone]</a><BR>"
|
|
dat += "<b>Genitals Use Skintone:</b><a href='?_src_=prefs;preference=genital_colour'>[features["genitals_use_skintone"] == TRUE ? "Enabled" : "Disabled"]</a><BR>"
|
|
|
|
if(HAIR in pref_species.species_traits)
|
|
dat += "<b>Hair Style: </b><a href='?_src_=prefs;preference=hair_style;task=input'>[hair_style]</a><BR>"
|
|
dat += "<b>Hair Color: </b><span style='border:1px solid #161616; background-color: #[hair_color];'> </span> <a href='?_src_=prefs;preference=hair;task=input'>Change</a><BR>"
|
|
dat += "<b>Facial Hair Style: </b><a href='?_src_=prefs;preference=facial_hair_style;task=input'>[facial_hair_style]</a><BR>"
|
|
dat += "<b>Facial Hair Color: </b><span style='border: 1px solid #161616; background-color: #[facial_hair_color];'> </span> <a href='?_src_=prefs;preference=facial;task=input'>Change</a><BR>"
|
|
if(EYECOLOR in pref_species.species_traits)
|
|
dat += "<b>Eye Color: </b><span style='border: 1px solid #161616; background-color: #[eye_color];'> </span> <a href='?_src_=prefs;preference=eyes;task=input'>Change</a><BR>"
|
|
if("tail_lizard" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Tail: </b><a href='?_src_=prefs;preference=tail_lizard;task=input'>[features["tail_lizard"]]</a><BR>"
|
|
else if("mam_tail" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Tail: </b><a href='?_src_=prefs;preference=mam_tail;task=input'>[features["mam_tail"]]</a><BR>"
|
|
else if("tail_human" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Tail: </b><a href='?_src_=prefs;preference=tail_human;task=input'>[features["tail_human"]]</a><BR>"
|
|
if("snout" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Snout: </b><a href='?_src_=prefs;preference=snout;task=input'>[features["snout"]]</a><BR>"
|
|
if("horns" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Horns: </b><a href='?_src_=prefs;preference=horns;task=input'>[features["horns"]]</a><BR>"
|
|
if("frills" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Frills: </b><a href='?_src_=prefs;preference=frills;task=input'>[features["frills"]]</a><BR>"
|
|
if("spines" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Spines: </b><a href='?_src_=prefs;preference=spines;task=input'>[features["spines"]]</a><BR>"
|
|
if("body_markings" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Body Markings: </b><a href='?_src_=prefs;preference=body_markings;task=input'>[features["body_markings"]]</a><BR>"
|
|
else if("mam_body_markings" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Body Markings: </b><a href='?_src_=prefs;preference=mam_body_markings;task=input'>[features["mam_body_markings"]]</a><BR>"
|
|
if("mam_ears" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Ears: </b><a href='?_src_=prefs;preference=mam_ears;task=input'>[features["mam_ears"]]</a><BR>"
|
|
else if("ears" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Ears: </b><a href='?_src_=prefs;preference=ears;task=input'>[features["ears"]]</a><BR>"
|
|
if("legs" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Legs: </b><a href='?_src_=prefs;preference=legs;task=input'>[features["legs"]]</a><BR>"
|
|
if("moth_wings" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Moth wings</b><a href='?_src_=prefs;preference=moth_wings;task=input'>[features["moth_wings"]]</a><BR>"
|
|
|
|
if("taur" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Taur: </b><a href='?_src_=prefs;preference=taur;task=input'>[features["taur"]]</a><BR>"
|
|
if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1)
|
|
dat += "<b>Wings: </b><a href='?_src_=prefs;preference=wings;task=input'>[features["wings"]]</a><BR>"
|
|
if("xenohead" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Caste: </b><a href='?_src_=prefs;preference=xenohead;task=input'>[features["xenohead"]]</a><BR>"
|
|
if("xenotail" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Tail: </b><a href='?_src_=prefs;preference=xenotail;task=input'>[features["xenotail"]]</a><BR>"
|
|
if("xenodorsal" in pref_species.mutant_bodyparts)
|
|
dat += "<b>Dorsal Tubes: </b><a href='?_src_=prefs;preference=xenodorsal;task=input'>[features["xenodorsal"]]</a><BR>"
|
|
|
|
dat += "</td><td width='300px' height='300px' valign='top'>"
|
|
|
|
|
|
dat += "<h2>Clothing & Equipment</h2>"
|
|
//underwear will be refactored later so it fits in with other wearable equipment and isn't just an overlay
|
|
// dat += "<b>Underwear:</b><a href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a><br>"
|
|
// dat += "<b>Undershirt:</b><a href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a><br>"
|
|
// dat += "<b>Socks:</b><a href ='?_src_=prefs;preference=socks;task=input'>[socks]</a><br>"
|
|
dat += "<b>Backpack:</b><a href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a><br>"
|
|
dat += "<b>Uplink Location:</b><a href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a><br>"
|
|
|
|
dat += "<h2>Genitals</h2>"
|
|
if(NOGENITALS in pref_species.species_traits)
|
|
dat += "<b>Your species ([pref_species.name]) does not support genitals!</b><br>"
|
|
else
|
|
dat += "<b>Has Penis:</b><a href='?_src_=prefs;preference=has_cock'>[features["has_cock"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
if(features["has_cock"] == TRUE)
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Penis Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
|
else
|
|
dat += "<b>Penis Color:</b><span style='border: 1px solid #161616; background-color: #[features["cock_color"]];'> </span> <a href='?_src_=prefs;preference=cock_color;task=input'>Change</a><BR>"
|
|
// dat += "<br>"
|
|
dat += "<b>Penis Shape:</b> <a href='?_src_=prefs;preference=cock_shape;task=input'>[features["cock_shape"]]</a><BR>"
|
|
dat += "<b>Penis Length:</b> <a href='?_src_=prefs;preference=cock_length;task=input'>[features["cock_length"]] inch(es)</a><BR>"
|
|
dat += "<b>Has Testicles:</b><a href='?_src_=prefs;preference=has_balls'>[features["has_balls"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
if(features["has_balls"] == TRUE)
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Testicles Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
|
else
|
|
dat += "<b>Testicles Color:</b><span style='border: 1px solid #161616; background-color: #[features["balls_color"]];'> </span> <a href='?_src_=prefs;preference=balls_color;task=input'>Change</a><BR>"
|
|
dat += "<b>Has Vagina:</b><a href='?_src_=prefs;preference=has_vag'>[features["has_vag"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
if(features["has_vag"])
|
|
dat += "<b>Vagina Type:</b> <a href='?_src_=prefs;preference=vag_shape;task=input'>[features["vag_shape"]]</a><BR>"
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Vagina Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
|
else
|
|
dat += "<b>Vagina Color:</b><span style='border: 1px solid #161616; background-color: #[features["vag_color"]];'> </span> <a href='?_src_=prefs;preference=vag_color;task=input'>Change</a><BR>"
|
|
dat += "<b>Has Womb:</b><a href='?_src_=prefs;preference=has_womb'>[features["has_womb"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
dat += "<b>Has Breasts:</b><a href='?_src_=prefs;preference=has_breasts'>[features["has_breasts"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
if(features["has_breasts"])
|
|
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
|
|
dat += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[skintone2hex(skin_tone)];'> </span>(Skin tone overriding)<BR>"
|
|
else
|
|
dat += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[features["breasts_color"]];'> </span> <a href='?_src_=prefs;preference=breasts_color;task=input'>Change</a><BR>"
|
|
dat += "<b>Cup Size:</b><a href='?_src_=prefs;preference=breasts_size;task=input'>[features["breasts_size"]]</a><br>"
|
|
dat += "<b>Breast Shape:</b><a href='?_src_=prefs;preference=breasts_shape;task=input'>[features["breasts_shape"]]</a><br>"
|
|
/*
|
|
dat += "<h3>Ovipositor</h3>"
|
|
dat += "<b>Has Ovipositor:</b><a href='?_src_=prefs;preference=has_ovi'>[features["has_ovi"] == TRUE ? "Yes" : "No"]</a>"
|
|
if(features["has_ovi"])
|
|
dat += "<b>Ovi Color:</b><span style='border: 1px solid #161616; background-color: #[features["ovi_color"]];'> </span> <a href='?_src_=prefs;preference=ovi_color;task=input'>Change</a>"
|
|
dat += "<h3>Eggsack</h3>"
|
|
dat += "<b>Has Eggsack:</b><a href='?_src_=prefs;preference=has_eggsack'>[features["has_eggsack"] == TRUE ? "Yes" : "No"]</a><BR>"
|
|
if(features["has_eggsack"] == TRUE)
|
|
dat += "<b>Color:</b><span style='border: 1px solid #161616; background-color: #[features["eggsack_color"]];'> </span> <a href='?_src_=prefs;preference=eggsack_color;task=input'>Change</a>"
|
|
dat += "<b>Egg Color:</b><span style='border: 1px solid #161616; background-color: #[features["eggsack_egg_color"]];'> </span> <a href='?_src_=prefs;preference=egg_color;task=input'>Change</a>"
|
|
dat += "<b>Egg Size:</b><a href='?_src_=prefs;preference=egg_size;task=input'>[features["eggsack_egg_size"]]\" Diameter</a>"
|
|
dat += "</td>"
|
|
*/
|
|
|
|
dat += "</td></tr></table>"
|
|
if(3)
|
|
if(!gear_tab)
|
|
gear_tab = GLOB.loadout_items[1]
|
|
dat += "<table align='center' width='100%'>"
|
|
dat += "<tr><td colspan=4><center><b><font color='[gear_points == 0 ? "#E62100" : "#CCDDFF"]'>[gear_points]</font> loadout points remaining.</b> \[<a href='?_src_=prefs;preference=gear;clear_loadout=1'>Clear Loadout</a>\]</center></td></tr>"
|
|
dat += "<tr><td colspan=4><center>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>"
|
|
var/firstcat = TRUE
|
|
for(var/i in GLOB.loadout_items)
|
|
if(firstcat)
|
|
firstcat = FALSE
|
|
else
|
|
dat += " |"
|
|
if(i == gear_tab)
|
|
dat += " <span class='linkOn'>[i]</span> "
|
|
else
|
|
dat += " <a href='?_src_=prefs;preference=gear;select_category=[i]'>[i]</a> "
|
|
dat += "</b></center></td></tr>"
|
|
dat += "<tr><td colspan=4><hr></td></tr>"
|
|
dat += "<tr><td colspan=4><b><center>[gear_tab]</center></b></td></tr>"
|
|
dat += "<tr><td colspan=4><hr></td></tr>"
|
|
dat += "<tr style='vertical-align:top;'><td width=15%><b>Name</b></td>"
|
|
dat += "<td width=5% style='vertical-align:top'><b>Cost</b></td>"
|
|
dat += "<td><font size=2><b>Restrictions</b></font></td>"
|
|
dat += "<td><font size=2><b>Description</b></font></td></tr>"
|
|
for(var/j in GLOB.loadout_items[gear_tab])
|
|
var/datum/gear/gear = GLOB.loadout_items[gear_tab][j]
|
|
var/donoritem
|
|
if(gear.ckeywhitelist && gear.ckeywhitelist.len)
|
|
donoritem = TRUE
|
|
if(!(user.ckey in gear.ckeywhitelist))
|
|
continue
|
|
var/class_link = ""
|
|
if(gear.type in chosen_gear)
|
|
class_link = "style='white-space:normal;' class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=0'"
|
|
else if(gear_points <= 0)
|
|
class_link = "style='white-space:normal;' class='linkOff'"
|
|
else if(donoritem)
|
|
class_link = "style='white-space:normal;background:#ebc42e;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=1'"
|
|
else
|
|
class_link = "style='white-space:normal;' href='?_src_=prefs;preference=gear;toggle_gear_path=[html_encode(j)];toggle_gear=1'"
|
|
dat += "<tr style='vertical-align:top;'><td width=15%><a [class_link]>[j]</a></td>"
|
|
dat += "<td width = 5% style='vertical-align:top'>[gear.cost]</td><td>"
|
|
if(islist(gear.restricted_roles))
|
|
if(gear.restricted_roles.len)
|
|
dat += "<font size=2>"
|
|
dat += gear.restricted_roles.Join(";")
|
|
dat += "</font>"
|
|
dat += "</td><td><font size=2><i>[gear.description]</i></font></td></tr>"
|
|
dat += "</table>"
|
|
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>"
|
|
|
|
var/datum/browser/popup = new(user, "preferences", "<div align='center'>Character Setup</div>", 640, 770)
|
|
popup.set_content(dat)
|
|
popup.open(0)
|
|
|
|
/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620)
|
|
if(!SSjob)
|
|
return
|
|
|
|
//limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice.
|
|
//splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice.
|
|
//widthPerColumn - Screen's width for every column.
|
|
//height - Screen's height.
|
|
|
|
var/width = widthPerColumn
|
|
|
|
var/HTML = "<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 SSjob.occupations)
|
|
|
|
index += 1
|
|
if((index >= limit) || (job.title in splitJobs))
|
|
width += widthPerColumn
|
|
if((index < limit) && (lastJob != null))
|
|
//If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with
|
|
//the last job's selection color. Creating a rather nice effect.
|
|
for(var/i = 0, i < (limit - index), i += 1)
|
|
HTML += "<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
|
|
lastJob = job
|
|
if(jobban_isbanned(user, rank))
|
|
HTML += "<font color=red>[rank]</font></td><td><a href='?_src_=prefs;jobbancheck=[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((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant"))
|
|
HTML += "<font color=orange>[rank]</font></td><td></td></tr>"
|
|
continue
|
|
if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs
|
|
HTML += "<b><span class='dark'>[rank]</span></b>"
|
|
else
|
|
HTML += "<span class='dark'>[rank]</span>"
|
|
|
|
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
|
|
|
|
if(GetJobDepartment(job, 1) & job.flag)
|
|
prefLevelLabel = "High"
|
|
prefLevelColor = "slateblue"
|
|
prefUpperLevel = 4
|
|
prefLowerLevel = 2
|
|
else if(GetJobDepartment(job, 2) & job.flag)
|
|
prefLevelLabel = "Medium"
|
|
prefLevelColor = "green"
|
|
prefUpperLevel = 1
|
|
prefLowerLevel = 3
|
|
else if(GetJobDepartment(job, 3) & job.flag)
|
|
prefLevelLabel = "Low"
|
|
prefLevelColor = "orange"
|
|
prefUpperLevel = 2
|
|
prefLowerLevel = 4
|
|
else
|
|
prefLevelLabel = "NEVER"
|
|
prefLevelColor = "red"
|
|
prefUpperLevel = 3
|
|
prefLowerLevel = 1
|
|
|
|
|
|
HTML += "<a class='white' href='?_src_=prefs;preference=job;task=setJobLevel;level=[prefUpperLevel];text=[rank]' oncontextmenu='javascript:return setJobPrefRedirect([prefLowerLevel], \"[rank]\");'>"
|
|
|
|
if(rank == "Assistant")//Assistant is special
|
|
if(job_civilian_low & ASSISTANT)
|
|
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 Assistant if preferences unavailable"
|
|
if(joblessrole == BERANDOMJOB)
|
|
message = "Get random job if preferences unavailable"
|
|
else if(joblessrole == RETURNTOLOBBY)
|
|
message = "Return to lobby if preferences unavailable"
|
|
HTML += "<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>"
|
|
|
|
user << browse(null, "window=preferences")
|
|
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(0)
|
|
return
|
|
|
|
/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level)
|
|
if (!job)
|
|
return 0
|
|
|
|
if (level == 1) // to high
|
|
// remove any other job(s) set to high
|
|
job_civilian_med |= job_civilian_high
|
|
job_engsec_med |= job_engsec_high
|
|
job_medsci_med |= job_medsci_high
|
|
job_civilian_high = 0
|
|
job_engsec_high = 0
|
|
job_medsci_high = 0
|
|
|
|
if (job.department_flag == CIVILIAN)
|
|
job_civilian_low &= ~job.flag
|
|
job_civilian_med &= ~job.flag
|
|
job_civilian_high &= ~job.flag
|
|
|
|
switch(level)
|
|
if (1)
|
|
job_civilian_high |= job.flag
|
|
if (2)
|
|
job_civilian_med |= job.flag
|
|
if (3)
|
|
job_civilian_low |= job.flag
|
|
|
|
return 1
|
|
else if (job.department_flag == ENGSEC)
|
|
job_engsec_low &= ~job.flag
|
|
job_engsec_med &= ~job.flag
|
|
job_engsec_high &= ~job.flag
|
|
|
|
switch(level)
|
|
if (1)
|
|
job_engsec_high |= job.flag
|
|
if (2)
|
|
job_engsec_med |= job.flag
|
|
if (3)
|
|
job_engsec_low |= job.flag
|
|
|
|
return 1
|
|
else if (job.department_flag == MEDSCI)
|
|
job_medsci_low &= ~job.flag
|
|
job_medsci_med &= ~job.flag
|
|
job_medsci_high &= ~job.flag
|
|
|
|
switch(level)
|
|
if (1)
|
|
job_medsci_high |= job.flag
|
|
if (2)
|
|
job_medsci_med |= job.flag
|
|
if (3)
|
|
job_medsci_low |= job.flag
|
|
|
|
return 1
|
|
|
|
return 0
|
|
|
|
/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl)
|
|
if(!SSjob || SSjob.occupations.len <= 0)
|
|
return
|
|
var/datum/job/job = SSjob.GetJob(role)
|
|
|
|
if(!job)
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
return
|
|
|
|
if (!isnum(desiredLvl))
|
|
to_chat(user, "<span class='danger'>UpdateJobPreference - desired level was not a number. Please notify coders!</span>")
|
|
ShowChoices(user)
|
|
return
|
|
|
|
if(role == "Assistant")
|
|
if(job_civilian_low & job.flag)
|
|
job_civilian_low &= ~job.flag
|
|
else
|
|
job_civilian_low |= job.flag
|
|
SetChoices(user)
|
|
return 1
|
|
|
|
SetJobPreferenceLevel(job, desiredLvl)
|
|
SetChoices(user)
|
|
|
|
return 1
|
|
|
|
|
|
/datum/preferences/proc/ResetJobs()
|
|
|
|
job_civilian_high = 0
|
|
job_civilian_med = 0
|
|
job_civilian_low = 0
|
|
|
|
job_medsci_high = 0
|
|
job_medsci_med = 0
|
|
job_medsci_low = 0
|
|
|
|
job_engsec_high = 0
|
|
job_engsec_med = 0
|
|
job_engsec_low = 0
|
|
|
|
|
|
/datum/preferences/proc/GetJobDepartment(datum/job/job, level)
|
|
if(!job || !level)
|
|
return 0
|
|
switch(job.department_flag)
|
|
if(CIVILIAN)
|
|
switch(level)
|
|
if(1)
|
|
return job_civilian_high
|
|
if(2)
|
|
return job_civilian_med
|
|
if(3)
|
|
return job_civilian_low
|
|
if(MEDSCI)
|
|
switch(level)
|
|
if(1)
|
|
return job_medsci_high
|
|
if(2)
|
|
return job_medsci_med
|
|
if(3)
|
|
return job_medsci_low
|
|
if(ENGSEC)
|
|
switch(level)
|
|
if(1)
|
|
return job_engsec_high
|
|
if(2)
|
|
return job_engsec_med
|
|
if(3)
|
|
return job_engsec_low
|
|
return 0
|
|
|
|
/datum/preferences/proc/SetTraits(mob/user)
|
|
if(!SStraits)
|
|
to_chat(user, "<span class='danger'>The trait subsystem is still initializing! Try again in a minute.</span>")
|
|
return
|
|
|
|
var/list/dat = list()
|
|
if(!SStraits.traits.len)
|
|
dat += "The trait 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 trait setup</b></center><br>"
|
|
dat += "<div align='center'>Left-click to add or remove traits. You need one negative trait for every positive trait.<br>\
|
|
Traits 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 traits:</b> [all_traits.len ? all_traits.Join(", ") : "None"]</center>"
|
|
/*dat += "<center><font color='#AAFFAA'>[positive_traits.len] / [MAX_POSITIVE_TRAITS]</font> \
|
|
| <font color='#AAAAFF'>[neutral_traits.len] / [MAX_NEUTRAL_TRAITS]</font> \
|
|
| <font color='#FFAAAA'>[negative_traits.len] / [MAX_NEGATIVE_TRAITS]</font></center><br>"*/
|
|
dat += "<center>[all_traits.len] / [MAX_TRAITS] max traits<br>\
|
|
<b>Trait balance remaining:</b> [GetTraitBalance()]</center><br>"
|
|
for(var/V in SStraits.traits)
|
|
var/datum/trait/T = SStraits.traits[V]
|
|
var/trait_name = initial(T.name)
|
|
var/has_trait
|
|
var/trait_cost = initial(T.value) * -1
|
|
for(var/_V in all_traits)
|
|
if(_V == trait_name)
|
|
has_trait = TRUE
|
|
if(has_trait)
|
|
trait_cost *= -1 //invert it back, since we'd be regaining this amount
|
|
if(trait_cost > 0)
|
|
trait_cost = "+[trait_cost]"
|
|
var/font_color = "#AAAAFF"
|
|
if(initial(T.value) != 0)
|
|
font_color = initial(T.value) > 0 ? "#AAFFAA" : "#FFAAAA"
|
|
if(has_trait)
|
|
dat += "<b><font color='[font_color]'>[trait_name]</font></b> - [initial(T.desc)] \
|
|
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>"
|
|
else
|
|
dat += "<font color='[font_color]'>[trait_name]</font> - [initial(T.desc)] \
|
|
<a href='?_src_=prefs;preference=trait;task=update;trait=[trait_name]'>[has_trait ? "Lose" : "Take"] ([trait_cost] pts.)</a><br>"
|
|
dat += "<br><center><a href='?_src_=prefs;preference=trait;task=reset'>Reset Traits</a></center>"
|
|
|
|
user << browse(null, "window=preferences")
|
|
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Trait 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(0)
|
|
return
|
|
|
|
/datum/preferences/proc/GetTraitBalance()
|
|
var/bal = 0
|
|
for(var/V in all_traits)
|
|
var/datum/trait/T = SStraits.traits[V]
|
|
bal -= initial(T.value)
|
|
return bal
|
|
|
|
/datum/preferences/proc/process_link(mob/user, list/href_list)
|
|
if(href_list["jobbancheck"])
|
|
var/job = sanitizeSQL(href_list["jobbancheck"])
|
|
var/sql_ckey = sanitizeSQL(user.ckey)
|
|
var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'")
|
|
if(!query_get_jobban.warn_execute())
|
|
return
|
|
if(query_get_jobban.NextRow())
|
|
var/reason = query_get_jobban.item[1]
|
|
var/bantime = query_get_jobban.item[2]
|
|
var/duration = query_get_jobban.item[3]
|
|
var/expiration_time = query_get_jobban.item[4]
|
|
var/a_ckey = query_get_jobban.item[5]
|
|
var/text
|
|
text = "<span class='redtext'>You, or another user of this computer, ([user.ckey]) is banned from playing [job]. The ban reason is:<br>[reason]<br>This ban was applied by [a_ckey] on [bantime]"
|
|
if(text2num(duration) > 0)
|
|
text += ". The ban is for [duration] minutes and expires on [expiration_time] (server time)"
|
|
text += ".</span>"
|
|
to_chat(user, text)
|
|
return
|
|
|
|
if(href_list["preference"] == "job")
|
|
switch(href_list["task"])
|
|
if("close")
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
if("reset")
|
|
ResetJobs()
|
|
SetChoices(user)
|
|
if("random")
|
|
switch(joblessrole)
|
|
if(RETURNTOLOBBY)
|
|
if(jobban_isbanned(user, "Assistant"))
|
|
joblessrole = BERANDOMJOB
|
|
else
|
|
joblessrole = BEASSISTANT
|
|
if(BEASSISTANT)
|
|
joblessrole = BERANDOMJOB
|
|
if(BERANDOMJOB)
|
|
joblessrole = RETURNTOLOBBY
|
|
SetChoices(user)
|
|
if("setJobLevel")
|
|
UpdateJobPreference(user, href_list["text"], text2num(href_list["level"]))
|
|
else
|
|
SetChoices(user)
|
|
return 1
|
|
|
|
else if(href_list["preference"] == "trait")
|
|
if(SSticker.HasRoundStarted() && !isnewplayer(user))
|
|
to_chat(user, "<span class='danger'>The round has already started. Please wait until next round to set up your traits!</span>")
|
|
return
|
|
switch(href_list["task"])
|
|
if("close")
|
|
user << browse(null, "window=mob_occupation")
|
|
ShowChoices(user)
|
|
if("update")
|
|
var/trait = href_list["trait"]
|
|
var/value = SStraits.trait_points[trait]
|
|
if(value == 0)
|
|
if(trait in neutral_traits)
|
|
neutral_traits -= trait
|
|
all_traits -= trait
|
|
else
|
|
if(all_traits.len >= MAX_TRAITS)
|
|
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
|
|
return
|
|
neutral_traits += trait
|
|
all_traits += trait
|
|
else
|
|
var/balance = GetTraitBalance()
|
|
if(trait in positive_traits)
|
|
positive_traits -= trait
|
|
all_traits -= trait
|
|
else if(trait in negative_traits)
|
|
if(balance + value < 0)
|
|
to_chat(user, "<span class='warning'>Refunding this would cause you to go below your balance!</span>")
|
|
return
|
|
negative_traits -= trait
|
|
all_traits -= trait
|
|
else if(value > 0)
|
|
if(all_traits.len >= MAX_TRAITS)
|
|
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
|
|
return
|
|
if(balance - value < 0)
|
|
to_chat(user, "<span class='warning'>You don't have enough balance to gain this trait!</span>")
|
|
return
|
|
positive_traits += trait
|
|
all_traits += trait
|
|
else
|
|
if(all_traits.len >= MAX_TRAITS)
|
|
to_chat(user, "<span class='warning'>You can't have more than [MAX_TRAITS] traits!</span>")
|
|
return
|
|
negative_traits += trait
|
|
all_traits += trait
|
|
SetTraits(user)
|
|
if("reset")
|
|
all_traits = list()
|
|
positive_traits = list()
|
|
negative_traits = list()
|
|
neutral_traits = list()
|
|
SetTraits(user)
|
|
else
|
|
SetTraits(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)
|
|
if("undershirt")
|
|
undershirt = random_undershirt(gender)
|
|
if("socks")
|
|
socks = random_socks()
|
|
if("eyes")
|
|
eye_color = random_eye_color()
|
|
if("s_tone")
|
|
skin_tone = random_skin_tone()
|
|
if("bag")
|
|
backbag = pick(GLOB.backbaglist)
|
|
if("all")
|
|
random_character()
|
|
|
|
if("input")
|
|
switch(href_list["preference"])
|
|
if("ghostform")
|
|
if(unlock_content)
|
|
var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in GLOB.ghost_forms
|
|
if(new_form)
|
|
ghost_form = new_form
|
|
if("ghostorbit")
|
|
if(unlock_content)
|
|
var/new_orbit = input(user, "Thanks for supporting BYOND - Choose your ghostly orbit:","Thanks for supporting BYOND", null) as null|anything in GLOB.ghost_orbits
|
|
if(new_orbit)
|
|
ghost_orbit = new_orbit
|
|
|
|
if("ghostaccs")
|
|
var/new_ghost_accs = alert("Do you want your ghost to show full accessories where possible, hide accessories but still use the directional sprites where possible, or also ignore the directions and stick to the default sprites?",,GHOST_ACCS_FULL_NAME, GHOST_ACCS_DIR_NAME, GHOST_ACCS_NONE_NAME)
|
|
switch(new_ghost_accs)
|
|
if(GHOST_ACCS_FULL_NAME)
|
|
ghost_accs = GHOST_ACCS_FULL
|
|
if(GHOST_ACCS_DIR_NAME)
|
|
ghost_accs = GHOST_ACCS_DIR
|
|
if(GHOST_ACCS_NONE_NAME)
|
|
ghost_accs = GHOST_ACCS_NONE
|
|
|
|
if("ghostothers")
|
|
var/new_ghost_others = alert("Do you want the ghosts of others to show up as their own setting, as their default sprites or always as the default white ghost?",,GHOST_OTHERS_THEIR_SETTING_NAME, GHOST_OTHERS_DEFAULT_SPRITE_NAME, GHOST_OTHERS_SIMPLE_NAME)
|
|
switch(new_ghost_others)
|
|
if(GHOST_OTHERS_THEIR_SETTING_NAME)
|
|
ghost_others = GHOST_OTHERS_THEIR_SETTING
|
|
if(GHOST_OTHERS_DEFAULT_SPRITE_NAME)
|
|
ghost_others = GHOST_OTHERS_DEFAULT_SPRITE
|
|
if(GHOST_OTHERS_SIMPLE_NAME)
|
|
ghost_others = GHOST_OTHERS_SIMPLE
|
|
|
|
if("name")
|
|
var/new_name = reject_bad_name( input(user, "Choose your character's name:", "Character Preference") as text|null )
|
|
if(new_name)
|
|
real_name = new_name
|
|
else
|
|
to_chat(user, "<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 = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null
|
|
if(new_age)
|
|
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
|
|
|
|
if("flavor_text")
|
|
var/msg = stripped_multiline_input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"]), MAX_MESSAGE_LEN*2, TRUE) as message
|
|
if(msg != null)
|
|
msg = copytext(msg, 1, MAX_MESSAGE_LEN*2)
|
|
features["flavor_text"] = msg
|
|
|
|
if("metadata")
|
|
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
|
|
if(new_metadata)
|
|
metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))
|
|
|
|
if("hair")
|
|
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
|
|
if(new_hair)
|
|
hair_color = sanitize_hexcolor(new_hair)
|
|
|
|
|
|
if("hair_style")
|
|
var/new_hair_style
|
|
if(gender == MALE)
|
|
new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_male_list
|
|
else
|
|
new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_female_list
|
|
if(new_hair_style)
|
|
hair_style = new_hair_style
|
|
|
|
if("next_hair_style")
|
|
if (gender == MALE)
|
|
hair_style = next_list_item(hair_style, GLOB.hair_styles_male_list)
|
|
else
|
|
hair_style = next_list_item(hair_style, GLOB.hair_styles_female_list)
|
|
|
|
if("previous_hair_style")
|
|
if (gender == MALE)
|
|
hair_style = previous_list_item(hair_style, GLOB.hair_styles_male_list)
|
|
else
|
|
hair_style = previous_list_item(hair_style, GLOB.hair_styles_female_list)
|
|
|
|
if("facial")
|
|
var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference","#"+facial_hair_color) as color|null
|
|
if(new_facial)
|
|
facial_hair_color = sanitize_hexcolor(new_facial)
|
|
|
|
if("facial_hair_style")
|
|
var/new_facial_hair_style
|
|
if(gender == MALE)
|
|
new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_male_list
|
|
else
|
|
new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_female_list
|
|
if(new_facial_hair_style)
|
|
facial_hair_style = new_facial_hair_style
|
|
|
|
if("next_facehair_style")
|
|
if (gender == MALE)
|
|
facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list)
|
|
else
|
|
facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list)
|
|
|
|
if("previous_facehair_style")
|
|
if (gender == MALE)
|
|
facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list)
|
|
else
|
|
facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list)
|
|
|
|
if("underwear")
|
|
var/new_underwear
|
|
if(gender == MALE)
|
|
new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m
|
|
else
|
|
new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f
|
|
if(new_underwear)
|
|
underwear = new_underwear
|
|
|
|
if("undershirt")
|
|
var/new_undershirt
|
|
if(gender == MALE)
|
|
new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m
|
|
else
|
|
new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f
|
|
if(new_undershirt)
|
|
undershirt = new_undershirt
|
|
|
|
if("socks")
|
|
var/new_socks
|
|
new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list
|
|
if(new_socks)
|
|
socks = new_socks
|
|
|
|
if("eyes")
|
|
var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference","#"+eye_color) as color|null
|
|
if(new_eyes)
|
|
eye_color = sanitize_hexcolor(new_eyes)
|
|
|
|
if("species")
|
|
|
|
var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_races
|
|
|
|
if(result)
|
|
var/newtype = GLOB.species_list[result]
|
|
pref_species = new newtype()
|
|
//Now that we changed our species, we must verify that the mutant colour is still allowed.
|
|
var/temp_hsv = RGBtoHSV(features["mcolor"])
|
|
if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
|
features["mcolor"] = pref_species.default_color
|
|
if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
|
features["mcolor2"] = pref_species.default_color
|
|
if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
|
|
features["mcolor3"] = pref_species.default_color
|
|
|
|
if("mutant_color")
|
|
var/new_mutantcolor = input(user, "Choose your character's alien/mutant color:", "Character Preference","#"+features["mcolor"]) as color|null
|
|
if(new_mutantcolor)
|
|
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
|
if(new_mutantcolor == "#000000")
|
|
features["mcolor"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
|
features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
|
|
else
|
|
to_chat(user, "<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") as color|null
|
|
if(new_mutantcolor)
|
|
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
|
if(new_mutantcolor == "#000000")
|
|
features["mcolor2"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
|
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor)
|
|
else
|
|
to_chat(user, "<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") as color|null
|
|
if(new_mutantcolor)
|
|
var/temp_hsv = RGBtoHSV(new_mutantcolor)
|
|
if(new_mutantcolor == "#000000")
|
|
features["mcolor3"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
|
|
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor)
|
|
else
|
|
to_chat(user, "<span class='danger'>Invalid color. Your color is not bright enough.</span>")
|
|
|
|
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"
|
|
|
|
if("tail_human")
|
|
var/new_tail
|
|
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_human
|
|
if(new_tail)
|
|
features["tail_human"] = new_tail
|
|
if(new_tail != "None")
|
|
features["taur"] = "None"
|
|
|
|
if("mam_tail")
|
|
var/new_tail
|
|
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.mam_tails_list
|
|
if(new_tail)
|
|
features["mam_tail"] = new_tail
|
|
if(new_tail != "None")
|
|
features["taur"] = "None"
|
|
|
|
if("taur")
|
|
var/new_taur
|
|
new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in GLOB.taur_list
|
|
if(new_taur)
|
|
features["taur"] = new_taur
|
|
if(new_taur != "None")
|
|
features["mam_tail"] = "None"
|
|
features["xenotail"] = "None"
|
|
|
|
if("snout")
|
|
var/new_snout
|
|
new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.snouts_list
|
|
if(new_snout)
|
|
features["snout"] = new_snout
|
|
|
|
if("mam_ears")
|
|
var/new_ears
|
|
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.mam_ears_list
|
|
if(new_ears)
|
|
features["mam_ears"] = new_ears
|
|
|
|
if("horns")
|
|
var/new_horns
|
|
new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list
|
|
if(new_horns)
|
|
features["horns"] = new_horns
|
|
|
|
if("ears")
|
|
var/new_ears
|
|
new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.ears_list
|
|
if(new_ears)
|
|
features["ears"] = new_ears
|
|
|
|
if("wings")
|
|
var/new_wings
|
|
new_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.r_wings_list
|
|
if(new_wings)
|
|
features["wings"] = new_wings
|
|
|
|
if("moth_wings")
|
|
var/new_moth_wings
|
|
new_moth_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.moth_wings_list
|
|
if(new_moth_wings)
|
|
features["moth_wings"] = new_moth_wings
|
|
|
|
if("frills")
|
|
var/new_frills
|
|
new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list
|
|
if(new_frills)
|
|
features["frills"] = new_frills
|
|
|
|
if("spines")
|
|
var/new_spines
|
|
new_spines = input(user, "Choose your character's spines:", "Character Preference") as null|anything in GLOB.spines_list
|
|
if(new_spines)
|
|
features["spines"] = new_spines
|
|
|
|
if("body_markings")
|
|
var/new_body_markings
|
|
new_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.body_markings_list
|
|
if(new_body_markings)
|
|
features["body_markings"] = new_body_markings
|
|
|
|
if("mam_body_markings")
|
|
var/new_mam_body_markings
|
|
new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.mam_body_markings_list
|
|
if(new_mam_body_markings)
|
|
features["mam_body_markings"] = new_mam_body_markings
|
|
|
|
//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("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
|
|
|
|
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("s_tone")
|
|
var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in GLOB.skin_tones
|
|
if(new_s_tone)
|
|
skin_tone = new_s_tone
|
|
|
|
if("ooccolor")
|
|
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null
|
|
if(new_ooccolor)
|
|
ooccolor = new_ooccolor
|
|
|
|
if("bag")
|
|
var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist
|
|
if(new_backbag)
|
|
backbag = new_backbag
|
|
|
|
if("uplink_loc")
|
|
var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in GLOB.uplink_spawn_loc_list
|
|
if(new_loc)
|
|
uplink_spawn_loc = new_loc
|
|
|
|
if("human_name")
|
|
var/new_human_name = reject_bad_name( input(user, "Choose your character's backup human name, used in the event you are assigned a command role as another species:", "Character Preference") as text|null )
|
|
if(new_human_name)
|
|
custom_names["human"] = new_human_name
|
|
else
|
|
to_chat(user, "<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("clown_name")
|
|
var/new_clown_name = reject_bad_name( input(user, "Choose your character's clown name:", "Character Preference") as text|null )
|
|
if(new_clown_name)
|
|
custom_names["clown"] = new_clown_name
|
|
else
|
|
to_chat(user, "<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("mime_name")
|
|
var/new_mime_name = reject_bad_name( input(user, "Choose your character's mime name:", "Character Preference") as text|null )
|
|
if(new_mime_name)
|
|
custom_names["mime"] = new_mime_name
|
|
else
|
|
to_chat(user, "<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("ai_name")
|
|
var/new_ai_name = reject_bad_name( input(user, "Choose your character's AI name:", "Character Preference") as text|null, 1 )
|
|
if(new_ai_name)
|
|
custom_names["ai"] = new_ai_name
|
|
else
|
|
to_chat(user, "<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, 0-9, -, ' and .</font>")
|
|
|
|
if("cyborg_name")
|
|
var/new_cyborg_name = reject_bad_name( input(user, "Choose your character's cyborg name:", "Character Preference") as text|null, 1 )
|
|
if(new_cyborg_name)
|
|
custom_names["cyborg"] = new_cyborg_name
|
|
else
|
|
to_chat(user, "<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, 0-9, -, ' and .</font>")
|
|
|
|
if("religion_name")
|
|
var/new_religion_name = reject_bad_name( input(user, "Choose your character's religion:", "Character Preference") as text|null )
|
|
if(new_religion_name)
|
|
custom_names["religion"] = new_religion_name
|
|
else
|
|
to_chat(user, "<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("deity_name")
|
|
var/new_deity_name = reject_bad_name( input(user, "Choose your character's deity:", "Character Preference") as text|null )
|
|
if(new_deity_name)
|
|
custom_names["deity"] = new_deity_name
|
|
else
|
|
to_chat(user, "<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("sec_dept")
|
|
var/department = input(user, "Choose your prefered security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs
|
|
if(department)
|
|
prefered_security_department = department
|
|
|
|
if ("preferred_map")
|
|
var/maplist = list()
|
|
var/default = "Default"
|
|
if (config.defaultmap)
|
|
default += " ([config.defaultmap.map_name])"
|
|
for (var/M in config.maplist)
|
|
var/datum/map_config/VM = config.maplist[M]
|
|
var/friendlyname = "[VM.map_name] "
|
|
if (VM.voteweight <= 0)
|
|
friendlyname += " (disabled)"
|
|
maplist[friendlyname] = VM.map_name
|
|
maplist[default] = null
|
|
var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in maplist
|
|
if (pickedmap)
|
|
preferred_map = maplist[pickedmap]
|
|
|
|
if ("clientfps")
|
|
var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
|
|
if (!isnull(desiredfps))
|
|
clientfps = desiredfps
|
|
parent.fps = desiredfps
|
|
if("ui")
|
|
var/pickedui = input(user, "Choose your UI style.", "Character Preference") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork")
|
|
if(pickedui)
|
|
UI_style = pickedui
|
|
if("pda_style")
|
|
var/pickedPDAStyle = input(user, "Choose your PDA style.", "Character Preference") as null|anything in list(MONO, SHARE, ORBITRON, VT)
|
|
if(pickedPDAStyle)
|
|
pda_style = pickedPDAStyle
|
|
if("pda_color")
|
|
var/pickedPDAColor = input(user, "Choose your PDA Interface color.", "Character Preference",pda_color) as color|null
|
|
if(pickedPDAColor)
|
|
pda_color = pickedPDAColor
|
|
|
|
//citadel code
|
|
if("cock_color")
|
|
var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null
|
|
if(new_cockcolor)
|
|
var/temp_hsv = RGBtoHSV(new_cockcolor)
|
|
if(new_cockcolor == "#000000")
|
|
features["cock_color"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
|
features["cock_color"] = sanitize_hexcolor(new_cockcolor)
|
|
else
|
|
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
|
|
|
if("cock_length")
|
|
var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null
|
|
if(new_length)
|
|
features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
|
|
|
|
if("cock_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list
|
|
if(new_shape)
|
|
features["cock_shape"] = new_shape
|
|
|
|
if("balls_color")
|
|
var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null
|
|
if(new_ballscolor)
|
|
var/temp_hsv = RGBtoHSV(new_ballscolor)
|
|
if(new_ballscolor == "#000000")
|
|
features["balls_color"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
|
features["balls_color"] = sanitize_hexcolor(new_ballscolor)
|
|
else
|
|
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
|
|
|
if("egg_size")
|
|
var/new_size
|
|
var/list/egg_sizes = list(1,2,3)
|
|
new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes
|
|
if(new_size)
|
|
features["eggsack_egg_size"] = new_size
|
|
|
|
if("egg_color")
|
|
var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null
|
|
if(new_egg_color)
|
|
var/temp_hsv = RGBtoHSV(new_egg_color)
|
|
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
|
features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color)
|
|
else
|
|
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
|
if("breasts_size")
|
|
var/new_size
|
|
new_size = input(user, "Breast Size", "Character Preference") as null|anything in GLOB.breasts_size_list
|
|
if(new_size)
|
|
features["breasts_size"] = new_size
|
|
|
|
if("breasts_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list
|
|
if(new_shape)
|
|
features["breasts_shape"] = new_shape
|
|
|
|
if("breasts_color")
|
|
var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null
|
|
if(new_breasts_color)
|
|
var/temp_hsv = RGBtoHSV(new_breasts_color)
|
|
if(new_breasts_color == "#000000")
|
|
features["breasts_color"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
|
features["breasts_color"] = sanitize_hexcolor(new_breasts_color)
|
|
else
|
|
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
|
|
|
if("vag_shape")
|
|
var/new_shape
|
|
new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list
|
|
if(new_shape)
|
|
features["vag_shape"] = new_shape
|
|
if("vag_color")
|
|
var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null
|
|
if(new_vagcolor)
|
|
var/temp_hsv = RGBtoHSV(new_vagcolor)
|
|
if(new_vagcolor == "#000000")
|
|
features["vag_color"] = pref_species.default_color
|
|
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3])
|
|
features["vag_color"] = sanitize_hexcolor(new_vagcolor)
|
|
else
|
|
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
|
|
|
|
|
|
|
|
else
|
|
switch(href_list["preference"])
|
|
|
|
//citadel code
|
|
if("genital_colour")
|
|
switch(features["genitals_use_skintone"])
|
|
if(TRUE)
|
|
features["genitals_use_skintone"] = FALSE
|
|
if(FALSE)
|
|
features["genitals_use_skintone"] = TRUE
|
|
else
|
|
features["genitals_use_skintone"] = FALSE
|
|
if("arousable")
|
|
switch(arousable)
|
|
if(TRUE)
|
|
arousable = FALSE
|
|
if(FALSE)
|
|
arousable = TRUE
|
|
else//failsafe
|
|
arousable = FALSE
|
|
if("has_cock")
|
|
switch(features["has_cock"])
|
|
if(TRUE)
|
|
features["has_cock"] = FALSE
|
|
if(FALSE)
|
|
features["has_cock"] = TRUE
|
|
features["has_ovi"] = FALSE
|
|
features["has_eggsack"] = FALSE
|
|
else
|
|
features["has_cock"] = FALSE
|
|
features["has_ovi"] = FALSE
|
|
if("has_balls")
|
|
switch(features["has_balls"])
|
|
if(TRUE)
|
|
features["has_balls"] = FALSE
|
|
if(FALSE)
|
|
features["has_balls"] = TRUE
|
|
features["has_eggsack"] = FALSE
|
|
else
|
|
features["has_balls"] = FALSE
|
|
features["has_eggsack"] = FALSE
|
|
if("has_ovi")
|
|
switch(features["has_ovi"])
|
|
if(TRUE)
|
|
features["has_ovi"] = FALSE
|
|
if(FALSE)
|
|
features["has_ovi"] = TRUE
|
|
features["has_cock"] = FALSE
|
|
features["has_balls"] = FALSE
|
|
else
|
|
features["has_ovi"] = FALSE
|
|
features["has_cock"] = FALSE
|
|
|
|
if("has_eggsack")
|
|
switch(features["has_eggsack"])
|
|
if(TRUE)
|
|
features["has_eggsack"] = FALSE
|
|
if(FALSE)
|
|
features["has_eggsack"] = TRUE
|
|
features["has_balls"] = FALSE
|
|
else
|
|
features["has_eggsack"] = FALSE
|
|
features["has_balls"] = FALSE
|
|
if("balls_internal")
|
|
switch(features["balls_internal"])
|
|
if(TRUE)
|
|
features["balls_internal"] = FALSE
|
|
if(FALSE)
|
|
features["balls_internal"] = TRUE
|
|
features["eggsack_internal"] = FALSE
|
|
else
|
|
features["balls_internal"] = FALSE
|
|
features["eggsack_internal"] = FALSE
|
|
|
|
if("eggsack_internal")
|
|
switch(features["eggsack_internal"])
|
|
if(TRUE)
|
|
features["eggsack_internal"] = FALSE
|
|
if(FALSE)
|
|
features["eggsack_internal"] = TRUE
|
|
features["balls_internal"] = FALSE
|
|
else
|
|
features["eggsack_internal"] = FALSE
|
|
features["balls_internal"] = FALSE
|
|
if("has_breasts")
|
|
switch(features["has_breasts"])
|
|
if(TRUE)
|
|
features["has_breasts"] = FALSE
|
|
if(FALSE)
|
|
features["has_breasts"] = TRUE
|
|
else
|
|
features["has_breasts"] = FALSE
|
|
if("has_vag")
|
|
switch(features["has_vag"])
|
|
if(TRUE)
|
|
features["has_vag"] = FALSE
|
|
if(FALSE)
|
|
features["has_vag"] = TRUE
|
|
else
|
|
features["has_vag"] = FALSE
|
|
if("has_womb")
|
|
switch(features["has_womb"])
|
|
if(TRUE)
|
|
features["has_womb"] = FALSE
|
|
if(FALSE)
|
|
features["has_womb"] = TRUE
|
|
else
|
|
features["has_womb"] = FALSE
|
|
if("exhibitionist")
|
|
switch(features["exhibitionist"])
|
|
if(TRUE)
|
|
features["exhibitionist"] = FALSE
|
|
if(FALSE)
|
|
features["exhibitionist"] = TRUE
|
|
else
|
|
features["exhibitionist"] = FALSE
|
|
if("widescreenpref")
|
|
widescreenpref = !widescreenpref
|
|
user.client.change_view(CONFIG_GET(string/default_view))
|
|
if("autostand")
|
|
autostand = !autostand
|
|
if ("screenshake")
|
|
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num
|
|
if (!isnull(desiredshake))
|
|
screenshake = desiredshake
|
|
if("damagescreenshake")
|
|
switch(damagescreenshake)
|
|
if(0)
|
|
damagescreenshake = 1
|
|
if(1)
|
|
damagescreenshake = 2
|
|
if(2)
|
|
damagescreenshake = 0
|
|
else
|
|
damagescreenshake = 1
|
|
if("publicity")
|
|
if(unlock_content)
|
|
toggles ^= MEMBER_PUBLIC
|
|
if("gender")
|
|
if(gender == MALE)
|
|
gender = FEMALE
|
|
else
|
|
gender = MALE
|
|
underwear = random_underwear(gender)
|
|
undershirt = random_undershirt(gender)
|
|
socks = random_socks()
|
|
facial_hair_style = random_facial_hair_style(gender)
|
|
hair_style = random_hair_style(gender)
|
|
|
|
if("hotkeys")
|
|
hotkeys = !hotkeys
|
|
if(hotkeys)
|
|
winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=default")
|
|
else
|
|
winset(user, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=old_default")
|
|
if("action_buttons")
|
|
buttons_locked = !buttons_locked
|
|
if("tgui_fancy")
|
|
tgui_fancy = !tgui_fancy
|
|
if("tgui_lock")
|
|
tgui_lock = !tgui_lock
|
|
if("winflash")
|
|
windowflashing = !windowflashing
|
|
if("hear_adminhelps")
|
|
toggles ^= SOUND_ADMINHELP
|
|
if("announce_login")
|
|
toggles ^= ANNOUNCE_LOGIN
|
|
|
|
if("be_special")
|
|
var/be_special_type = href_list["be_special_type"]
|
|
if(be_special_type in be_special)
|
|
be_special -= be_special_type
|
|
else
|
|
be_special += be_special_type
|
|
|
|
if("name")
|
|
be_random_name = !be_random_name
|
|
|
|
if("all")
|
|
be_random_body = !be_random_body
|
|
|
|
if("hear_midis")
|
|
toggles ^= SOUND_MIDI
|
|
|
|
if("lobby_music")
|
|
toggles ^= SOUND_LOBBY
|
|
if((toggles & SOUND_LOBBY) && user.client)
|
|
user.client.playtitlemusic()
|
|
else
|
|
user.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
|
// VORE SOUND TOGGLES
|
|
if("toggleeatingnoise")
|
|
toggles ^= EATING_NOISES
|
|
|
|
if("toggledigestionnoise")
|
|
toggles ^= DIGESTION_NOISES
|
|
|
|
if("ghost_ears")
|
|
chat_toggles ^= CHAT_GHOSTEARS
|
|
|
|
if("ghost_sight")
|
|
chat_toggles ^= CHAT_GHOSTSIGHT
|
|
|
|
if("ghost_whispers")
|
|
chat_toggles ^= CHAT_GHOSTWHISPER
|
|
|
|
if("ghost_radio")
|
|
chat_toggles ^= CHAT_GHOSTRADIO
|
|
|
|
if("ghost_pda")
|
|
chat_toggles ^= CHAT_GHOSTPDA
|
|
|
|
if("pull_requests")
|
|
chat_toggles ^= CHAT_PULLR
|
|
|
|
if("hound_sleeper")
|
|
toggles ^= MEDIHOUND_SLEEPER
|
|
|
|
if("allow_midround_antag")
|
|
toggles ^= MIDROUND_ANTAG
|
|
|
|
if("parallaxup")
|
|
parallax = WRAP(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
|
if (parent && parent.mob && parent.mob.hud_used)
|
|
parent.mob.hud_used.update_parallax_pref(parent.mob)
|
|
|
|
if("parallaxdown")
|
|
parallax = WRAP(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
|
|
if (parent && parent.mob && parent.mob.hud_used)
|
|
parent.mob.hud_used.update_parallax_pref(parent.mob)
|
|
|
|
if("save")
|
|
save_preferences()
|
|
save_character()
|
|
|
|
if("load")
|
|
load_preferences()
|
|
load_character()
|
|
if(parent && parent.prefs_vr)
|
|
attempt_vr(parent.prefs_vr,"load_vore","")
|
|
|
|
if("changeslot")
|
|
if(!load_character(text2num(href_list["num"])))
|
|
random_character()
|
|
real_name = random_unique_name(gender)
|
|
save_character()
|
|
if(parent && parent.prefs_vr)
|
|
attempt_vr(parent.prefs_vr,"load_vore","")
|
|
|
|
if("tab")
|
|
if (href_list["tab"])
|
|
current_tab = text2num(href_list["tab"])
|
|
|
|
if(href_list["preference"] == "gear")
|
|
if(href_list["clear_loadout"])
|
|
LAZYCLEARLIST(chosen_gear)
|
|
gear_points = initial(gear_points)
|
|
save_preferences()
|
|
if(href_list["select_category"])
|
|
for(var/i in GLOB.loadout_items)
|
|
if(i == href_list["select_category"])
|
|
gear_tab = i
|
|
if(href_list["toggle_gear_path"])
|
|
var/datum/gear/G = GLOB.loadout_items[gear_tab][html_decode(href_list["toggle_gear_path"])]
|
|
if(!G)
|
|
return
|
|
var/toggle = text2num(href_list["toggle_gear"])
|
|
if(!toggle && (G.type in chosen_gear))//toggling off and the item effectively is in chosen gear)
|
|
LAZYREMOVE(chosen_gear, G.type)
|
|
gear_points += initial(G.cost)
|
|
else if(toggle && (!(is_type_in_ref_list(G, chosen_gear))))
|
|
if(!is_loadout_slot_available(G.category))
|
|
to_chat(user, "<span class='danger'>You cannot take this loadout, as you've already chosen too many of the same category!</span>")
|
|
return
|
|
if(G.ckeywhitelist && G.ckeywhitelist.len && !(user.ckey in G.ckeywhitelist))
|
|
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(gear_points >= initial(G.cost))
|
|
LAZYADD(chosen_gear, G.type)
|
|
gear_points -= initial(G.cost)
|
|
|
|
ShowChoices(user)
|
|
return 1
|
|
|
|
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1)
|
|
if(be_random_name)
|
|
real_name = pref_species.random_name(gender)
|
|
|
|
if(be_random_body)
|
|
random_character(gender)
|
|
|
|
if(CONFIG_GET(flag/humans_need_surnames))
|
|
var/firstspace = findtext(real_name, " ")
|
|
var/name_length = length(real_name)
|
|
if(!firstspace) //we need a surname
|
|
real_name += " [pick(GLOB.last_names)]"
|
|
else if(firstspace == name_length)
|
|
real_name += "[pick(GLOB.last_names)]"
|
|
|
|
character.real_name = real_name
|
|
character.name = character.real_name
|
|
|
|
character.gender = gender
|
|
character.age = age
|
|
|
|
character.eye_color = eye_color
|
|
var/obj/item/organ/eyes/organ_eyes = character.getorgan(/obj/item/organ/eyes)
|
|
if(organ_eyes)
|
|
if(!initial(organ_eyes.eye_color))
|
|
organ_eyes.eye_color = eye_color
|
|
organ_eyes.old_eye_color = eye_color
|
|
character.hair_color = hair_color
|
|
character.facial_hair_color = facial_hair_color
|
|
|
|
character.skin_tone = skin_tone
|
|
character.hair_style = hair_style
|
|
character.facial_hair_style = facial_hair_style
|
|
character.underwear = underwear
|
|
character.undershirt = undershirt
|
|
character.socks = socks
|
|
|
|
character.backbag = backbag
|
|
|
|
character.dna.features = features.Copy()
|
|
character.dna.real_name = character.real_name
|
|
var/datum/species/chosen_species
|
|
if(pref_species.id in GLOB.roundstart_races)
|
|
chosen_species = pref_species.type
|
|
else
|
|
chosen_species = /datum/species/human
|
|
pref_species = new /datum/species/human
|
|
save_character()
|
|
character.set_species(chosen_species, icon_update=0)
|
|
|
|
//citadel code
|
|
character.give_genitals(TRUE)
|
|
character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially
|
|
character.canbearoused = arousable
|
|
|
|
if(icon_updates)
|
|
character.update_body()
|
|
character.update_hair()
|
|
character.update_body_parts()
|
|
character.update_genitals()
|
|
|
|
if(CONFIG_GET(flag/roundstart_traits))
|
|
SStraits.AssignTraits(character, parent)
|