mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 02:34:00 +00:00
Tooling updates and removal of corrupt maps [MDB IGNORE] (#7620)
This commit is contained in:
@@ -1,498 +1,498 @@
|
||||
#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
|
||||
var/obfuscate_key = FALSE
|
||||
var/obfuscate_job = FALSE
|
||||
var/chat_timestamp = FALSE
|
||||
var/throwmode_loud = 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/blood_reagents = "default" //blood restoration reagents
|
||||
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
|
||||
var/digitigrade = 0
|
||||
|
||||
//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/custom_link = null
|
||||
|
||||
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.
|
||||
var/ringtone = 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("Yes" != tgui_alert(usr, "This will reset the current slot. Continue?", "Reset current slot?", list("No", "Yes")))
|
||||
return 0
|
||||
if("Yes" != 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)
|
||||
#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
|
||||
var/obfuscate_key = FALSE
|
||||
var/obfuscate_job = FALSE
|
||||
var/chat_timestamp = FALSE
|
||||
var/throwmode_loud = 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/blood_reagents = "default" //blood restoration reagents
|
||||
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
|
||||
var/digitigrade = 0
|
||||
|
||||
//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/custom_link = null
|
||||
|
||||
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.
|
||||
var/ringtone = 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("Yes" != tgui_alert(usr, "This will reset the current slot. Continue?", "Reset current slot?", list("No", "Yes")))
|
||||
return 0
|
||||
if("Yes" != 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)
|
||||
|
||||
Reference in New Issue
Block a user