Merge pull request #3025 from Crazylemon64/infinite_antags

Infinite antag tags
This commit is contained in:
Fox McCloud
2015-12-30 13:52:41 -05:00
53 changed files with 1726 additions and 2130 deletions
File diff suppressed because it is too large Load Diff
+212 -62
View File
@@ -5,7 +5,7 @@
UI_style,
UI_style_color,
UI_style_alpha,
be_special,
be_role,
default_slot,
toggles,
sound,
@@ -28,18 +28,19 @@
UI_style = query.item[2]
UI_style_color = query.item[3]
UI_style_alpha = text2num(query.item[4])
be_special = text2num(query.item[5])
be_special = params2list(query.item[5])
default_slot = text2num(query.item[6])
toggles = text2num(query.item[7])
sound = text2num(query.item[8])
randomslot = text2num(query.item[9])
volume = text2num(query.item[10])
old_roles_to_new(C)
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
// lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
sound = sanitize_integer(sound, 0, 65535, initial(sound))
@@ -51,13 +52,19 @@
/datum/preferences/proc/save_preferences(client/C)
// Might as well scrub out any malformed be_special list entries while we're here
for (var/role in be_special)
if(!(role in special_roles))
log_to_dd("[C.key] had a malformed role entry: '[role]'. Removing!")
be_special -= role
var/DBQuery/query = dbcon.NewQuery({"UPDATE [format_table_name("player")]
SET
ooccolor='[ooccolor]',
UI_style='[UI_style]',
UI_style_color='[UI_style_color]',
UI_style_alpha='[UI_style_alpha]',
be_special='[be_special]',
be_role='[list2params(sql_sanitize_text_list(be_special))]',
default_slot='[default_slot]',
toggles='[toggles]',
sound='[sound]',
@@ -82,7 +89,60 @@
var/DBQuery/firstquery = dbcon.NewQuery("UPDATE [format_table_name("player")] SET default_slot=[slot] WHERE ckey='[C.ckey]'")
firstquery.Execute()
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[slot]'")
// Let's not have this explode if you sneeze on the DB
var/DBQuery/query = dbcon.NewQuery({"SELECT
OOC_Notes,
real_name,
name_is_always_random,
gender,
age,
species,
language,
hair_red,
hair_green,
hair_blue,
facial_red,
facial_green,
facial_blue,
skin_tone,
skin_red,
skin_green,
skin_blue,
hair_style_name,
facial_style_name,
eyes_red,
eyes_green,
eyes_blue,
underwear,
undershirt,
backbag,
b_type,
alternate_option,
job_support_high,
job_support_med,
job_support_low,
job_medsci_high,
job_medsci_med,
job_medsci_low,
job_engsec_high,
job_engsec_med,
job_engsec_low,
job_karma_high,
job_karma_med,
job_karma_low,
flavor_text,
med_record,
sec_record,
gen_record,
disabilities,
player_alt_titles,
organ_data,
rlimb_data,
nanotrasen_relation,
speciesprefs,
socks,
body_accessory
FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' AND slot='[slot]'"})
if(!query.Execute())
var/err = query.ErrorMsg()
log_game("SQL ERROR during character slot loading. Error : \[[err]\]\n")
@@ -91,68 +151,67 @@
while(query.NextRow())
//Character
metadata = query.item[4]
real_name = query.item[5]
be_random_name = text2num(query.item[6])
gender = query.item[7]
age = text2num(query.item[8])
species = query.item[9]
language = query.item[10]
metadata = query.item[1]
real_name = query.item[2]
be_random_name = text2num(query.item[3])
gender = query.item[4]
age = text2num(query.item[5])
species = query.item[6]
language = query.item[7]
//colors to be consolidated into hex strings (requires some work with dna code)
r_hair = text2num(query.item[11])
g_hair = text2num(query.item[12])
b_hair = text2num(query.item[13])
r_facial = text2num(query.item[14])
g_facial = text2num(query.item[15])
b_facial = text2num(query.item[16])
s_tone = text2num(query.item[17])
r_skin = text2num(query.item[18])
g_skin = text2num(query.item[19])
b_skin = text2num(query.item[20])
h_style = query.item[21]
f_style = query.item[22]
r_eyes = text2num(query.item[23])
g_eyes = text2num(query.item[24])
b_eyes = text2num(query.item[25])
underwear = query.item[26]
undershirt = query.item[27]
backbag = text2num(query.item[28])
b_type = query.item[29]
r_hair = text2num(query.item[8])
g_hair = text2num(query.item[9])
b_hair = text2num(query.item[10])
r_facial = text2num(query.item[11])
g_facial = text2num(query.item[12])
b_facial = text2num(query.item[13])
s_tone = text2num(query.item[14])
r_skin = text2num(query.item[15])
g_skin = text2num(query.item[16])
b_skin = text2num(query.item[17])
h_style = query.item[18]
f_style = query.item[19]
r_eyes = text2num(query.item[20])
g_eyes = text2num(query.item[21])
b_eyes = text2num(query.item[22])
underwear = query.item[23]
undershirt = query.item[24]
backbag = text2num(query.item[25])
b_type = query.item[26]
//Jobs
alternate_option = text2num(query.item[30])
job_support_high = text2num(query.item[31])
job_support_med = text2num(query.item[32])
job_support_low = text2num(query.item[33])
job_medsci_high = text2num(query.item[34])
job_medsci_med = text2num(query.item[35])
job_medsci_low = text2num(query.item[36])
job_engsec_high = text2num(query.item[37])
job_engsec_med = text2num(query.item[38])
job_engsec_low = text2num(query.item[39])
job_karma_high = text2num(query.item[40])
job_karma_med = text2num(query.item[41])
job_karma_low = text2num(query.item[42])
alternate_option = text2num(query.item[27])
job_support_high = text2num(query.item[28])
job_support_med = text2num(query.item[29])
job_support_low = text2num(query.item[30])
job_medsci_high = text2num(query.item[31])
job_medsci_med = text2num(query.item[32])
job_medsci_low = text2num(query.item[33])
job_engsec_high = text2num(query.item[34])
job_engsec_med = text2num(query.item[35])
job_engsec_low = text2num(query.item[36])
job_karma_high = text2num(query.item[37])
job_karma_med = text2num(query.item[38])
job_karma_low = text2num(query.item[39])
//Miscellaneous
flavor_text = query.item[43]
med_record = query.item[44]
sec_record = query.item[45]
gen_record = query.item[46]
be_special = text2num(query.item[47])
disabilities = text2num(query.item[48])
player_alt_titles = params2list(query.item[49])
organ_data = params2list(query.item[50])
rlimb_data = params2list(query.item[51])
nanotrasen_relation = query.item[52]
speciesprefs = text2num(query.item[53])
flavor_text = query.item[40]
med_record = query.item[41]
sec_record = query.item[42]
gen_record = query.item[43]
disabilities = text2num(query.item[44])
player_alt_titles = params2list(query.item[45])
organ_data = params2list(query.item[46])
rlimb_data = params2list(query.item[47])
nanotrasen_relation = query.item[48]
speciesprefs = text2num(query.item[49])
//socks
socks = query.item[54]
body_accessory = query.item[55]
socks = query.item[50]
body_accessory = query.item[51]
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
@@ -198,7 +257,6 @@
job_karma_med = sanitize_integer(job_karma_med, 0, 65535, initial(job_karma_med))
job_karma_low = sanitize_integer(job_karma_low, 0, 65535, initial(job_karma_low))
disabilities = sanitize_integer(disabilities, 0, 65535, initial(disabilities))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
socks = sanitize_text(socks, initial(socks))
body_accessory = sanitize_text(body_accessory, initial(body_accessory))
@@ -269,7 +327,6 @@
sec_record='[sql_sanitize_text(html_decode(sec_record))]',
gen_record='[sql_sanitize_text(html_decode(gen_record))]',
player_alt_titles='[playertitlelist]',
be_special='[be_special]',
disabilities='[disabilities]',
organ_data='[organlist]',
rlimb_data='[rlimblist]',
@@ -303,7 +360,7 @@
job_engsec_high, job_engsec_med, job_engsec_low,
job_karma_high, job_karma_med, job_karma_low,
flavor_text, med_record, sec_record, gen_record,
player_alt_titles, be_special,
player_alt_titles,
disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs,
socks, body_accessory)
@@ -322,7 +379,7 @@
'[job_engsec_high]', '[job_engsec_med]', '[job_engsec_low]',
'[job_karma_high]', '[job_karma_med]', '[job_karma_low]',
'[sql_sanitize_text(html_encode(flavor_text))]', '[sql_sanitize_text(html_encode(med_record))]', '[sql_sanitize_text(html_encode(sec_record))]', '[sql_sanitize_text(html_encode(gen_record))]',
'[playertitlelist]', '[be_special]',
'[playertitlelist]',
'[disabilities]', '[organlist]', '[rlimblist]', '[nanotrasen_relation]', '[speciesprefs]',
'[socks]', '[body_accessory]')
@@ -335,6 +392,99 @@
message_admins("SQL ERROR during character slot saving. Error : \[[err]\]\n")
return
return 1
// If you see this proc lying around and don't know why it's there, expunge it, as this is for a short-term DB update, starting 27/12/2015
// 0 on failed update, 1 on success
/datum/preferences/proc/old_roles_to_new(var/client/C)
var/DBQuery/query = dbcon.NewQuery({"
SELECT be_special
FROM [format_table_name("player")]
WHERE ckey='[C.ckey]'"})
if(!query.Execute())
return 0
var/old_be_special
while(query.NextRow())
old_be_special = text2num(query.item[1])
if(isnull(old_be_special))
message_admins("SQL NOTICE: be_special has been purged from the database, bug the coders.\n")
return 0
old_be_special = sanitize_integer(old_be_special, 0, 65535)
var/B_traitor = 1
var/B_operative = 2
var/B_changeling = 4
var/B_wizard = 8
var/B_malf = 16
var/B_rev = 32
var/B_alien = 64
var/B_pai = 128
var/B_cultist = 256
var/B_ninja = 512
var/B_raider = 1024
var/B_vampire = 2048
var/B_mutineer = 4096
var/B_blob = 8192
var/B_shadowling = 16384
var/B_revenant = 32768
var/list/archived = list(B_traitor,B_operative,B_changeling,B_wizard,B_malf,B_rev,B_alien,B_pai,B_cultist,B_ninja,B_raider,B_vampire,B_mutineer,B_blob,B_shadowling,B_revenant)
// meow meow I am the copy cat
for(var/flag in archived)
if(old_be_special & flag)
switch(flag)
// hello i am byond i think constant variables r dumm
if(1)
be_special |= ROLE_TRAITOR
if(2)
be_special |= ROLE_OPERATIVE
if(4)
be_special |= ROLE_CHANGELING
if(8)
be_special |= ROLE_WIZARD
if(16)
be_special |= ROLE_MALF
if(32)
be_special |= ROLE_REV
if(64)
be_special |= ROLE_ALIEN
be_special |= ROLE_SENTIENT
be_special |= ROLE_DEMON
be_special |= ROLE_BORER
if(128)
be_special |= ROLE_PAI
be_special |= ROLE_POSIBRAIN
be_special |= ROLE_GUARDIAN
if(256)
be_special |= ROLE_CULTIST
if(512)
be_special |= ROLE_NINJA
if(1024)
be_special |= ROLE_RAIDER
if(2048)
be_special |= ROLE_VAMPIRE
if(4096)
be_special |= ROLE_MUTINEER
if(8192)
be_special |= ROLE_BLOB
if(16384)
be_special |= ROLE_SHADOWLING
if(32768)
be_special |= ROLE_REVENANT
var/DBQuery/query2 = dbcon.NewQuery({"UPDATE [format_table_name("player")]
SET
be_role='[list2params(sql_sanitize_text_list(be_special))]'
WHERE ckey='[C.ckey]'"}
)
if(!query2.Execute())
var/err = query2.ErrorMsg()
log_game("SQL ERROR during saving player preferences. Error : \[[err]\]\n")
message_admins("SQL ERROR during saving player preferences. Error : \[[err]\]\n")
return
return 1
/*
/datum/preferences/proc/random_character(client/C)
var/DBQuery/query = dbcon.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey='[C.ckey]' ORDER BY slot")
-443
View File
@@ -1,443 +0,0 @@
#define SAVEFILE_VERSION_MIN 8
#define SAVEFILE_VERSION_MAX 12
//handles converting savefiles to new formats
//MAKE SURE YOU KEEP THIS UP TO DATE!
//If the sanity checks are capable of handling any issues. Only increase SAVEFILE_VERSION_MAX,
//this will mean that savefile_version will still be over SAVEFILE_VERSION_MIN, meaning
//this savefile update doesn't run everytime we load from the savefile.
//This is mainly for format changes, such as the bitflags in toggles changing order or something.
//if a file can't be updated, return 0 to delete it and start again
//if a file was updated, return 1
/datum/preferences/proc/savefile_update()
if(savefile_version < 8) //lazily delete everything + additional files so they can be saved in the new format
for(var/ckey in preferences_datums)
var/datum/preferences/D = preferences_datums[ckey]
if(D == src)
var/delpath = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/"
if(delpath && fexists(delpath))
fdel(delpath)
break
return 0
if(savefile_version == SAVEFILE_VERSION_MAX) //update successful.
save_preferences()
save_character()
return 1
return 0
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey) return
path = "data/player_saves/[copytext(ckey,1,2)]/[ckey]/[filename]"
savefile_version = SAVEFILE_VERSION_MAX
/*
/datum/preferences/proc/load_preferences()
if(!path) return 0
if(!fexists(path)) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/"
S["version"] >> savefile_version
//Conversion
if(!savefile_version || !isnum(savefile_version) || savefile_version < SAVEFILE_VERSION_MIN || savefile_version > SAVEFILE_VERSION_MAX)
if(!savefile_update()) //handles updates
savefile_version = SAVEFILE_VERSION_MAX
save_preferences()
save_character()
return 0
//general preferences
S["ooccolor"] >> ooccolor
S["lastchangelog"] >> lastchangelog
S["UI_style"] >> UI_style
S["be_special"] >> be_special
S["default_slot"] >> default_slot
S["toggles"] >> toggles
S["sound"] >> sound
S["UI_style_color"] >> UI_style_color
S["UI_style_alpha"] >> UI_style_alpha
S["randomslot"] >> randomslot
S["volume"] >> volume
//Sanitize
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style))
be_special = sanitize_integer(be_special, 0, 65535, initial(be_special))
default_slot = sanitize_integer(default_slot, 1, MAX_SAVE_SLOTS, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
sound = sanitize_integer(sound, 0, 65535, initial(toggles))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
randomslot = sanitize_integer(randomslot, 0, 1, initial(randomslot))
volume = sanitize_integer(volume, 0, 100, initial(volume))
return 1
/datum/preferences/proc/save_preferences()
if(!path) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/"
S["version"] << savefile_version
//general preferences
S["ooccolor"] << ooccolor
S["lastchangelog"] << lastchangelog
S["UI_style"] << UI_style
S["be_special"] << be_special
S["default_slot"] << default_slot
S["toggles"] << toggles
S["sound"] << sound
S["UI_style_color"] << UI_style_color
S["UI_style_alpha"] << UI_style_alpha
S["randomslot"] << randomslot
S["volume"] << volume
return 1
//saving volume changes
/datum/preferences/proc/save_volume()
if(!path) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/"
S["volume"] << volume
return 1
*/
/datum/preferences/proc/load_save(dir)
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = dir
//Character
S["OOC_Notes"] >> metadata
S["real_name"] >> real_name
S["name_is_always_random"] >> be_random_name
S["gender"] >> gender
S["age"] >> age
S["species"] >> species
S["language"] >> language
S["spawnpoint"] >> spawnpoint
//colors to be consolidated into hex strings (requires some work with dna code)
S["hair_red"] >> r_hair
S["hair_green"] >> g_hair
S["hair_blue"] >> b_hair
S["facial_red"] >> r_facial
S["facial_green"] >> g_facial
S["facial_blue"] >> b_facial
S["skin_tone"] >> s_tone
S["skin_red"] >> r_skin
S["skin_green"] >> g_skin
S["skin_blue"] >> b_skin
S["hair_style_name"] >> h_style
S["facial_style_name"] >> f_style
S["eyes_red"] >> r_eyes
S["eyes_green"] >> g_eyes
S["eyes_blue"] >> b_eyes
S["underwear"] >> underwear
S["undershirt"] >> undershirt
S["socks"] >> socks
S["backbag"] >> backbag
S["b_type"] >> b_type
S["accent"] >> accent
S["voice"] >> voice
S["pitch"] >> pitch
S["talkspeed"] >> talkspeed
//Jobs
S["alternate_option"] >> alternate_option
S["job_civilian_high"] >> job_civilian_high
S["job_civilian_med"] >> job_civilian_med
S["job_civilian_low"] >> job_civilian_low
S["job_medsci_high"] >> job_medsci_high
S["job_medsci_med"] >> job_medsci_med
S["job_medsci_low"] >> job_medsci_low
S["job_engsec_high"] >> job_engsec_high
S["job_engsec_med"] >> job_engsec_med
S["job_engsec_low"] >> job_engsec_low
S["job_karma_high"] >> job_karma_high
S["job_karma_med"] >> job_karma_med
S["job_karma_low"] >> job_karma_low
//Miscellaneous
S["flavor_text"] >> flavor_text
S["med_record"] >> med_record
S["sec_record"] >> sec_record
S["gen_record"] >> gen_record
S["be_special"] >> be_special
S["disabilities"] >> disabilities
S["player_alt_titles"] >> player_alt_titles
S["organ_data"] >> organ_data
S["nanotrasen_relation"] >> nanotrasen_relation
//S["skin_style"] >> skin_style
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
if(isnull(species)) species = "Human"
if(isnull(language)) language = "None"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name(gender,species)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair))
g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair))
b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair))
r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial))
g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
underwear = sanitize_integer(underwear, 1, underwear_m.len, initial(underwear))
undershirt = sanitize_integer(undershirt, 1, undershirt_t.len, initial(undershirt))
socks = sanitize_integer(socks,1 socks_t.len, initial(socks))
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
b_type = sanitize_text(b_type, initial(b_type))
accent = sanitize_text(accent, initial(accent))
voice = sanitize_text(voice, initial(voice))
pitch = sanitize_text(pitch, initial(pitch))
talkspeed = sanitize_text(talkspeed, initial(talkspeed))
alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
job_karma_high = sanitize_integer(job_karma_high, 0, 65535, initial(job_karma_high))
job_karma_med = sanitize_integer(job_karma_med, 0, 65535, initial(job_karma_med))
job_karma_low = sanitize_integer(job_karma_low, 0, 65535, initial(job_karma_low))
if(isnull(disabilities)) disabilities = 0
if(!player_alt_titles) player_alt_titles = new()
if(!organ_data) src.organ_data = list()
//if(!skin_style) skin_style = "Default"
/datum/preferences/proc/random_character()
if(!path) return 0
if(!fexists(path)) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
var/list/saves = list()
var/name
for(var/i=1, i<=MAX_SAVE_SLOTS, i++)
S.cd = "/character[i]"
S["real_name"] >> name
if(!name) continue
saves.Add(S.cd)
if(!saves.len)
load_character()
return 0
S.cd = pick(saves)
load_save(S.cd)
return 1
/*
/datum/preferences/proc/load_character(slot)
if(!path) return 0
if(!fexists(path)) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/"
if(!slot) slot = default_slot
slot = sanitize_integer(slot, 1, MAX_SAVE_SLOTS, initial(default_slot))
if(slot != default_slot)
default_slot = slot
S["default_slot"] << slot
S.cd = "/character[slot]"
load_save(S.cd)
Now loaded by proc load_save(S.cd)
//Character
S["OOC_Notes"] >> metadata
S["real_name"] >> real_name
S["name_is_always_random"] >> be_random_name
S["gender"] >> gender
S["age"] >> age
S["species"] >> species
S["language"] >> language
//colors to be consolidated into hex strings (requires some work with dna code)
S["hair_red"] >> r_hair
S["hair_green"] >> g_hair
S["hair_blue"] >> b_hair
S["facial_red"] >> r_facial
S["facial_green"] >> g_facial
S["facial_blue"] >> b_facial
S["skin_tone"] >> s_tone
S["skin_red"] >> r_skin
S["skin_green"] >> g_skin
S["skin_blue"] >> b_skin
S["hair_style_name"] >> h_style
S["facial_style_name"] >> f_style
S["eyes_red"] >> r_eyes
S["eyes_green"] >> g_eyes
S["eyes_blue"] >> b_eyes
S["underwear"] >> underwear
S["undershirt"] >> undershirt
S["backbag"] >> backbag
S["b_type"] >> b_type
//Jobs
S["alternate_option"] >> alternate_option
S["job_civilian_high"] >> job_civilian_high
S["job_civilian_med"] >> job_civilian_med
S["job_civilian_low"] >> job_civilian_low
S["job_medsci_high"] >> job_medsci_high
S["job_medsci_med"] >> job_medsci_med
S["job_medsci_low"] >> job_medsci_low
S["job_engsec_high"] >> job_engsec_high
S["job_engsec_med"] >> job_engsec_med
S["job_engsec_low"] >> job_engsec_low
//Miscellaneous
S["flavor_text"] >> flavor_text
S["med_record"] >> med_record
S["sec_record"] >> sec_record
S["gen_record"] >> gen_record
S["be_special"] >> be_special
S["disabilities"] >> disabilities
S["player_alt_titles"] >> player_alt_titles
S["organ_data"] >> organ_data
S["nanotrasen_relation"] >> nanotrasen_relation
//S["skin_style"] >> skin_style
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
if(isnull(species)) species = "Human"
if(isnull(language)) language = "None"
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
if(!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
gender = sanitize_gender(gender)
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
r_hair = sanitize_integer(r_hair, 0, 255, initial(r_hair))
g_hair = sanitize_integer(g_hair, 0, 255, initial(g_hair))
b_hair = sanitize_integer(b_hair, 0, 255, initial(b_hair))
r_facial = sanitize_integer(r_facial, 0, 255, initial(r_facial))
g_facial = sanitize_integer(g_facial, 0, 255, initial(g_facial))
b_facial = sanitize_integer(b_facial, 0, 255, initial(b_facial))
s_tone = sanitize_integer(s_tone, -185, 34, initial(s_tone))
r_skin = sanitize_integer(r_skin, 0, 255, initial(r_skin))
g_skin = sanitize_integer(g_skin, 0, 255, initial(g_skin))
b_skin = sanitize_integer(b_skin, 0, 255, initial(b_skin))
h_style = sanitize_inlist(h_style, hair_styles_list, initial(h_style))
f_style = sanitize_inlist(f_style, facial_hair_styles_list, initial(f_style))
r_eyes = sanitize_integer(r_eyes, 0, 255, initial(r_eyes))
g_eyes = sanitize_integer(g_eyes, 0, 255, initial(g_eyes))
b_eyes = sanitize_integer(b_eyes, 0, 255, initial(b_eyes))
underwear = sanitize_integer(underwear, 1, underwear_m.len, initial(underwear))
undershirt = sanitize_integer(undershirt, 1, undershirt_t.len, initial(undershirt))
backbag = sanitize_integer(backbag, 1, backbaglist.len, initial(backbag))
b_type = sanitize_text(b_type, initial(b_type))
alternate_option = sanitize_integer(alternate_option, 0, 2, initial(alternate_option))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
job_medsci_high = sanitize_integer(job_medsci_high, 0, 65535, initial(job_medsci_high))
job_medsci_med = sanitize_integer(job_medsci_med, 0, 65535, initial(job_medsci_med))
job_medsci_low = sanitize_integer(job_medsci_low, 0, 65535, initial(job_medsci_low))
job_engsec_high = sanitize_integer(job_engsec_high, 0, 65535, initial(job_engsec_high))
job_engsec_med = sanitize_integer(job_engsec_med, 0, 65535, initial(job_engsec_med))
job_engsec_low = sanitize_integer(job_engsec_low, 0, 65535, initial(job_engsec_low))
if(isnull(disabilities)) disabilities = 0
if(!player_alt_titles) player_alt_titles = new()
if(!organ_data) src.organ_data = list()
//if(!skin_style) skin_style = "Default"
return 1
/datum/preferences/proc/save_character()
if(!path) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/character[default_slot]"
//Character
S["OOC_Notes"] << metadata
S["real_name"] << real_name
S["name_is_always_random"] << be_random_name
S["gender"] << gender
S["age"] << age
S["species"] << species
S["language"] << language
S["hair_red"] << r_hair
S["hair_green"] << g_hair
S["hair_blue"] << b_hair
S["facial_red"] << r_facial
S["facial_green"] << g_facial
S["facial_blue"] << b_facial
S["skin_tone"] << s_tone
S["skin_red"] << r_skin
S["skin_green"] << g_skin
S["skin_blue"] << b_skin
S["hair_style_name"] << h_style
S["facial_style_name"] << f_style
S["eyes_red"] << r_eyes
S["eyes_green"] << g_eyes
S["eyes_blue"] << b_eyes
S["underwear"] << underwear
S["undershirt"] << undershirt
S["backbag"] << backbag
S["b_type"] << b_type
S["accent"] << accent
S["voice"] << voice
S["pitch"] << pitch
S["talkspeed"] << talkspeed
//Jobs
S["alternate_option"] << alternate_option
S["job_civilian_high"] << job_civilian_high
S["job_civilian_med"] << job_civilian_med
S["job_civilian_low"] << job_civilian_low
S["job_medsci_high"] << job_medsci_high
S["job_medsci_med"] << job_medsci_med
S["job_medsci_low"] << job_medsci_low
S["job_engsec_high"] << job_engsec_high
S["job_engsec_med"] << job_engsec_med
S["job_engsec_low"] << job_engsec_low
S["job_karma_high"] << job_karma_high
S["job_karma_med"] << job_karma_med
S["job_karma_low"] << job_karma_low
//Miscellaneous
S["flavor_text"] << flavor_text
S["med_record"] << med_record
S["sec_record"] << sec_record
S["gen_record"] << gen_record
S["player_alt_titles"] << player_alt_titles
S["be_special"] << be_special
S["disabilities"] << disabilities
S["organ_data"] << organ_data
S["nanotrasen_relation"] << nanotrasen_relation
//S["skin_style"] << skin_style
return 1
*/
#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN