mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Co-authored-by: Casey <a.roaming.shadow@gmail.com> Co-authored-by: Raeschen <rycoop29@gmail.com>
492 lines
16 KiB
Plaintext
492 lines
16 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 = 40
|
|
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
|
|
var/tgui_input_mode = FALSE // All the Input Boxes (Text,Number,List,Alert)
|
|
var/tgui_large_buttons = TRUE
|
|
var/tgui_swapped_buttons = 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/bday_month = 0 //Birthday month
|
|
var/bday_day = 0 //Birthday day
|
|
var/last_birthday_notification = 0 //The last year we were notified about our birthday
|
|
var/bday_announce = FALSE //Public announcement for birthdays
|
|
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 = -75 //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() //Language prefix keys
|
|
var/list/language_custom_keys = list() //Language custom call 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" //Current home or residence.
|
|
var/birthplace = "Unset" //Location of birth.
|
|
var/citizenship = "None" //Government or similar entity with which you hold citizenship.
|
|
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:2,7",
|
|
"2" = "character_preview_map:2,5",
|
|
"4" = "character_preview_map:2,3",
|
|
"8" = "character_preview_map:2,1",
|
|
"BG" = "character_preview_map:1,1 to 3,8",
|
|
"PMH" = "character_preview_map:2,7"
|
|
)
|
|
|
|
//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" //VOREStation Edit: "name" = list(BP_HEAD = list("on" = <enabled>, "color" = "#rgbcolor"), BP_TORSO = ...)
|
|
|
|
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/metadata_likes = ""
|
|
var/metadata_dislikes = ""
|
|
var/list/ignored_players = list()
|
|
|
|
var/client/client = null
|
|
var/client_ckey = null
|
|
|
|
// Communicator identity data
|
|
var/communicator_visibility = 0
|
|
|
|
// Default ringtone for character; if blank, use job default. YW EDIT
|
|
var/ttone = null
|
|
|
|
var/datum/category_collection/player_setup_collection/player_setup
|
|
var/datum/browser/panel
|
|
|
|
var/lastnews // Hash of last seen lobby news content.
|
|
var/lastlorenews //ID of last seen lore news article.
|
|
|
|
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
|
|
|
|
var/list/volume_channels = list()
|
|
|
|
///If they are currently in the process of swapping slots, don't let them open 999 windows for it and get confused
|
|
var/selecting_slots = FALSE
|
|
|
|
|
|
/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())
|
|
load_character()
|
|
|
|
|
|
/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>")
|
|
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) //CHOMPEdit _ch override.
|
|
if(!client)
|
|
return
|
|
|
|
var/obj/screen/setup_preview/pm_helper/PMH = LAZYACCESS(char_render_holders, "PMH")
|
|
if(!PMH)
|
|
PMH = new
|
|
LAZYSET(char_render_holders, "PMH", PMH)
|
|
client.screen |= PMH
|
|
PMH.screen_loc = preview_screen_locs["PMH"]
|
|
|
|
var/obj/screen/setup_preview/bg/BG = LAZYACCESS(char_render_holders, "BG")
|
|
if(!BG)
|
|
BG = new
|
|
BG.plane = TURF_PLANE
|
|
BG.icon = 'icons/effects/setup_backgrounds_vr.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["resetslot"])
|
|
if("No" == tgui_alert(usr, "This will reset the current slot. Continue?", "Reset current slot?", list("No", "Yes")))
|
|
return 0
|
|
if("No" == tgui_alert(usr, "Are you completely sure that you want to reset this character slot?", "Reset current slot?", list("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["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)
|
|
if(selecting_slots)
|
|
to_chat(user, "<span class='warning'>You already have a slot selection dialog open!</span>")
|
|
return
|
|
var/savefile/S = new /savefile(path)
|
|
if(!S)
|
|
error("Somehow missing savefile path?! [path]")
|
|
return
|
|
|
|
var/name
|
|
var/nickname //vorestation edit - This set appends nicknames to the save slot
|
|
var/list/charlist = list()
|
|
var/default //VOREStation edit
|
|
for(var/i=1, i<= config.character_slots, i++)
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
S["nickname"] >> nickname //vorestation edit
|
|
if(!name)
|
|
name = "[i] - \[Unused Slot\]"
|
|
else if(i == default_slot)
|
|
name = "►[i] - [name]"
|
|
else
|
|
name = "[i] - [name]"
|
|
if (i == default_slot) //VOREStation edit
|
|
default = "[name][nickname ? " ([nickname])" : ""]"
|
|
charlist["[name][nickname ? " ([nickname])" : ""]"] = i
|
|
|
|
selecting_slots = TRUE
|
|
var/choice = tgui_input_list(user, "Select a character to load:", "Load Slot", charlist, default)
|
|
selecting_slots = FALSE
|
|
if(!choice)
|
|
return
|
|
|
|
var/slotnum = charlist[choice]
|
|
if(!slotnum)
|
|
error("Player picked [choice] slot to load, but that wasn't one we sent.")
|
|
return
|
|
|
|
load_character(slotnum)
|
|
attempt_vr(user.client?.prefs_vr,"load_vore","") //VOREStation Edit
|
|
sanitize_preferences()
|
|
ShowChoices(user)
|
|
|
|
/datum/preferences/proc/open_copy_dialog(mob/user)
|
|
if(selecting_slots)
|
|
to_chat(user, "<span class='warning'>You already have a slot selection dialog open!</span>")
|
|
return
|
|
var/savefile/S = new /savefile(path)
|
|
if(!S)
|
|
error("Somehow missing savefile path?! [path]")
|
|
return
|
|
|
|
var/name
|
|
var/nickname //vorestation edit - This set appends nicknames to the save slot
|
|
var/list/charlist = list()
|
|
for(var/i=1, i<= config.character_slots, i++)
|
|
S.cd = "/character[i]"
|
|
S["real_name"] >> name
|
|
S["nickname"] >> nickname //vorestation edit
|
|
if(!name)
|
|
name = "[i] - \[Unused Slot\]"
|
|
if(i == default_slot)
|
|
name = "►[i] - [name]"
|
|
else
|
|
name = "[i] - [name]"
|
|
charlist["[name][nickname ? " ([nickname])" : ""]"] = i
|
|
|
|
selecting_slots = TRUE
|
|
var/choice = tgui_input_list(user, "Select a character to COPY TO:", "Copy Slot", charlist)
|
|
selecting_slots = FALSE
|
|
if(!choice)
|
|
return
|
|
|
|
var/slotnum = charlist[choice]
|
|
if(!slotnum)
|
|
error("Player picked [choice] slot to copy to, but that wasn't one we sent.")
|
|
return
|
|
|
|
overwrite_character(slotnum)
|
|
sanitize_preferences()
|
|
ShowChoices(user)
|