Merge branch 'master' into language-tab

This commit is contained in:
Timothy Teakettle
2021-03-01 20:49:16 +00:00
1890 changed files with 88328 additions and 35824 deletions
+237 -51
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 36
#define SAVEFILE_VERSION_MAX 48
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -42,7 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//if your savefile is 3 months out of date, then 'tough shit'.
/datum/preferences/proc/update_preferences(current_version, savefile/S)
if(current_version < 32) //If you remove this, remove force_reset_keybindings() too.
if(current_version < 46) //If you remove this, remove force_reset_keybindings() too.
force_reset_keybindings_direct(TRUE)
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
/datum/preferences/proc/update_character(current_version, savefile/S)
@@ -204,24 +205,104 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(S["species"] == "lizard")
features["mam_snouts"] = features["snout"]
if(current_version < 36)
if(current_version < 36) //introduction of heterochromia
left_eye_color = S["eye_color"]
right_eye_color = S["eye_color"]
if(current_version < 37) //introduction of chooseable eye types/sprites
if(S["species"] == "insect")
left_eye_color = "#000000"
right_eye_color = "#000000"
if(chosen_limb_id == "moth" || chosen_limb_id == "moth_not_greyscale") //these actually have slightly different eyes!
eye_type = "moth"
else
eye_type = "insect"
if(current_version < 38) //further eye sprite changes
if(S["species"] == "plasmaman")
left_eye_color = "#FFC90E"
right_eye_color = "#FFC90E"
else
if(S["species"] == "skeleton")
left_eye_color = "#BAB99E"
right_eye_color = "#BAB99E"
if(current_version < 43) //extreme changes to how things are coloured (the introduction of the advanced coloring system)
features["color_scheme"] = OLD_CHARACTER_COLORING //disable advanced coloring system by default
for(var/feature in features)
var/feature_value = features[feature]
if(feature_value)
var/ref_list = GLOB.mutant_reference_list[feature]
if(ref_list)
var/datum/sprite_accessory/accessory = ref_list[feature_value]
if(accessory)
var/mutant_string = accessory.mutant_part_string
if(!mutant_string)
if(istype(accessory, /datum/sprite_accessory/mam_body_markings))
mutant_string = "mam_body_markings"
var/primary_string = "[mutant_string]_primary"
var/secondary_string = "[mutant_string]_secondary"
var/tertiary_string = "[mutant_string]_tertiary"
if(accessory.color_src == MATRIXED && !accessory.matrixed_sections && feature_value != "None")
message_admins("Sprite Accessory Failure (migration from [current_version] to 39): Accessory [accessory.type] is a matrixed item without any matrixed sections set!")
continue
var/primary_exists = features[primary_string]
var/secondary_exists = features[secondary_string]
var/tertiary_exists = features[tertiary_string]
if(accessory.color_src == MATRIXED && !primary_exists && !secondary_exists && !tertiary_exists)
features[primary_string] = features["mcolor"]
features[secondary_string] = features["mcolor2"]
features[tertiary_string] = features["mcolor3"]
else if(accessory.color_src == MUTCOLORS && !primary_exists)
features[primary_string] = features["mcolor"]
else if(accessory.color_src == MUTCOLORS2 && !secondary_exists)
features[secondary_string] = features["mcolor2"]
else if(accessory.color_src == MUTCOLORS3 && !tertiary_exists)
features[tertiary_string] = features["mcolor3"]
features["color_scheme"] = OLD_CHARACTER_COLORING //advanced is off by default
if(current_version < 47) //loadout save gets changed to json
var/text_to_load
S["loadout"] >> text_to_load
var/list/saved_loadout_paths = splittext(text_to_load, "|")
//MAXIMUM_LOADOUT_SAVES save slots per loadout now
for(var/i=1, i<= MAXIMUM_LOADOUT_SAVES, i++)
loadout_data["SAVE_[i]"] = list()
for(var/some_gear_item in saved_loadout_paths)
if(!ispath(text2path(some_gear_item)))
log_game("Failed to copy item [some_gear_item] to new loadout system when migrating from version [current_version] to 40, issue: item is not a path")
continue
var/datum/gear/gear_item = text2path(some_gear_item)
if(!(initial(gear_item.loadout_flags) & LOADOUT_CAN_COLOR_POLYCHROMIC))
loadout_data["SAVE_1"] += list(list(LOADOUT_ITEM = some_gear_item)) //for the migration we put their old save into the first save slot, which is loaded by default!
else
//the same but we setup some new polychromic data (you can't get the initial value for a list so we have to do this horrible thing here)
var/datum/gear/temporary_gear_item = new gear_item
loadout_data["SAVE_1"] += list(list(LOADOUT_ITEM = some_gear_item, LOADOUT_COLOR = temporary_gear_item.loadout_initial_colors))
qdel(temporary_gear_item)
//it's double packed into a list because += will union the two lists contents
S["loadout"] = safe_json_encode(loadout_data)
if(current_version < 48) //unlockable loadout items but we need to clear bad data from a mistake
S["unlockable_loadout"] = list()
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
path = "data/player_saves/[ckey[1]]/[ckey]/[filename]"
vr_path = "data/player_saves/[ckey[1]]/[ckey]/vore"
/datum/preferences/proc/load_preferences()
/datum/preferences/proc/load_preferences(bypass_cooldown = FALSE)
if(!path)
return FALSE
if(world.time < loadprefcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your preferences a little too fast. Wait half a second, then try again.</span>")
return FALSE
loadprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!bypass_cooldown)
if(world.time < loadprefcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your preferences a little too fast. Wait half a second, then try again.</span>")
return FALSE
loadprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!fexists(path))
return FALSE
@@ -271,6 +352,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["parallax"] >> parallax
S["ambientocclusion"] >> ambientocclusion
S["auto_fit_viewport"] >> auto_fit_viewport
S["widescreenpref"] >> widescreenpref
S["pixel_size"] >> pixel_size
S["scaling_method"] >> scaling_method
S["hud_toggle_flash"] >> hud_toggle_flash
S["hud_toggle_color"] >> hud_toggle_color
S["menuoptions"] >> menuoptions
@@ -288,7 +372,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["arousable"] >> arousable
S["screenshake"] >> screenshake
S["damagescreenshake"] >> damagescreenshake
S["widescreenpref"] >> widescreenpref
S["autostand"] >> autostand
S["cit_toggles"] >> cit_toggles
S["preferred_chaos"] >> preferred_chaos
@@ -304,8 +387,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
fcopy(S, bacpath) //byond helpfully lets you use a savefile for the first arg.
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
//Sanitize
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
@@ -324,6 +405,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null)
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
pixel_size = sanitize_integer(pixel_size, PIXEL_SCALING_AUTO, PIXEL_SCALING_3X, initial(pixel_size))
scaling_method = sanitize_text(scaling_method, initial(scaling_method))
hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color))
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
@@ -337,7 +421,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
autostand = sanitize_integer(autostand, 0, 1, initial(autostand))
cit_toggles = sanitize_integer(cit_toggles, 0, 16777215, initial(cit_toggles))
auto_ooc = sanitize_integer(auto_ooc, 0, 1, initial(auto_ooc))
@@ -347,6 +430,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
verify_keybindings_valid() // one of these days this will runtime and you'll be glad that i put it in a different proc so no one gets their saves wiped
if(S["unlockable_loadout"])
unlockable_loadout_data = safe_json_decode(S["unlockable_loadout"])
else
unlockable_loadout_data = list()
if(needs_update >= 0) //save the updated version
var/old_default_slot = default_slot
var/old_max_save_slots = max_save_slots
@@ -359,11 +447,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
continue
max_save_slots = max(max_save_slots, slotnum) //so we can still update byond member slots after they lose memeber status
default_slot = slotnum
if (load_character()) // this updtates char slots
save_character()
if (load_character(null, TRUE)) // this updtates char slots
save_character(TRUE)
default_slot = old_default_slot
max_save_slots = old_max_save_slots
save_preferences()
save_preferences(TRUE)
return TRUE
@@ -385,14 +473,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!GLOB.keybindings_by_name[bindname])
modless_key_bindings -= key
/datum/preferences/proc/save_preferences()
/datum/preferences/proc/save_preferences(bypass_cooldown = FALSE)
if(!path)
return 0
if(world.time < saveprefcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to save your preferences a little too fast. Wait half a second, then try again.</span>")
return 0
saveprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!bypass_cooldown)
if(world.time < saveprefcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to save your preferences a little too fast. Wait half a second, then try again.</span>")
return 0
saveprefcooldown = world.time + PREF_SAVELOAD_COOLDOWN
var/savefile/S = new /savefile(path)
if(!S)
return 0
@@ -451,21 +540,29 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["auto_ooc"], auto_ooc)
WRITE_FILE(S["no_tetris_storage"], no_tetris_storage)
if(length(unlockable_loadout_data))
WRITE_FILE(S["unlockable_loadout"], safe_json_encode(unlockable_loadout_data))
else
WRITE_FILE(S["unlockable_loadout"], safe_json_encode(list()))
return 1
/datum/preferences/proc/load_character(slot)
/datum/preferences/proc/load_character(slot, bypass_cooldown = FALSE)
if(!path)
return FALSE
if(world.time < loadcharcooldown) //This is before the check to see if the filepath exists to ensure that BYOND can't get hung up on read attempts when the hard drive is a little slow
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your character a little too fast. Wait half a second, then try again.</span>")
return "SLOW THE FUCK DOWN" //the reason this isn't null is to make sure that people don't have their character slots overridden by random chars if they accidentally double-click a slot
loadcharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!bypass_cooldown)
if(world.time < loadcharcooldown) //This is before the check to see if the filepath exists to ensure that BYOND can't get hung up on read attempts when the hard drive is a little slow
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to load your character a little too fast. Wait half a second, then try again.</span>")
return "SLOW THE FUCK DOWN" //the reason this isn't null is to make sure that people don't have their character slots overridden by random chars if they accidentally double-click a slot
loadcharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!fexists(path))
return FALSE
var/savefile/S = new /savefile(path)
if(!S)
return FALSE
features = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF", "mcolor3" = "FFFFFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "horns_color" = "85615a", "ears" = "None", "wings" = "None", "wings_color" = "FFF", "frills" = "None", "deco_wings" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Plantigrade", "insect_wings" = "Plain", "insect_fluff" = "None", "insect_markings" = "None", "arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain", "mam_body_markings" = "Plain", "mam_ears" = "None", "mam_snouts" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", "xenodorsal" = "Standard", "xenohead" = "Standard", "xenotail" = "Xenomorph Tail", "taur" = "None", "genitals_use_skintone" = FALSE, "has_cock" = FALSE, "cock_shape" = DEF_COCK_SHAPE, "cock_length" = COCK_SIZE_DEF, "cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF, "cock_color" = "ffffff", "cock_taur" = FALSE, "has_balls" = FALSE, "balls_color" = "ffffff", "balls_shape" = DEF_BALLS_SHAPE, "balls_size" = BALLS_SIZE_DEF, "balls_cum_rate" = CUM_RATE, "balls_cum_mult" = CUM_RATE_MULT, "balls_efficiency" = CUM_EFFICIENCY, "has_breasts" = FALSE, "breasts_color" = "ffffff", "breasts_size" = BREASTS_SIZE_DEF, "breasts_shape" = DEF_BREASTS_SHAPE, "breasts_producing" = FALSE, "has_vag" = FALSE, "vag_shape" = DEF_VAGINA_SHAPE, "vag_color" = "ffffff", "has_womb" = FALSE, "balls_visibility" = GEN_VISIBLE_NO_UNDIES, "breasts_visibility"= GEN_VISIBLE_NO_UNDIES, "cock_visibility" = GEN_VISIBLE_NO_UNDIES, "vag_visibility" = GEN_VISIBLE_NO_UNDIES, "ipc_screen" = "Sunburst", "ipc_antenna" = "None", "flavor_text" = "", "silicon_flavor_text" = "", "ooc_notes" = "", "meat_type" = "Mammalian", "body_model" = MALE, "body_size" = RESIZE_DEFAULT_SIZE, "color_scheme" = OLD_CHARACTER_COLORING)
S.cd = "/"
if(!slot)
slot = default_slot
@@ -507,8 +604,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["body_model"] >> features["body_model"]
S["body_size"] >> features["body_size"]
S["age"] >> age
S["language"] >> language
S["choselanguage"] >> choselanguage
S["hair_color"] >> hair_color
S["facial_hair_color"] >> facial_hair_color
S["eye_type"] >> eye_type
S["left_eye_color"] >> left_eye_color
S["right_eye_color"] >> right_eye_color
S["use_custom_skin_tone"] >> use_custom_skin_tone
@@ -541,8 +641,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_insect_wings"] >> features["insect_wings"]
S["feature_insect_fluff"] >> features["insect_fluff"]
S["feature_insect_markings"] >> features["insect_markings"]
S["feature_arachnid_legs"] >> features["arachnid_legs"]
S["feature_arachnid_spinneret"] >> features["arachnid_spinneret"]
S["feature_arachnid_mandibles"] >> features["arachnid_mandibles"]
S["feature_horns_color"] >> features["horns_color"]
S["feature_wings_color"] >> features["wings_color"]
S["feature_color_scheme"] >> features["color_scheme"]
S["persistent_scars"] >> persistent_scars
S["scars1"] >> scars_list["1"]
S["scars2"] >> scars_list["2"]
@@ -555,6 +659,21 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
modified_limbs = safe_json_decode(limbmodstr)
else
modified_limbs = list()
var/tcgcardstr
S["tcg_cards"] >> tcgcardstr
if(length(tcgcardstr))
tcg_cards = safe_json_decode(tcgcardstr)
else
tcg_cards = list()
var/tcgdeckstr
S["tcg_decks"] >> tcgdeckstr
if(length(tcgdeckstr))
tcg_decks = safe_json_decode(tcgdeckstr)
else
tcg_decks = list()
S["chosen_limb_id"] >> chosen_limb_id
S["hide_ckey"] >> hide_ckey //saved per-character
@@ -568,6 +687,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//Jobs
S["joblessrole"] >> joblessrole
//Load prefs
S["job_preferences"] >> job_preferences
@@ -620,6 +740,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_vag_visibility"] >> features["vag_visibility"]
//womb features
S["feature_has_womb"] >> features["has_womb"]
//flavor text
//Let's make our players NOT cry desperately as we wipe their savefiles of their special snowflake texts:
if((S["flavor_text"] != "") && (S["flavor_text"] != null) && S["flavor_text"]) //If old text isn't null and isn't "" but still exists.
@@ -644,20 +765,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/list/json_from_file = json_decode(file2text(char_vr_path))
if(json_from_file)
belly_prefs = json_from_file["belly_prefs"]
//gear loadout
var/text_to_load
S["loadout"] >> text_to_load
var/list/saved_loadout_paths = splittext(text_to_load, "|")
chosen_gear = list()
gear_points = CONFIG_GET(number/initial_gear_points)
for(var/i in saved_loadout_paths)
var/datum/gear/path = text2path(i)
if(path)
var/init_cost = initial(path.cost)
if(init_cost > gear_points)
continue
chosen_gear += path
gear_points -= init_cost
if(S["loadout"])
loadout_data = safe_json_decode(S["loadout"])
else
loadout_data = list()
//try to fix any outdated data if necessary
//preference updating will handle saving the updated data for us.
@@ -693,6 +806,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age))
hair_color = sanitize_hexcolor(hair_color, 6, FALSE)
facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE)
eye_type = sanitize_inlist(eye_type, GLOB.eye_types, DEFAULT_EYES_TYPE)
left_eye_color = sanitize_hexcolor(left_eye_color, 6, FALSE)
right_eye_color = sanitize_hexcolor(right_eye_color, 6, FALSE)
@@ -724,6 +838,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
features["insect_markings"] = sanitize_inlist(features["insect_markings"], GLOB.insect_markings_list, "None")
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
features["arachnid_legs"] = sanitize_inlist(features["arachnid_legs"], GLOB.arachnid_legs_list, "Plain")
features["arachnid_spinneret"] = sanitize_inlist(features["arachnid_spinneret"], GLOB.arachnid_spinneret_list, "Plain")
features["arachnid_mandibles"] = sanitize_inlist(features["arachnid_mandibles"], GLOB.arachnid_mandibles_list, "Plain")
var/static/size_min
if(!size_min)
@@ -774,6 +891,32 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["silicon_flavor_text"] = copytext(features["silicon_flavor_text"], 1, MAX_FLAVOR_LEN)
features["ooc_notes"] = copytext(features["ooc_notes"], 1, MAX_FLAVOR_LEN)
//load every advanced coloring mode thing in one go
//THIS MUST BE DONE AFTER ALL FEATURE SAVES OR IT WILL NOT WORK
for(var/feature in features)
var/feature_value = features[feature]
if(feature_value)
var/ref_list = GLOB.mutant_reference_list[feature]
if(ref_list)
var/datum/sprite_accessory/accessory = ref_list[feature_value]
if(accessory)
var/mutant_string = accessory.mutant_part_string
if(!mutant_string)
if(istype(accessory, /datum/sprite_accessory/mam_body_markings))
mutant_string = "mam_body_markings"
var/primary_string = "[mutant_string]_primary"
var/secondary_string = "[mutant_string]_secondary"
var/tertiary_string = "[mutant_string]_tertiary"
if(accessory.color_src == MATRIXED && !accessory.matrixed_sections && feature_value != "None")
message_admins("Sprite Accessory Failure (loading data): Accessory [accessory.type] is a matrixed item without any matrixed sections set!")
continue
if(S["feature_[primary_string]"])
S["feature_[primary_string]"] >> features[primary_string]
if(S["feature_[secondary_string]"])
S["feature_[secondary_string]"] >> features[secondary_string]
if(S["feature_[tertiary_string]"])
S["feature_[tertiary_string]"] >> features[tertiary_string]
persistent_scars = sanitize_integer(persistent_scars)
scars_list["1"] = sanitize_text(scars_list["1"])
scars_list["2"] = sanitize_text(scars_list["2"])
@@ -797,14 +940,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
return 1
/datum/preferences/proc/save_character()
/datum/preferences/proc/save_character(bypass_cooldown = FALSE)
if(!path)
return 0
if(world.time < savecharcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to save your character a little too fast. Wait half a second, then try again.</span>")
return 0
savecharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
if(!bypass_cooldown)
if(world.time < savecharcooldown)
if(istype(parent))
to_chat(parent, "<span class='warning'>You're attempting to save your character a little too fast. Wait half a second, then try again.</span>")
return 0
savecharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
var/savefile/S = new /savefile(path)
if(!S)
return 0
@@ -822,8 +966,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["body_model"] , features["body_model"])
WRITE_FILE(S["body_size"] , features["body_size"])
WRITE_FILE(S["age"] , age)
WRITE_FILE(S["language"] , language)
WRITE_FILE(S["choselanguage"] , choselanguage)
WRITE_FILE(S["hair_color"] , hair_color)
WRITE_FILE(S["facial_hair_color"] , facial_hair_color)
WRITE_FILE(S["eye_type"] , eye_type)
WRITE_FILE(S["left_eye_color"] , left_eye_color)
WRITE_FILE(S["right_eye_color"] , right_eye_color)
WRITE_FILE(S["use_custom_skin_tone"] , use_custom_skin_tone)
@@ -864,6 +1011,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"])
WRITE_FILE(S["feature_insect_fluff"] , features["insect_fluff"])
WRITE_FILE(S["feature_insect_markings"] , features["insect_markings"])
WRITE_FILE(S["feature_arachnid_legs"] , features["arachnid_legs"])
WRITE_FILE(S["feature_arachnid_spinneret"] , features["arachnid_spinneret"])
WRITE_FILE(S["feature_arachnid_mandibles"] , features["arachnid_mandibles"])
WRITE_FILE(S["feature_meat"] , features["meat_type"])
WRITE_FILE(S["feature_has_cock"], features["has_cock"])
@@ -894,6 +1044,33 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["feature_ooc_notes"], features["ooc_notes"])
WRITE_FILE(S["feature_color_scheme"], features["color_scheme"])
//save every advanced coloring mode thing in one go
for(var/feature in features)
var/feature_value = features[feature]
if(feature_value)
var/ref_list = GLOB.mutant_reference_list[feature]
if(ref_list)
var/datum/sprite_accessory/accessory = ref_list[feature_value]
if(accessory)
var/mutant_string = accessory.mutant_part_string
if(!mutant_string)
if(istype(accessory, /datum/sprite_accessory/mam_body_markings))
mutant_string = "mam_body_markings"
var/primary_string = "[mutant_string]_primary"
var/secondary_string = "[mutant_string]_secondary"
var/tertiary_string = "[mutant_string]_tertiary"
if(accessory.color_src == MATRIXED && !accessory.matrixed_sections && feature_value != "None")
message_admins("Sprite Accessory Failure (saving data): Accessory [accessory.type] is a matrixed item without any matrixed sections set!")
continue
if(features[primary_string])
WRITE_FILE(S["feature_[primary_string]"], features[primary_string])
if(features[secondary_string])
WRITE_FILE(S["feature_[secondary_string]"], features[secondary_string])
if(features[tertiary_string])
WRITE_FILE(S["feature_[tertiary_string]"], features[tertiary_string])
//Custom names
for(var/custom_name_id in GLOB.preferences_custom_names)
var/savefile_slot_name = custom_name_id + "_name" //TODO remove this
@@ -931,11 +1108,20 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//gear loadout
if(chosen_gear.len)
var/text_to_save = chosen_gear.Join("|")
S["loadout"] << text_to_save
if(length(loadout_data))
S["loadout"] << safe_json_encode(loadout_data)
else
S["loadout"] << "" //empty string to reset the value
S["loadout"] << safe_json_encode(list())
if(length(tcg_cards))
S["tcg_cards"] << safe_json_encode(tcg_cards)
else
S["tcg_cards"] << safe_json_encode(list())
if(length(tcg_decks))
S["tcg_decks"] << safe_json_encode(tcg_decks)
else
S["tcg_decks"] << safe_json_encode(list())
cit_character_pref_save(S)