mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-12 19:22:56 +00:00
Adds a Random Ambience Frequency and Ambience Chance Setting under Global, underneath Client FPS. Images here:    Self-explanatory. Random-Ambience-Frequency controls how long before it checks if it can play ambience to you again. Setting it to 0 disables the random re-play of ambience. Ambience Chance affects the % chance to play ambience to your client. It defaults to 35%, but can be set from 0 to 100 to disable it or always play every time you move into an area or have the Random Ambience check called.
442 lines
14 KiB
Plaintext
442 lines
14 KiB
Plaintext
#define SAVE_RESET -1
|
|
|
|
var/list/preferences_datums = list()
|
|
|
|
datum/preferences
|
|
//doohickeys for savefiles
|
|
var/path
|
|
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
|
|
var/savefile_version = 0
|
|
|
|
//non-preference stuff
|
|
var/warns = 0
|
|
var/muted = 0
|
|
var/last_ip
|
|
var/last_id
|
|
|
|
//game-preferences
|
|
var/lastchangelog = "" //Saved changlog filesize to detect if there was a change
|
|
var/ooccolor = "#010000" //Whatever this is set to acts as 'reset' color and is thus unusable as an actual custom color
|
|
var/be_special = 0 //Special role selection
|
|
var/UI_style = "Midnight"
|
|
var/UI_style_color = "#ffffff"
|
|
var/UI_style_alpha = 255
|
|
var/tooltipstyle = "Midnight" //Style for popup tooltips
|
|
var/client_fps = 0
|
|
var/ambience_freq = 5 // How often we're playing repeating ambience to a client.
|
|
var/ambience_chance = 35 // What's the % chance we'll play ambience (in conjunction with the above frequency)
|
|
|
|
var/tgui_fancy = TRUE
|
|
var/tgui_lock = FALSE
|
|
|
|
//character preferences
|
|
var/real_name //our character's name
|
|
var/be_random_name = 0 //whether we are a random name every round
|
|
var/nickname //our character's nickname
|
|
var/age = 30 //age of character
|
|
var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
|
|
var/b_type = "A+" //blood type (not-chooseable)
|
|
var/backbag = 2 //backpack type
|
|
var/pdachoice = 1 //PDA type
|
|
var/h_style = "Bald" //Hair type
|
|
var/r_hair = 0 //Hair color
|
|
var/g_hair = 0 //Hair color
|
|
var/b_hair = 0 //Hair color
|
|
var/grad_style = "none" //Gradient style
|
|
var/r_grad = 0 //Gradient color
|
|
var/g_grad = 0 //Gradient color
|
|
var/b_grad = 0 //Gradient color
|
|
var/f_style = "Shaved" //Face hair type
|
|
var/r_facial = 0 //Face hair color
|
|
var/g_facial = 0 //Face hair color
|
|
var/b_facial = 0 //Face hair color
|
|
var/s_tone = 0 //Skin tone
|
|
var/r_skin = 238 //Skin color // Vorestation edit, so color multi sprites can aren't BLACK AS THE VOID by default.
|
|
var/g_skin = 206 //Skin color // Vorestation edit, so color multi sprites can aren't BLACK AS THE VOID by default.
|
|
var/b_skin = 179 //Skin color // Vorestation edit, so color multi sprites can aren't BLACK AS THE VOID by default.
|
|
var/r_eyes = 0 //Eye color
|
|
var/g_eyes = 0 //Eye color
|
|
var/b_eyes = 0 //Eye color
|
|
var/species = SPECIES_HUMAN //Species datum to use.
|
|
var/species_preview //Used for the species selection window.
|
|
var/list/alternate_languages = list() //Secondary language(s)
|
|
var/list/language_prefixes = list() //Kanguage prefix keys
|
|
var/list/gear //Left in for Legacy reasons, will no longer save.
|
|
var/list/gear_list = list() //Custom/fluff item loadouts.
|
|
var/gear_slot = 1 //The current gear save slot
|
|
var/list/traits //Traits which modifier characters for better or worse (mostly worse).
|
|
var/synth_color = 0 //Lets normally uncolorable synth parts be colorable.
|
|
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
|
|
var/g_synth //Same as above
|
|
var/b_synth //Same as above
|
|
var/synth_markings = 1 //Enable/disable markings on synth parts. //VOREStation Edit - 1 by default
|
|
|
|
//Some faction information.
|
|
var/home_system = "Unset" //System of birth.
|
|
var/citizenship = "None" //Current home system.
|
|
var/faction = "None" //General associated faction.
|
|
var/religion = "None" //Religious association.
|
|
var/antag_faction = "None" //Antag associated faction.
|
|
var/antag_vis = "Hidden" //How visible antag association is to others.
|
|
|
|
//Mob preview
|
|
var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
|
|
var/static/list/preview_screen_locs = list(
|
|
"1" = "character_preview_map:1,5:-12",
|
|
"2" = "character_preview_map:1,3:15",
|
|
"4" = "character_preview_map:1:7,2:10",
|
|
"8" = "character_preview_map:1:-7,1:5",
|
|
"BG" = "character_preview_map:1,1 to 1,5"
|
|
)
|
|
|
|
//Jobs, uses bitflags
|
|
var/job_civilian_high = 0
|
|
var/job_civilian_med = 0
|
|
var/job_civilian_low = 0
|
|
|
|
var/job_medsci_high = 0
|
|
var/job_medsci_med = 0
|
|
var/job_medsci_low = 0
|
|
|
|
var/job_engsec_high = 0
|
|
var/job_engsec_med = 0
|
|
var/job_engsec_low = 0
|
|
|
|
//Keeps track of preferrence for not getting any wanted jobs
|
|
var/alternate_option = 1
|
|
|
|
var/used_skillpoints = 0
|
|
var/skill_specialization = null
|
|
var/list/skills = list() // skills can range from 0 to 3
|
|
|
|
// maps each organ to either null(intact), "cyborg" or "amputated"
|
|
// will probably not be able to do this for head and torso ;)
|
|
var/list/organ_data = list()
|
|
var/list/rlimb_data = list()
|
|
var/list/player_alt_titles = new() // the default name of a job like "Medical Doctor"
|
|
|
|
var/list/body_markings = list() // "name" = "#rgbcolor"
|
|
|
|
var/list/flavor_texts = list()
|
|
var/list/flavour_texts_robot = list()
|
|
|
|
var/list/body_descriptors = list()
|
|
|
|
var/med_record = ""
|
|
var/sec_record = ""
|
|
var/gen_record = ""
|
|
var/exploit_record = ""
|
|
var/disabilities = 0
|
|
|
|
var/economic_status = "Average"
|
|
|
|
var/uplinklocation = "PDA"
|
|
|
|
// OOC Metadata:
|
|
var/metadata = ""
|
|
var/list/ignored_players = list()
|
|
|
|
var/client/client = null
|
|
var/client_ckey = null
|
|
|
|
// Communicator identity data
|
|
var/communicator_visibility = 0
|
|
|
|
var/datum/category_collection/player_setup_collection/player_setup
|
|
var/datum/browser/panel
|
|
|
|
var/lastnews // Hash of last seen lobby news content.
|
|
|
|
var/examine_text_mode = 0 // Just examine text, include usage (description_info), switch to examine panel.
|
|
var/multilingual_mode = 0 // Default behaviour, delimiter-key-space, delimiter-key-delimiter, off
|
|
|
|
|
|
/datum/preferences/New(client/C)
|
|
player_setup = new(src)
|
|
set_biological_gender(pick(MALE, FEMALE))
|
|
real_name = random_name(identifying_gender,species)
|
|
b_type = RANDOM_BLOOD_TYPE
|
|
|
|
gear = list()
|
|
gear_list = list()
|
|
gear_slot = 1
|
|
|
|
if(istype(C))
|
|
client = C
|
|
client_ckey = C.ckey
|
|
if(!IsGuestKey(C.key))
|
|
load_path(C.ckey)
|
|
if(load_preferences())
|
|
if(load_character())
|
|
return
|
|
|
|
/datum/preferences/Destroy()
|
|
. = ..()
|
|
QDEL_LIST_ASSOC_VAL(char_render_holders)
|
|
|
|
/datum/preferences/proc/ZeroSkills(var/forced = 0)
|
|
for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V])
|
|
if(!skills.Find(S.ID) || forced)
|
|
skills[S.ID] = SKILL_NONE
|
|
|
|
/datum/preferences/proc/CalculateSkillPoints()
|
|
used_skillpoints = 0
|
|
for(var/V in SKILLS) for(var/datum/skill/S in SKILLS[V])
|
|
var/multiplier = 1
|
|
switch(skills[S.ID])
|
|
if(SKILL_NONE)
|
|
used_skillpoints += 0 * multiplier
|
|
if(SKILL_BASIC)
|
|
used_skillpoints += 1 * multiplier
|
|
if(SKILL_ADEPT)
|
|
// secondary skills cost less
|
|
if(S.secondary)
|
|
used_skillpoints += 1 * multiplier
|
|
else
|
|
used_skillpoints += 3 * multiplier
|
|
if(SKILL_EXPERT)
|
|
// secondary skills cost less
|
|
if(S.secondary)
|
|
used_skillpoints += 3 * multiplier
|
|
else
|
|
used_skillpoints += 6 * multiplier
|
|
|
|
/datum/preferences/proc/GetSkillClass(points)
|
|
return CalculateSkillClass(points, age)
|
|
|
|
/proc/CalculateSkillClass(points, age)
|
|
if(points <= 0) return "Unconfigured"
|
|
// skill classes describe how your character compares in total points
|
|
points -= min(round((age - 20) / 2.5), 4) // every 2.5 years after 20, one extra skillpoint
|
|
if(age > 30)
|
|
points -= round((age - 30) / 5) // every 5 years after 30, one extra skillpoint
|
|
switch(points)
|
|
if(-1000 to 3)
|
|
return "Terrifying"
|
|
if(4 to 6)
|
|
return "Below Average"
|
|
if(7 to 10)
|
|
return "Average"
|
|
if(11 to 14)
|
|
return "Above Average"
|
|
if(15 to 18)
|
|
return "Exceptional"
|
|
if(19 to 24)
|
|
return "Genius"
|
|
if(24 to 1000)
|
|
return "God"
|
|
|
|
/datum/preferences/proc/ShowChoices(mob/user)
|
|
if(!user || !user.client) return
|
|
|
|
if(!get_mob_by_key(client_ckey))
|
|
to_chat(user, "<span class='danger'>No mob exists for the given client!</span>")
|
|
close_load_dialog(user)
|
|
return
|
|
|
|
if(!char_render_holders)
|
|
update_preview_icon()
|
|
show_character_previews()
|
|
|
|
var/dat = "<html><body><center>"
|
|
|
|
if(path)
|
|
dat += "Slot - "
|
|
dat += "<a href='?src=\ref[src];load=1'>Load slot</a> - "
|
|
dat += "<a href='?src=\ref[src];save=1'>Save slot</a> - "
|
|
dat += "<a href='?src=\ref[src];reload=1'>Reload slot</a> - "
|
|
dat += "<a href='?src=\ref[src];resetslot=1'>Reset slot</a> - "
|
|
dat += "<a href='?src=\ref[src];copy=1'>Copy slot</a>"
|
|
|
|
else
|
|
dat += "Please create an account to save your preferences."
|
|
|
|
dat += "<br>"
|
|
dat += player_setup.header()
|
|
dat += "<br><HR></center>"
|
|
dat += player_setup.content(user)
|
|
|
|
dat += "</html></body>"
|
|
//user << browse(dat, "window=preferences;size=635x736")
|
|
winshow(user, "preferences_window", TRUE)
|
|
var/datum/browser/popup = new(user, "preferences_browser", "Character Setup", 800, 800)
|
|
popup.set_content(dat)
|
|
popup.open(FALSE) // Skip registring onclose on the browser pane
|
|
onclose(user, "preferences_window", src) // We want to register on the window itself
|
|
|
|
/datum/preferences/proc/update_character_previews(mutable_appearance/MA)
|
|
if(!client)
|
|
return
|
|
|
|
var/obj/screen/setup_preview/bg/BG = LAZYACCESS(char_render_holders, "BG")
|
|
if(!BG)
|
|
BG = new
|
|
BG.plane = TURF_PLANE
|
|
BG.icon = 'icons/effects/128x48.dmi'
|
|
BG.pref = src
|
|
LAZYSET(char_render_holders, "BG", BG)
|
|
client.screen |= BG
|
|
BG.icon_state = bgstate
|
|
BG.screen_loc = preview_screen_locs["BG"]
|
|
|
|
for(var/D in global.cardinal)
|
|
var/obj/screen/setup_preview/O = LAZYACCESS(char_render_holders, "[D]")
|
|
if(!O)
|
|
O = new
|
|
O.pref = src
|
|
LAZYSET(char_render_holders, "[D]", O)
|
|
client.screen |= O
|
|
O.appearance = MA
|
|
O.dir = D
|
|
O.screen_loc = preview_screen_locs["[D]"]
|
|
|
|
/datum/preferences/proc/show_character_previews()
|
|
if(!client || !char_render_holders)
|
|
return
|
|
for(var/render_holder in char_render_holders)
|
|
client.screen |= char_render_holders[render_holder]
|
|
|
|
/datum/preferences/proc/clear_character_previews()
|
|
for(var/index in char_render_holders)
|
|
var/obj/screen/S = char_render_holders[index]
|
|
client?.screen -= S
|
|
qdel(S)
|
|
char_render_holders = null
|
|
|
|
/datum/preferences/proc/process_link(mob/user, list/href_list)
|
|
if(!user) return
|
|
|
|
if(!istype(user, /mob/new_player)) return
|
|
|
|
if(href_list["preference"] == "open_whitelist_forum")
|
|
if(config.forumurl)
|
|
user << link(config.forumurl)
|
|
else
|
|
to_chat(user, "<span class='danger'>The forum URL is not set in the server configuration.</span>")
|
|
return
|
|
ShowChoices(usr)
|
|
return 1
|
|
|
|
/datum/preferences/Topic(href, list/href_list)
|
|
if(..())
|
|
return 1
|
|
|
|
if(href_list["save"])
|
|
save_preferences()
|
|
save_character()
|
|
else if(href_list["reload"])
|
|
load_preferences()
|
|
load_character()
|
|
attempt_vr(client.prefs_vr,"load_vore","") //VOREStation Edit
|
|
sanitize_preferences()
|
|
else if(href_list["load"])
|
|
if(!IsGuestKey(usr.key))
|
|
open_load_dialog(usr)
|
|
return 1
|
|
else if(href_list["changeslot"])
|
|
load_character(text2num(href_list["changeslot"]))
|
|
attempt_vr(client.prefs_vr,"load_vore","") //VOREStation Edit
|
|
sanitize_preferences()
|
|
close_load_dialog(usr)
|
|
else if(href_list["resetslot"])
|
|
if("No" == alert("This will reset the current slot. Continue?", "Reset current slot?", "No", "Yes"))
|
|
return 0
|
|
if("No" == alert("Are you completely sure that you want to reset this character slot?", "Reset current slot?", "No", "Yes"))
|
|
return 0
|
|
load_character(SAVE_RESET)
|
|
sanitize_preferences()
|
|
else if(href_list["copy"])
|
|
if(!IsGuestKey(usr.key))
|
|
open_copy_dialog(usr)
|
|
return 1
|
|
else if(href_list["overwrite"])
|
|
overwrite_character(text2num(href_list["overwrite"]))
|
|
sanitize_preferences()
|
|
close_load_dialog(usr)
|
|
else if(href_list["close"])
|
|
// User closed preferences window, cleanup anything we need to.
|
|
clear_character_previews()
|
|
return 1
|
|
else
|
|
return 0
|
|
|
|
ShowChoices(usr)
|
|
return 1
|
|
|
|
/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = TRUE)
|
|
// Sanitizing rather than saving as someone might still be editing when copy_to occurs.
|
|
player_setup.sanitize_setup()
|
|
|
|
// This needs to happen before anything else becuase it sets some variables.
|
|
character.set_species(species)
|
|
// Special Case: This references variables owned by two different datums, so do it here.
|
|
if(be_random_name)
|
|
real_name = random_name(identifying_gender,species)
|
|
|
|
// Ask the preferences datums to apply their own settings to the new mob
|
|
player_setup.copy_to_mob(character)
|
|
|
|
// VOREStation Edit - Sync up all their organs and species one final time
|
|
character.force_update_organs()
|
|
|
|
if(icon_updates)
|
|
character.force_update_limbs()
|
|
character.update_icons_body()
|
|
character.update_mutations()
|
|
character.update_underwear()
|
|
character.update_hair()
|
|
|
|
if(LAZYLEN(character.descriptors))
|
|
for(var/entry in body_descriptors)
|
|
character.descriptors[entry] = body_descriptors[entry]
|
|
|
|
/datum/preferences/proc/open_load_dialog(mob/user)
|
|
var/dat = "<body>"
|
|
dat += "<tt><center>"
|
|
|
|
var/savefile/S = new /savefile(path)
|
|
if(S)
|
|
dat += "<b>Select a character slot to load</b><hr>"
|
|
var/name
|
|
for(var/i=1, i<= config.character_slots, i++)
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
if(!name) name = "Character[i]"
|
|
if(i==default_slot)
|
|
name = "<b>[name]</b>"
|
|
dat += "<a href='?src=\ref[src];changeslot=[i]'>[name]</a><br>"
|
|
|
|
dat += "<hr>"
|
|
dat += "</center></tt>"
|
|
//user << browse(dat, "window=saves;size=300x390")
|
|
panel = new(user, "Character Slots", "Character Slots", 300, 390, src)
|
|
panel.set_content(dat)
|
|
panel.open()
|
|
|
|
/datum/preferences/proc/close_load_dialog(mob/user)
|
|
//user << browse(null, "window=saves")
|
|
panel.close()
|
|
|
|
/datum/preferences/proc/open_copy_dialog(mob/user)
|
|
var/dat = "<body>"
|
|
dat += "<tt><center>"
|
|
|
|
var/savefile/S = new /savefile(path)
|
|
if(S)
|
|
dat += "<b>Select a character slot to overwrite</b><br>"
|
|
dat += "<b>You will then need to save to confirm</b><hr>"
|
|
var/name
|
|
for(var/i=1, i<= config.character_slots, i++)
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
if(!name) name = "Character[i]"
|
|
if(i==default_slot)
|
|
name = "<b>[name]</b>"
|
|
dat += "<a href='?src=\ref[src];overwrite=[i]'>[name]</a><br>"
|
|
|
|
dat += "<hr>"
|
|
dat += "</center></tt>"
|
|
panel = new(user, "Character Slots", "Character Slots", 300, 390, src)
|
|
panel.set_content(dat)
|
|
panel.open()
|