From 80fcaab9dc2f458097f2c15a01e350ca1a44c34e Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Sat, 21 Mar 2026 06:19:04 -0700 Subject: [PATCH] [MIRROR] Convert species, organ_data, and rlimb_data to TG (#12570) --- code/datums/components/species/xenochimera.dm | 5 +- code/game/antagonist/station/changeling.dm | 5 +- code/game/jobs/job_controller.dm | 14 +- .../machinery/virtual_reality/vr_procs.dm | 2 +- .../objects/structures/ghost_pods/event_vr.dm | 4 +- .../ghost_pods/unified_ghost_hole.dm | 2 +- code/game/sound.dm | 5 +- .../preference_setup/general/01_basic.dm | 29 ++-- .../preference_setup/general/02_language.dm | 14 +- .../preference_setup/general/03_body.dm | 140 +++++++++--------- .../preference_setup/general/12_traits.dm | 33 +++-- .../client/preference_setup/general/13_nif.dm | 2 +- .../preference_setup/loadout/02_loadout.dm | 2 +- .../preference_setup/occupation/occupation.dm | 4 +- .../preference_setup/preference_setup.dm | 14 +- .../preference_setup/preference_setup_vr.dm | 3 +- code/modules/client/preferences.dm | 19 ++- .../preferences/types/character/gender.dm | 10 +- .../preferences/types/character/names.dm | 11 +- .../preferences/types/character/organ_data.dm | 38 +++++ .../preferences/types/character/rlimb_data.dm | 42 ++++++ .../preferences/types/character/species.dm | 38 +++++ code/modules/mob/new_player/new_player.dm | 10 +- code/modules/mob/new_player/new_player_vr.dm | 10 +- .../mob/new_player/preferences_setup.dm | 6 +- code/modules/organs/organ.dm | 3 +- code/modules/organs/organ_external.dm | 6 +- code/modules/resleeving/autoresleever.dm | 7 +- code/modules/tgui/modules/late_choices.dm | 11 +- code/modules/vore/eating/inbelly_spawn.dm | 2 +- code/modules/vore/persist/persist_vr.dm | 42 +++--- vorestation.dme | 3 + 32 files changed, 343 insertions(+), 193 deletions(-) create mode 100644 code/modules/client/preferences/types/character/organ_data.dm create mode 100644 code/modules/client/preferences/types/character/rlimb_data.dm create mode 100644 code/modules/client/preferences/types/character/species.dm diff --git a/code/datums/components/species/xenochimera.dm b/code/datums/components/species/xenochimera.dm index 28691289e3..1b00fdd9f0 100644 --- a/code/datums/components/species/xenochimera.dm +++ b/code/datums/components/species/xenochimera.dm @@ -394,10 +394,11 @@ var/from_slot = "" from_slot = "You'll hatch using your current appearance" if(reload_slot == "From Slot" && client) - if(client.prefs.species == SPECIES_PROTEAN) // Exploit protection + if(client.prefs.read_preference(/datum/preference/choiced/species) == SPECIES_PROTEAN) // Exploit protection to_chat(src,span_warning("You cannot copy nanoform prosthetic limbs from this species. Please try another character.")) return - var/slot_is_synth = ((O_BRAIN in client.prefs.organ_data) && client.prefs.organ_data[O_BRAIN]) + var/list/organ_data = client.prefs.read_preference(/datum/preference/organ_data) + var/slot_is_synth = (organ_data && (O_BRAIN in organ_data) && organ_data[O_BRAIN]) if(slot_is_synth && !isSynthetic()) // Prevents some pretty weird situations to_chat(src,span_warning("Cannot apply character appearance. [slot_is_synth ? "The slot's character is synthetic." : "The slot's character is organic."] Slot must match the current body's synthetic state. Please try another character.")) return diff --git a/code/game/antagonist/station/changeling.dm b/code/game/antagonist/station/changeling.dm index d09a357dcb..c0129a2c11 100644 --- a/code/game/antagonist/station/changeling.dm +++ b/code/game/antagonist/station/changeling.dm @@ -82,10 +82,11 @@ return 1 else if(isnewplayer(player.current)) if(player.current.client && player.current.client.prefs) - var/datum/species/S = GLOB.all_species[player.current.client.prefs.species] + var/datum/species/S = GLOB.all_species[player.current.client.prefs.read_preference(/datum/preference/choiced/species)] if(S && (S.flags & (NO_SLEEVE|NO_DNA))) return 0 - if(player.current.client.prefs.organ_data[BP_TORSO] == "cyborg") // Full synthetic. // TODO, this to issynthetic()? + var/list/organ_data = player.current.client.prefs.read_preference(/datum/preference/organ_data) + if(organ_data && organ_data[BP_TORSO] == "cyborg") // Full synthetic. // TODO, this to issynthetic()? return 0 return 1 return 0 diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm index 1d42127ae7..51ff11ca51 100644 --- a/code/game/jobs/job_controller.dm +++ b/code/game/jobs/job_controller.dm @@ -50,7 +50,7 @@ GLOBAL_DATUM(job_master, /datum/controller/occupations) var/datum/job/job = GetJob(rank) if(!job) return 0 - if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]))) + if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]))) return 0 if(jobban_isbanned(player, rank)) return 0 @@ -104,7 +104,7 @@ GLOBAL_DATUM(job_master, /datum/controller/occupations) if(!job.player_old_enough(player.client)) Debug("FOC player not old enough, Player: [player]") continue - if(job.minimum_character_age && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]))) + if(job.minimum_character_age && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]))) Debug("FOC character not old enough, Player: [player]") continue //VOREStation Code Start @@ -115,7 +115,7 @@ GLOBAL_DATUM(job_master, /datum/controller/occupations) Debug("FOC is_job_whitelisted failed, Player: [player]") continue //VOREStation Code End - if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]) == TRUE) + if(job.is_species_banned(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]) == TRUE) Debug("FOC character species invalid for job, Player: [player]") continue if(flag && !(player.client.prefs.be_special & flag)) @@ -132,10 +132,10 @@ GLOBAL_DATUM(job_master, /datum/controller/occupations) if(!job) continue - if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]))) + if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]))) continue - if(job.is_species_banned(player.client.prefs.species, player.client.prefs.organ_data[O_BRAIN]) == TRUE) + if(job.is_species_banned(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]) == TRUE) continue if(istype(job, GetJob(JOB_ALT_VISITOR))) // We don't want to give him assistant, that's boring! //VOREStation Edit - Visitor not Assistant @@ -193,10 +193,10 @@ GLOBAL_DATUM(job_master, /datum/controller/occupations) if(!V.client) continue var/age = V.read_preference(/datum/preference/numeric/human/age) - if(age < job.get_min_age(V.client.prefs.species, V.client.prefs.organ_data[O_BRAIN])) // Nope. + if(age < job.get_min_age(V.client.prefs.read_preference(/datum/preference/choiced/species), V.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])) // Nope. continue - var/idealage = job.get_ideal_age(V.client.prefs.species, V.client.prefs.organ_data[O_BRAIN]) + var/idealage = job.get_ideal_age(V.client.prefs.read_preference(/datum/preference/choiced/species), V.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]) var/agediff = abs(idealage - age) // Compute the absolute difference in age from target switch(agediff) /// If the math sucks, it's because I almost failed algebra in high school. if(20 to INFINITY) diff --git a/code/game/machinery/virtual_reality/vr_procs.dm b/code/game/machinery/virtual_reality/vr_procs.dm index 9a79a4039c..501aa5cfcd 100644 --- a/code/game/machinery/virtual_reality/vr_procs.dm +++ b/code/game/machinery/virtual_reality/vr_procs.dm @@ -62,7 +62,7 @@ if(!landmark) return - var/mob/living/carbon/human/avatar = new(get_turf(landmark), client.prefs.species) + var/mob/living/carbon/human/avatar = new(get_turf(landmark), client.prefs.read_preference(/datum/preference/choiced/species)) if(!avatar) to_chat(src, "Something went wrong and spawning failed.") return diff --git a/code/game/objects/structures/ghost_pods/event_vr.dm b/code/game/objects/structures/ghost_pods/event_vr.dm index d56f41c44b..1847414a34 100644 --- a/code/game/objects/structures/ghost_pods/event_vr.dm +++ b/code/game/objects/structures/ghost_pods/event_vr.dm @@ -133,7 +133,7 @@ return //No whitelist - if(!is_alien_whitelisted(user.client, GLOB.all_species[user.client.prefs.species])) + if(!is_alien_whitelisted(user.client, GLOB.all_species[user.client.prefs.read_preference(/datum/preference/choiced/species)])) to_chat(user, span_warning("You cannot use this spawnpoint to spawn as a species you are not whitelisted for!")) return @@ -211,7 +211,7 @@ return //No whitelist - if(!is_alien_whitelisted(user.client, GLOB.all_species[user.client.prefs.species])) + if(!is_alien_whitelisted(user.client, GLOB.all_species[user.client.prefs.read_preference(/datum/preference/choiced/species)])) to_chat(user, span_warning("You cannot use this spawnpoint to spawn as a species you are not whitelisted for!")) return diff --git a/code/game/objects/structures/ghost_pods/unified_ghost_hole.dm b/code/game/objects/structures/ghost_pods/unified_ghost_hole.dm index 8e160fcffc..17024555cd 100644 --- a/code/game/objects/structures/ghost_pods/unified_ghost_hole.dm +++ b/code/game/objects/structures/ghost_pods/unified_ghost_hole.dm @@ -39,7 +39,7 @@ if("Morph") create_morph(user) if("Lurker") - if(!is_alien_whitelisted(user.client, GLOB.all_species[user.client.prefs.species])) + if(!is_alien_whitelisted(user.client, GLOB.all_species[user.client.prefs.read_preference(/datum/preference/choiced/species)])) to_chat(user, span_warning("You cannot use this spawnpoint to spawn as a species you are not whitelisted for!")) return create_lurker(user) diff --git a/code/game/sound.dm b/code/game/sound.dm index 5e5bf9643c..7951a6726c 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -416,9 +416,10 @@ GLOBAL_LIST_INIT(species_sound_map, list( */ /proc/select_default_species_sound(var/datum/preferences/pref) // Called in character setup. This is similar to check_gendered_sounds, except here we pull from the prefs. // First, we determine if we're custom-choosing a body or if we're a base game species. - var/datum/species/valid = GLOB.all_species[pref.species] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) + var/datum/species/valid = GLOB.all_species[pref_species] if(valid.selects_bodytype == (SELECTS_BODYTYPE_CUSTOM || SELECTS_BODYTYPE_SHAPESHIFTER)) // Custom species or xenochimera handling here - valid = coalesce(GLOB.all_species[pref.custom_base], GLOB.all_species[pref.species]) + valid = coalesce(GLOB.all_species[pref.custom_base], GLOB.all_species[pref_species]) // Now we start getting our sounds. var/id_gender = pref.read_preference(/datum/preference/choiced/gender/identifying) if(valid.gender_specific_species_sounds) // Do we have gender-specific sounds? diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index b5ff2f03d7..491ca9030a 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -31,11 +31,12 @@ var/char_real_name = pref.read_preference(/datum/preference/name/real_name) var/char_bio_gender = pref.read_preference(/datum/preference/choiced/gender/biological) var/char_id_gender = pref.read_preference(/datum/preference/choiced/gender/identifying) + var/pref_species = pref.read_preference(/datum/preference/choiced/species) // Re-sanitize name on join. // Fixes being able to swap from FBP to organic before round join to be organic with numbers in name. - char_real_name = sanitize_name(char_real_name, pref.species, is_FBP()) + char_real_name = sanitize_name(char_real_name, pref_species, is_FBP()) if(!char_real_name) - char_real_name = random_name(char_id_gender, pref.species) + char_real_name = random_name(char_id_gender, pref_species) if(CONFIG_GET(flag/humans_need_surnames)) var/firstspace = findtext(char_real_name, " ") var/name_length = length(char_real_name) @@ -91,10 +92,12 @@ var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin(pref.client_ckey) if(mannequin) species = mannequin.species - else if(pref.species) - species = GLOB.all_species[pref.species] else - species = GLOB.all_species[SPECIES_HUMAN] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) + if(pref_species) + species = GLOB.all_species[pref_species] + else + species = GLOB.all_species[SPECIES_HUMAN] var/list/species_stats = list( "total_health" = species.total_health, @@ -193,9 +196,10 @@ switch(action) if("rename") var/current_name = pref.read_preference(/datum/preference/name/real_name) + var/pref_species = pref.read_preference(/datum/preference/choiced/species) var/raw_name = tgui_input_text(user, "Choose your character's name:", "Character Name", current_name, encode = FALSE) if(!isnull(raw_name)) - var/new_name = sanitize_name(raw_name, pref.species, is_FBP()) + var/new_name = sanitize_name(raw_name, pref_species, is_FBP()) if(new_name) pref.update_preference_by_type(/datum/preference/name/real_name, new_name) return TOPIC_REFRESH @@ -204,7 +208,7 @@ return TOPIC_NOACTION if("random_name") - pref.update_preference_by_type(/datum/preference/name/real_name, random_name(pref.read_preference(/datum/preference/choiced/gender/identifying), pref.species)) + pref.update_preference_by_type(/datum/preference/name/real_name, random_name(pref.read_preference(/datum/preference/choiced/gender/identifying), pref.read_preference(/datum/preference/choiced/species))) return TOPIC_REFRESH if("always_random_name") @@ -213,9 +217,10 @@ if("nickname") var/current_nickname = pref.read_preference(/datum/preference/name/nickname) + var/pref_species = pref.read_preference(/datum/preference/choiced/species) var/raw_nickname = tgui_input_text(user, "Choose your character's nickname:", "Character Nickname", current_nickname, encode = FALSE) if(!isnull(raw_nickname)) - var/new_nickname = sanitize_name(raw_nickname, pref.species, is_FBP()) + var/new_nickname = sanitize_name(raw_nickname, pref_species, is_FBP()) if(new_nickname) pref.update_preference_by_type(/datum/preference/name/nickname, new_nickname) return TOPIC_REFRESH @@ -376,12 +381,14 @@ /datum/category_item/player_setup_item/general/basic/proc/get_genders() var/datum/species/S - if(pref.species) - S = GLOB.all_species[pref.species] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) + if(pref_species) + S = GLOB.all_species[pref_species] else S = GLOB.all_species[SPECIES_HUMAN] var/list/possible_genders = S.genders - if(!pref.organ_data || pref.organ_data[BP_TORSO] != "cyborg") + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + if(!organ_data || organ_data[BP_TORSO] != "cyborg") return possible_genders possible_genders = possible_genders.Copy() possible_genders |= NEUTER diff --git a/code/modules/client/preference_setup/general/02_language.dm b/code/modules/client/preference_setup/general/02_language.dm index d3a898266a..45dafdf5b5 100644 --- a/code/modules/client/preference_setup/general/02_language.dm +++ b/code/modules/client/preference_setup/general/02_language.dm @@ -12,7 +12,6 @@ pref.alternate_languages = check_list_copy(save_data["language"]) pref.extra_languages = save_data["extra_languages"] pref.language_prefixes = save_data["language_prefixes"] - pref.species = save_data["species"] pref.preferred_language = save_data["preflang"] pref.language_custom_keys = check_list_copy(save_data["language_custom_keys"]) pref.runechat_color = save_data["runechat_color"] @@ -32,10 +31,11 @@ if(!islist(pref.alternate_languages)) testing("LANGSANI: Sanitizing languages on [pref.client]'s character [char_name] because their character has no languages list") pref.alternate_languages = list() - if(pref.species) - var/datum/species/S = GLOB.all_species[pref.species] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) + if(pref_species) + var/datum/species/S = GLOB.all_species[pref_species] if(!istype(S)) - testing("LANGSANI: Failed sani on [pref.client]'s character [char_name] because their species ([pref.species]) isn't in the global list") + testing("LANGSANI: Failed sani on [pref.client]'s character [char_name] because their species ([pref_species]) isn't in the global list") return if(pref.alternate_languages.len > (S.num_alternate_languages + pref.extra_languages)) @@ -62,7 +62,7 @@ pref.language_prefixes -= prefix if(isnull(pref.language_custom_keys)) pref.language_custom_keys = list() - var/datum/species/S = GLOB.all_species[pref.species] + var/datum/species/S = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] for(var/key in pref.language_custom_keys) if(!pref.language_custom_keys[key]) pref.language_custom_keys.Remove(key) @@ -76,7 +76,7 @@ var/list/languages_list = list() - var/datum/species/S = GLOB.all_species[pref.species] + var/datum/species/S = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] if(S.language) UNTYPED_LIST_ADD(languages_list, list( "name" = S.language, @@ -108,7 +108,7 @@ return var/mob/user = ui.user - var/datum/species/S = GLOB.all_species[pref.species] + var/datum/species/S = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] switch(action) if("remove_language") diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index 2e063513a1..e70c1d38b3 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -50,6 +50,7 @@ /datum/preferences/proc/get_available_styles(var/style_list) . = list("Normal" = null) + var/pref_species = read_preference(/datum/preference/choiced/species) for(var/path in style_list) var/datum/sprite_accessory/instance = style_list[path] if(!istype(instance)) @@ -58,7 +59,7 @@ continue if(instance.ckeys_allowed && (!client || !(client.ckey in instance.ckeys_allowed))) continue - if(instance.species_allowed && (!species || !(species in instance.species_allowed)) && (!client || !check_rights_for(client, R_ADMIN | R_EVENT | R_FUN)) && (!custom_base || !(custom_base in instance.species_allowed))) + if(instance.species_allowed && (!pref_species || !(pref_species in instance.species_allowed)) && (!client || !check_rights_for(client, R_ADMIN | R_EVENT | R_FUN)) && (!custom_base || !(custom_base in instance.species_allowed))) continue if(!instance.can_be_selected && (!client || !check_rights_for(client, R_HOLDER))) continue @@ -79,14 +80,11 @@ sort_order = 3 /datum/category_item/player_setup_item/general/body/load_character(list/save_data) - pref.species = save_data["species"] pref.s_tone = save_data["skin_tone"] pref.h_style = save_data["hair_style_name"] pref.f_style = save_data["facial_style_name"] pref.grad_style = save_data["grad_style_name"] pref.b_type = save_data["b_type"] - pref.organ_data = check_list_copy(save_data["organ_data"]) - pref.rlimb_data = check_list_copy(save_data["rlimb_data"]) pref.body_markings = check_list_copy(save_data["body_markings"]) for(var/i in pref.body_markings) pref.body_markings[i] = check_list_copy(pref.body_markings[i]) @@ -103,14 +101,11 @@ pref.digitigrade = save_data["digitigrade"] /datum/category_item/player_setup_item/general/body/save_character(list/save_data) - save_data["species"] = pref.species save_data["skin_tone"] = pref.s_tone save_data["hair_style_name"] = pref.h_style save_data["facial_style_name"] = pref.f_style save_data["grad_style_name"] = pref.grad_style save_data["b_type"] = pref.b_type - save_data["organ_data"] = check_list_copy(pref.organ_data) - save_data["rlimb_data"] = check_list_copy(pref.rlimb_data) var/list/body_markings = check_list_copy(pref.body_markings) for(var/i in pref.body_markings) body_markings[i] = check_list_copy(body_markings[i]) @@ -128,28 +123,18 @@ save_data["digitigrade"] = pref.digitigrade /datum/category_item/player_setup_item/general/body/sanitize_character() - if(!pref.species || !(pref.species in GLOB.playable_species)) - pref.species = SPECIES_HUMAN pref.s_tone = sanitize_integer(pref.s_tone, -185, 34, initial(pref.s_tone)) pref.h_style = sanitize_inlist(pref.h_style, GLOB.hair_styles_list, initial(pref.h_style)) pref.f_style = sanitize_inlist(pref.f_style, GLOB.facial_hair_styles_list, initial(pref.f_style)) pref.grad_style = sanitize_inlist(pref.grad_style, GLOB.hair_gradients, initial(pref.grad_style)) pref.b_type = sanitize_text(pref.b_type, initial(pref.b_type)) - if(!pref.organ_data) pref.organ_data = list() - if(!pref.rlimb_data || !islist(pref.rlimb_data)) pref.rlimb_data = list() if(!pref.body_markings) pref.body_markings = list() else pref.body_markings &= GLOB.body_marking_styles_list for (var/M in pref.body_markings) if (!islist(pref.body_markings[M])) var/col = istext(pref.body_markings[M]) ? pref.body_markings[M] : "#000000" pref.body_markings[M] = pref.mass_edit_marking_list(M,color=col) - for(var/limb in pref.rlimb_data) - var/key = pref.rlimb_data[limb] - if(!istext(key)) - pref.rlimb_data -= limb - if(!LAZYACCESS(GLOB.all_robolimbs, key)) - pref.rlimb_data -= limb if(!pref.bgstate || !(pref.bgstate in pref.bgstate_options)) pref.bgstate = "000" @@ -198,7 +183,9 @@ character.set_gender(pref.read_preference(/datum/preference/choiced/gender/biological)) - character.synthetic = pref.species == "Protean" ? GLOB.all_robolimbs["protean"] : null //Clear the existing var. (unless protean, then switch it to the normal protean limb) + character.synthetic = pref.read_preference(/datum/preference/choiced/species) == "Protean" ? GLOB.all_robolimbs["protean"] : null //Clear the existing var. (unless protean, then switch it to the normal protean limb) + var/list/pref_organ_data = pref.read_preference(/datum/preference/organ_data) + var/list/pref_rlimb_data = pref.read_preference(/datum/preference/rlimb_data) var/list/organs_to_edit = list() for (var/name in list(BP_TORSO, BP_HEAD, BP_GROIN, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) var/obj/item/organ/external/O = character.organs_by_name[name] @@ -209,19 +196,19 @@ else organs_to_edit.Insert(x+(O.robotic == ORGAN_NANOFORM ? 1 : 0), name) for(var/name in organs_to_edit) - var/status = pref.organ_data[name] + var/status = pref_organ_data[name] var/obj/item/organ/external/O = character.organs_by_name[name] if(O) if(status == "amputated") O.remove_rejuv() else if(status == "cyborg") - if(pref.rlimb_data[name]) - O.robotize(pref.rlimb_data[name]) + if(pref_rlimb_data[name]) + O.robotize(pref_rlimb_data[name]) else O.robotize() for(var/name in list(O_HEART,O_EYES,O_VOICE,O_LUNGS,O_LIVER,O_KIDNEYS,O_SPLEEN,O_STOMACH,O_INTESTINE,O_BRAIN)) - var/status = pref.organ_data[name] + var/status = pref_organ_data[name] if(!status) continue var/obj/item/organ/I = character.internal_organs_by_name[name] @@ -256,31 +243,26 @@ return mob_species && (mob_species.appearance_flags & flag) /datum/category_item/player_setup_item/general/body/proc/reset_limbs() - for(var/organ in pref.organ_data) - pref.organ_data[organ] = null - while(null in pref.organ_data) - pref.organ_data -= null - - for(var/organ in pref.rlimb_data) - pref.rlimb_data[organ] = null - while(null in pref.rlimb_data) - pref.rlimb_data -= null + // Reset organ and robolimb data + pref.write_preference(GLOB.preference_entries[/datum/preference/organ_data], list()) + pref.write_preference(GLOB.preference_entries[/datum/preference/rlimb_data], list()) // Sanitize the name so that there aren't any numbers sticking around. // Is this still necessary with TG conversation? + var/pref_species = pref.read_preference(/datum/preference/choiced/species) var/current_name = pref.read_preference(/datum/preference/name/real_name) - current_name = sanitize_name(current_name, pref.species) + current_name = sanitize_name(current_name, pref_species) if(!current_name) - current_name = random_name(pref.read_preference(/datum/preference/choiced/gender/identifying), pref.species) + current_name = random_name(pref.read_preference(/datum/preference/choiced/gender/identifying), pref_species) pref.update_preference_by_type(/datum/preference/name/real_name, current_name) /datum/category_item/player_setup_item/general/body/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) var/list/data = ..() - data["species"] = pref.species - data["organ_data"] = pref.organ_data - data["rlimb_data"] = pref.rlimb_data + data["species"] = pref.read_preference(/datum/preference/choiced/species) + data["organ_data"] = pref.read_preference(/datum/preference/organ_data) + data["rlimb_data"] = pref.read_preference(/datum/preference/rlimb_data) data["s_tone"] = -pref.s_tone + 35 data["eyes_color"] = pref.read_preference(/datum/preference/color/human/eyes_color) @@ -495,7 +477,7 @@ if(.) return - var/datum/species/mob_species = GLOB.all_species[pref.species] + var/datum/species/mob_species = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] var/mob/user = ui.user switch(action) @@ -753,9 +735,9 @@ if(((!(setting_species.spawn_flags & SPECIES_CAN_JOIN)) || (!is_alien_whitelisted(user.client,setting_species))) && !check_rights(R_ADMIN|R_EVENT, 0) && !(setting_species.spawn_flags & SPECIES_WHITELIST_SELECTABLE)) return TOPIC_NOACTION - var/prev_species = pref.species - pref.species = params["species"] - if(prev_species != pref.species) + var/prev_species = pref.read_preference(/datum/preference/choiced/species) + pref.update_preference_by_type(/datum/preference/choiced/species, params["species"]) + if(prev_species != pref.read_preference(/datum/preference/choiced/species)) if(!(pref.read_preference(/datum/preference/choiced/gender/biological) in mob_species.genders)) pref.set_biological_gender(mob_species.genders[1]) pref.custom_species = null @@ -879,27 +861,35 @@ switch(new_state) if("Normal") - pref.organ_data[limb] = null - pref.rlimb_data[limb] = null + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + var/list/rlimb_data = pref.read_preference(/datum/preference/rlimb_data) + organ_data[limb] = null + rlimb_data[limb] = null if(limb == BP_TORSO) // depends on standardization for(var/other_limb in BP_ALL - BP_TORSO) - pref.organ_data[other_limb] = null - pref.rlimb_data[other_limb] = null + organ_data[other_limb] = null + rlimb_data[other_limb] = null for(var/internal in O_STANDARD) - pref.organ_data[internal] = null - pref.rlimb_data[internal] = null + organ_data[internal] = null + rlimb_data[internal] = null if(third_limb) - pref.organ_data[third_limb] = null - pref.rlimb_data[third_limb] = null + organ_data[third_limb] = null + rlimb_data[third_limb] = null + pref.write_preference(GLOB.preference_entries[/datum/preference/organ_data], organ_data) + pref.write_preference(GLOB.preference_entries[/datum/preference/rlimb_data], rlimb_data) if("Amputated") if(limb == BP_TORSO) // depends on standardization return - pref.organ_data[limb] = "amputated" - pref.rlimb_data[limb] = null + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + var/list/rlimb_data = pref.read_preference(/datum/preference/rlimb_data) + organ_data[limb] = "amputated" + rlimb_data[limb] = null if(second_limb) - pref.organ_data[second_limb] = "amputated" - pref.rlimb_data[second_limb] = null + organ_data[second_limb] = "amputated" + rlimb_data[second_limb] = null + pref.write_preference(GLOB.preference_entries[/datum/preference/organ_data], organ_data) + pref.write_preference(GLOB.preference_entries[/datum/preference/rlimb_data], rlimb_data) if("Prosthesis") var/list/usable_manufacturers = list() @@ -907,7 +897,7 @@ var/datum/robolimb/M = GLOB.chargen_robolimbs[company] if(!(limb in M.parts)) continue - if(pref.species in M.species_cannot_use) + if(pref.read_preference(/datum/preference/choiced/species) in M.species_cannot_use) continue if(M.whitelisted_to && !(user.ckey in M.whitelisted_to)) continue @@ -918,25 +908,29 @@ if(!choice) return - pref.rlimb_data[limb] = choice - pref.organ_data[limb] = "cyborg" + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + var/list/rlimb_data = pref.read_preference(/datum/preference/rlimb_data) + rlimb_data[limb] = choice + organ_data[limb] = "cyborg" if(second_limb) - pref.rlimb_data[second_limb] = choice - pref.organ_data[second_limb] = "cyborg" - if(third_limb && pref.organ_data[third_limb] == "amputated") - pref.organ_data[third_limb] = null + rlimb_data[second_limb] = choice + organ_data[second_limb] = "cyborg" + if(third_limb && organ_data[third_limb] == "amputated") + organ_data[third_limb] = null if(limb == BP_TORSO) for(var/other_limb in BP_ALL - BP_TORSO) - if(pref.organ_data[other_limb]) + if(organ_data[other_limb]) continue - pref.organ_data[other_limb] = "cyborg" - pref.rlimb_data[other_limb] = choice - if(!pref.organ_data[O_BRAIN]) - pref.organ_data[O_BRAIN] = FBP_ASSISTED + organ_data[other_limb] = "cyborg" + rlimb_data[other_limb] = choice + if(!organ_data[O_BRAIN]) + organ_data[O_BRAIN] = FBP_ASSISTED for(var/internal_organ in list(O_HEART,O_EYES)) - pref.organ_data[internal_organ] = FBP_MECHANICAL + organ_data[internal_organ] = FBP_MECHANICAL + pref.write_preference(GLOB.preference_entries[/datum/preference/organ_data], organ_data) + pref.write_preference(GLOB.preference_entries[/datum/preference/rlimb_data], rlimb_data) return TOPIC_REFRESH_UPDATE_PREVIEW @@ -945,7 +939,8 @@ if(!(zone in O_STANDARD)) return - if(zone == O_BRAIN && pref.organ_data[BP_HEAD] != "cyborg") + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + if(zone == O_BRAIN && organ_data[BP_HEAD] != "cyborg") to_chat(user, span_warning("You may only select a cybernetic or synthetic brain if you have a full prosthetic body.")) return @@ -971,17 +966,18 @@ switch(new_state) if("Normal") - pref.organ_data[zone] = null + organ_data[zone] = null if("Assisted") - pref.organ_data[zone] = FBP_ASSISTED + organ_data[zone] = FBP_ASSISTED if("Cybernetic") - pref.organ_data[zone] = FBP_ASSISTED + organ_data[zone] = FBP_ASSISTED if("Mechanical") - pref.organ_data[zone] = FBP_MECHANICAL + organ_data[zone] = FBP_MECHANICAL if("Drone") - pref.organ_data[zone] = FBP_DIGITAL + organ_data[zone] = FBP_DIGITAL if("Positronic") - pref.organ_data[zone] = FBP_MECHANICAL + organ_data[zone] = FBP_MECHANICAL + pref.write_preference(GLOB.preference_entries[/datum/preference/organ_data], organ_data) return TOPIC_REFRESH_UPDATE_PREVIEW diff --git a/code/modules/client/preference_setup/general/12_traits.dm b/code/modules/client/preference_setup/general/12_traits.dm index b7e952a170..6db74d4310 100644 --- a/code/modules/client/preference_setup/general/12_traits.dm +++ b/code/modules/client/preference_setup/general/12_traits.dm @@ -18,7 +18,7 @@ /datum/preferences/proc/get_custom_bases_for_species(var/new_species) if (!new_species) - new_species = species + new_species = read_preference(/datum/preference/choiced/species) var/list/choices var/datum/species/spec = GLOB.all_species[new_species] if (spec.selects_bodytype == SELECTS_BODYTYPE_SHAPESHIFTER) @@ -108,14 +108,15 @@ pref.blood_reagents = sanitize_text(pref.blood_reagents, initial(pref.blood_reagents)) if(!pref.traits_cheating) - var/datum/species/S = GLOB.all_species[pref.species] + var/datum/species/S = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] if(S) pref.starting_trait_points = S.trait_points else pref.starting_trait_points = 0 pref.max_traits = MAX_SPECIES_TRAITS - if(pref.organ_data[O_BRAIN]) //Checking if we have a synth on our hands, boys. + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + if(organ_data && organ_data[O_BRAIN]) //Checking if we have a synth on our hands, boys. pref.dirty_synth = 1 pref.gross_meatbag = 0 else @@ -123,11 +124,12 @@ pref.dirty_synth = 0 // Clean up positive traits + var/pref_species = pref.read_preference(/datum/preference/choiced/species) for(var/datum/trait/path as anything in pref.pos_traits) if(!(path in GLOB.positive_traits)) pref.pos_traits -= path continue - if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_positive)) + if(!(pref_species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_positive)) pref.pos_traits -= path continue var/take_flags = initial(path.can_take) @@ -139,7 +141,7 @@ log_world("removing [path] for not being in neutral_traits") pref.neu_traits -= path continue - if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_neutral)) + if(!(pref_species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_neutral)) log_world("removing [path] for not being a custom species") pref.neu_traits -= path continue @@ -152,14 +154,14 @@ if(!(path in GLOB.negative_traits)) pref.neg_traits -= path continue - if(!(pref.species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_negative)) + if(!(pref_species == SPECIES_CUSTOM) && !(path in GLOB.everyone_traits_negative)) pref.neg_traits -= path continue var/take_flags = initial(path.can_take) if((pref.dirty_synth && !(take_flags & SYNTHETICS)) || (pref.gross_meatbag && !(take_flags & ORGANICS))) pref.neg_traits -= path - var/datum/species/selected_species = GLOB.all_species[pref.species] + var/datum/species/selected_species = GLOB.all_species[pref_species] if(selected_species.selects_bodytype) if (!(pref.custom_base in pref.get_custom_bases_for_species())) pref.custom_base = selected_species.default_custom_base @@ -193,7 +195,7 @@ new_S.species_sounds = species_sounds_to_copy // Now we send our sounds over to the mob - if(pref.species == SPECIES_CUSTOM) + if(pref.read_preference(/datum/preference/choiced/species) == SPECIES_CUSTOM) //Statistics for this would be nice var/english_traits = english_list(new_S.traits, and_text = ";", comma_text = ";") log_game("TRAITS [pref.client_ckey]/([character]) with: [english_traits]") //Terrible 'fake' key_name()... but they aren't in the same entity yet @@ -201,7 +203,7 @@ /datum/category_item/player_setup_item/general/traits/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state) var/list/data = ..() - var/datum/species/selected_species = GLOB.all_species[pref.species] + var/datum/species/selected_species = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] data["selects_bodytype"] = selected_species.selects_bodytype data["custom_base"] = pref.custom_base data["blood_color"] = pref.blood_color @@ -252,7 +254,7 @@ pref.blood_color = sanitize_hexcolor(color_choice, default="#A10808") return TOPIC_REFRESH if("blood_reset") - var/datum/species/spec = GLOB.all_species[pref.species] + var/datum/species/spec = GLOB.all_species[pref.read_preference(/datum/preference/choiced/species)] var/new_blood = spec.blood_color ? spec.blood_color : "#A10808" var/choice = tgui_alert(user, "Reset blood color to species default ([new_blood])?","Reset Blood Color",list("Reset","Cancel")) if(choice == "Reset") @@ -295,23 +297,24 @@ var/mode = text2num(params["add_trait"]) var/list/picklist var/list/mylist + var/pref_species_for_traits = pref.read_preference(/datum/preference/choiced/species) switch(mode) if(POSITIVE_MODE) - if(pref.species == SPECIES_CUSTOM) + if(pref_species_for_traits == SPECIES_CUSTOM) picklist = GLOB.positive_traits.Copy() - pref.pos_traits mylist = pref.pos_traits else picklist = GLOB.everyone_traits_positive.Copy() - pref.pos_traits mylist = pref.pos_traits if(NEUTRAL_MODE) - if(pref.species == SPECIES_CUSTOM) + if(pref_species_for_traits == SPECIES_CUSTOM) picklist = GLOB.neutral_traits.Copy() - pref.neu_traits mylist = pref.neu_traits else picklist = GLOB.everyone_traits_neutral.Copy() - pref.neu_traits mylist = pref.neu_traits if(NEGATIVE_MODE) - if(pref.species == SPECIES_CUSTOM) + if(pref_species_for_traits == SPECIES_CUSTOM) picklist = GLOB.negative_traits.Copy() - pref.neg_traits mylist = pref.neg_traits else @@ -375,11 +378,11 @@ tgui_alert_async(user, "The trait you've selected can only be taken by synthetic characters!", "Error") return TOPIC_REFRESH - if(pref.species in instance.banned_species) + if(pref_species_for_traits in instance.banned_species) tgui_alert_async(user, "The trait you've selected cannot be taken by the species you've chosen!", "Error") return TOPIC_REFRESH - if( LAZYLEN(instance.allowed_species) && !(pref.species in instance.allowed_species)) + if( LAZYLEN(instance.allowed_species) && !(pref_species_for_traits in instance.allowed_species)) tgui_alert_async(user, "The trait you've selected cannot be taken by the species you've chosen!", "Error") return TOPIC_REFRESH diff --git a/code/modules/client/preference_setup/general/13_nif.dm b/code/modules/client/preference_setup/general/13_nif.dm index 91f59dfbc1..d4ed4d4442 100644 --- a/code/modules/client/preference_setup/general/13_nif.dm +++ b/code/modules/client/preference_setup/general/13_nif.dm @@ -42,7 +42,7 @@ pref.nif_path = null //Kill! WARNING("Loaded a NIF but it was an invalid path, [char_name]") - if (ispath(pref.nif_path, /obj/item/nif/protean) && pref.species != SPECIES_PROTEAN) //no free nifs + if (ispath(pref.nif_path, /obj/item/nif/protean) && pref.read_preference(/datum/preference/choiced/species) != SPECIES_PROTEAN) //no free nifs pref.nif_path = null if(ispath(pref.nif_path) && isnull(pref.nif_durability)) //How'd you lose this? diff --git a/code/modules/client/preference_setup/loadout/02_loadout.dm b/code/modules/client/preference_setup/loadout/02_loadout.dm index f6b151bda0..b9d86167e5 100644 --- a/code/modules/client/preference_setup/loadout/02_loadout.dm +++ b/code/modules/client/preference_setup/loadout/02_loadout.dm @@ -66,7 +66,7 @@ GLOBAL_LIST_EMPTY_TYPED(gear_datums, /datum/gear) /datum/category_item/player_setup_item/loadout/loadout/proc/is_valid_gear(datum/gear/G, max_cost) if(G.whitelisted && CONFIG_GET(flag/loadout_whitelist) != LOADOUT_WHITELIST_OFF && pref.client) - if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_STRICT && (G.whitelisted != pref.species && G.whitelisted != pref.custom_base)) + if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_STRICT && (G.whitelisted != pref.read_preference(/datum/preference/choiced/species) && G.whitelisted != pref.custom_base)) return FALSE if(CONFIG_GET(flag/loadout_whitelist) == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(pref.client, GLOB.all_species[G.whitelisted])) return FALSE diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index ad262064dc..27d384c2cd 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -113,14 +113,14 @@ "denylist_whitelist" = !is_job_whitelisted(user, job.title), // tigercat2000 - these shouldn't exist >:( "denylist_character_age" = FALSE, - "min_age" = job.get_min_age(pref.species, pref.organ_data[O_BRAIN]), + "min_age" = job.get_min_age(pref.read_preference(/datum/preference/choiced/species), pref.read_preference(/datum/preference/organ_data)?[O_BRAIN]), "special_color" = "", "selected" = 0, "selected_title" = "", "alt_titles" = list(), ) - if((job.minimum_character_age || job.min_age_by_species) && user.client && (user.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(user.client.prefs.species, user.client.prefs.organ_data[O_BRAIN]))) + if((job.minimum_character_age || job.min_age_by_species) && user.client && (user.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(user.client.prefs.read_preference(/datum/preference/choiced/species), user.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]))) job_data["denylist_character_age"] = TRUE if((pref.job_civilian_low & ASSISTANT) && job.type != /datum/job/assistant) diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 8839988f65..a59d10949a 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -233,7 +233,8 @@ // Checks in a really hacky way if a character's preferences say they are an FBP or not. /datum/category_item/player_setup_item/proc/is_FBP() - if(pref.organ_data && pref.organ_data[BP_TORSO] != "cyborg") + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + if(organ_data && organ_data[BP_TORSO] != "cyborg") return 0 return 1 @@ -241,8 +242,9 @@ /datum/category_item/player_setup_item/proc/get_FBP_type() if(!is_FBP()) return 0 // Not a robot. - if(O_BRAIN in pref.organ_data) - switch(pref.organ_data[O_BRAIN]) + var/list/organ_data = pref.read_preference(/datum/preference/organ_data) + if(organ_data && (O_BRAIN in organ_data)) + switch(organ_data[O_BRAIN]) if(FBP_ASSISTED) return PREF_FBP_CYBORG if(FBP_MECHANICAL) @@ -252,7 +254,8 @@ return 0 //Something went wrong! /datum/category_item/player_setup_item/proc/get_min_age() - var/datum/species/S = GLOB.all_species[pref.species ? pref.species : "Human"] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) || "Human" + var/datum/species/S = GLOB.all_species[pref_species] if(!is_FBP()) return S.min_age // If they're not a robot, we can just use the species var. var/FBP_type = get_FBP_type() @@ -266,7 +269,8 @@ return S.min_age // welp /datum/category_item/player_setup_item/proc/get_max_age() - var/datum/species/S = GLOB.all_species[pref.species ? pref.species : "Human"] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) || "Human" + var/datum/species/S = GLOB.all_species[pref_species] if(!is_FBP()) return S.max_age // If they're not a robot, we can just use the species var. var/FBP_type = get_FBP_type() diff --git a/code/modules/client/preference_setup/preference_setup_vr.dm b/code/modules/client/preference_setup/preference_setup_vr.dm index 2379875910..cd92790e68 100644 --- a/code/modules/client/preference_setup/preference_setup_vr.dm +++ b/code/modules/client/preference_setup/preference_setup_vr.dm @@ -1,7 +1,8 @@ //Minimum limit is 18 /datum/category_item/player_setup_item/get_min_age() var/min_age = 18 - var/datum/species/S = GLOB.all_species[pref.species ? pref.species : "Human"] + var/pref_species = pref.read_preference(/datum/preference/choiced/species) || "Human" + var/datum/species/S = GLOB.all_species[pref_species] if(!is_FBP() && S.min_age > 18) min_age = S.min_age return min_age diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ffd3da87b7..b1ced744cd 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -31,7 +31,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/grad_style = "none" //Gradient style var/f_style = "Shaved" //Face hair type var/s_tone = -75 //Skin tone - 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 @@ -87,8 +86,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) // 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 JOB_MEDICAL_DOCTOR var/list/body_markings = list() // "name" = "#rgbcolor" //VOREStation Edit: "name" = list(BP_HEAD = list("on" = , "color" = "#rgbcolor"), BP_TORSO = ...) @@ -159,7 +156,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) // Didn't load a character, so let's randomize set_biological_gender(pick(MALE, FEMALE)) - update_preference_by_type(/datum/preference/name/real_name, random_name(read_preference(/datum/preference/choiced/gender/identifying), species)) + update_preference_by_type(/datum/preference/name/real_name, random_name(read_preference(/datum/preference/choiced/gender/identifying), read_preference(/datum/preference/choiced/species))) b_type = RANDOM_BLOOD_TYPE if(client) @@ -298,10 +295,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) player_setup.sanitize_setup() // This needs to happen before anything else becuase it sets some variables. - character.set_species(species) + character.set_species(read_preference(/datum/preference/choiced/species)) // Special Case: This references variables owned by two different datums, so do it here. if(read_preference(/datum/preference/toggle/human/name_is_always_random)) - update_preference_by_type(/datum/preference/name/real_name, random_name(read_preference(/datum/preference/choiced/gender/identifying), species)) + update_preference_by_type(/datum/preference/name/real_name, random_name(read_preference(/datum/preference/choiced/gender/identifying), read_preference(/datum/preference/choiced/species))) // Ask the preferences datums to apply their own settings to the new mob player_setup.copy_to_mob(character) @@ -515,6 +512,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) // Destroy/cyborgize organs and limbs. if (convert_to_prosthetics) //should only really be run for proteans + var/list/pref_organ_data = read_preference(/datum/preference/organ_data) + var/list/pref_rlimb_data = read_preference(/datum/preference/rlimb_data) var/list/organs_to_edit = list() for (var/name in list(BP_TORSO, BP_HEAD, BP_GROIN, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND, BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)) var/obj/item/organ/external/O = character.organs_by_name[name] @@ -525,16 +524,16 @@ GLOBAL_LIST_EMPTY(preferences_datums) else organs_to_edit.Insert(x+(O.robotic == ORGAN_NANOFORM ? 1 : 0), name) for(var/name in organs_to_edit) - var/status = organ_data[name] + var/status = pref_organ_data[name] var/obj/item/organ/external/O = character.organs_by_name[name] if(O) if(status == "amputated") continue else if(status == "cyborg") - O.robotize(rlimb_data[name]) + O.robotize(pref_rlimb_data[name]) else var/bodytype - var/datum/species/selected_species = GLOB.all_species[species] + var/datum/species/selected_species = GLOB.all_species[read_preference(/datum/preference/choiced/species)] if(selected_species.selects_bodytype && custom_base) //Everyone technically has custom_base set to HUMAN, but only some species actually select it. bodytype = custom_base else @@ -621,7 +620,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.species?.blood_color = blood_color - var/datum/species/selected_species = GLOB.all_species[species] + var/datum/species/selected_species = GLOB.all_species[read_preference(/datum/preference/choiced/species)] var/bodytype_selected if(selected_species.selects_bodytype && custom_base) bodytype_selected = custom_base diff --git a/code/modules/client/preferences/types/character/gender.dm b/code/modules/client/preferences/types/character/gender.dm index 42d2657335..aefb026c30 100644 --- a/code/modules/client/preferences/types/character/gender.dm +++ b/code/modules/client/preferences/types/character/gender.dm @@ -11,15 +11,17 @@ /// FBP check /datum/preference/choiced/gender/proc/is_fbp(datum/preferences/preferences) - if(!preferences?.organ_data) + var/list/organ_data = preferences?.read_preference(/datum/preference/organ_data) + if(!organ_data) return FALSE - return preferences.organ_data[BP_TORSO] == "cyborg" + return organ_data[BP_TORSO] == "cyborg" /// Get the list of valid bio genders for the species /datum/preference/choiced/gender/proc/get_valid_biological_genders(datum/preferences/preferences) var/datum/species/S - if(preferences?.species) - S = GLOB.all_species[preferences.species] + var/species_name = preferences?.read_preference(/datum/preference/choiced/species) + if(species_name) + S = GLOB.all_species[species_name] if(!S) S = GLOB.all_species[SPECIES_HUMAN] var/list/possible_genders = S.genders diff --git a/code/modules/client/preferences/types/character/names.dm b/code/modules/client/preferences/types/character/names.dm index 5093917849..b3faeb49ed 100644 --- a/code/modules/client/preferences/types/character/names.dm +++ b/code/modules/client/preferences/types/character/names.dm @@ -11,9 +11,10 @@ /// Check if the character is a Full Body Prosthetic (allows numbers in name) /datum/preference/name/proc/is_fbp(datum/preferences/preferences) - if(!preferences?.organ_data) + var/list/organ_data = preferences?.read_preference(/datum/preference/organ_data) + if(!organ_data) return FALSE - return preferences.organ_data[BP_TORSO] == "cyborg" + return organ_data[BP_TORSO] == "cyborg" /datum/preference/name/is_valid(value) if(!istext(value)) @@ -26,8 +27,8 @@ if(!istext(input)) return create_default_value() var/species = default_species - if(preferences?.species) - species = preferences.species + if(preferences) + species = preferences.read_preference(/datum/preference/choiced/species) var/allow_numbers = is_fbp(preferences) var/sanitized = sanitize_name(input, species, allow_numbers) if(!sanitized) @@ -63,7 +64,7 @@ /datum/preference/name/real_name/create_informed_default_value(datum/preferences/preferences) var/gender = preferences?.read_preference(/datum/preference/choiced/gender/identifying) || MALE - var/species = preferences?.species || SPECIES_HUMAN + var/species = preferences?.read_preference(/datum/preference/choiced/species) || SPECIES_HUMAN return random_name(gender, species) /datum/preference/name/real_name/create_random_value(datum/preferences/preferences, datum/species/current_species) diff --git a/code/modules/client/preferences/types/character/organ_data.dm b/code/modules/client/preferences/types/character/organ_data.dm new file mode 100644 index 0000000000..7654bb10e9 --- /dev/null +++ b/code/modules/client/preferences/types/character/organ_data.dm @@ -0,0 +1,38 @@ +// Organ data preference for character creation +// Stores an assoc list mapping organ tags to their prosthetic/modified status. +// Values can be: null (normal), "cyborg", "amputated", FBP_ASSISTED, FBP_MECHANICAL, or FBP_DIGITAL. + +/datum/preference/organ_data + savefile_key = "organ_data" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + can_randomize = FALSE + +/datum/preference/organ_data/create_default_value() + return list() + +/datum/preference/organ_data/pref_deserialize(input, datum/preferences/preferences) + if(!islist(input)) + return list() + // Return the list directly (same reference) so in-place mutations update the cache. + return input + +/datum/preference/organ_data/pref_serialize(input) + if(!islist(input)) + return list() + return check_list_copy(input) + +/datum/preference/organ_data/is_valid(value) + return islist(value) + +/datum/preference/organ_data/apply_to_human(mob/living/carbon/human/target, value) + return // Organ application is handled by copy_to_mob in 03_body.dm + +/datum/preference/organ_data/apply_to_living(mob/living/target, value) + return + +/datum/preference/organ_data/apply_to_silicon(mob/living/silicon/target, value) + return + +/datum/preference/organ_data/apply_to_animal(mob/living/simple_mob/target, value) + return diff --git a/code/modules/client/preferences/types/character/rlimb_data.dm b/code/modules/client/preferences/types/character/rlimb_data.dm new file mode 100644 index 0000000000..9713c31eda --- /dev/null +++ b/code/modules/client/preferences/types/character/rlimb_data.dm @@ -0,0 +1,42 @@ +// Robolimb data preference for character creation +// Stores an assoc list mapping organ tags to robolimb manufacturer model names. +// Values are strings corresponding to keys in GLOB.all_robolimbs. + +/datum/preference/rlimb_data + savefile_key = "rlimb_data" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + can_randomize = FALSE + +/datum/preference/rlimb_data/create_default_value() + return list() + +/datum/preference/rlimb_data/pref_deserialize(input, datum/preferences/preferences) + if(!islist(input)) + return list() + // Sanitize: remove entries with invalid robolimb keys + for(var/limb in input) + var/key = input[limb] + if(!istext(key) || !LAZYACCESS(GLOB.all_robolimbs, key)) + input -= limb + return input + +/datum/preference/rlimb_data/pref_serialize(input) + if(!islist(input)) + return list() + return check_list_copy(input) + +/datum/preference/rlimb_data/is_valid(value) + return islist(value) + +/datum/preference/rlimb_data/apply_to_human(mob/living/carbon/human/target, value) + return // Robolimb application is handled by copy_to_mob in 03_body.dm + +/datum/preference/rlimb_data/apply_to_living(mob/living/target, value) + return + +/datum/preference/rlimb_data/apply_to_silicon(mob/living/silicon/target, value) + return + +/datum/preference/rlimb_data/apply_to_animal(mob/living/simple_mob/target, value) + return diff --git a/code/modules/client/preferences/types/character/species.dm b/code/modules/client/preferences/types/character/species.dm new file mode 100644 index 0000000000..b640e0258d --- /dev/null +++ b/code/modules/client/preferences/types/character/species.dm @@ -0,0 +1,38 @@ +// Species preference for character creation +// Handles the player's selected species, validated against GLOB.playable_species. + +/datum/preference/choiced/species + savefile_key = "species" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_MANUALLY_RENDERED + can_randomize = FALSE + priority = PREFERENCE_PRIORITY_SPECIES + +/datum/preference/choiced/species/init_possible_values() + // GLOB.playable_species is populated at world init and contains all joinable species names. + return GLOB.playable_species + +/datum/preference/choiced/species/create_default_value() + return SPECIES_HUMAN + +/datum/preference/choiced/species/pref_deserialize(input, datum/preferences/preferences) + if(!input || !istext(input) || !(input in GLOB.playable_species)) + return SPECIES_HUMAN + return input + +/datum/preference/choiced/species/is_valid(value) + if(!istext(value)) + return FALSE + return value in GLOB.playable_species + +/datum/preference/choiced/species/apply_to_human(mob/living/carbon/human/target, value) + return // Species application is handled by copy_to via character.set_species() + +/datum/preference/choiced/species/apply_to_living(mob/living/target, value) + return + +/datum/preference/choiced/species/apply_to_silicon(mob/living/silicon/target, value) + return + +/datum/preference/choiced/species/apply_to_animal(mob/living/simple_mob/target, value) + return diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 3ba389558b..9dab90569e 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -392,8 +392,9 @@ var/use_species_name var/datum/species/chosen_species - if(client.prefs.species) - chosen_species = GLOB.all_species[client.prefs.species] + var/pref_species = client.prefs.read_preference(/datum/preference/choiced/species) + if(pref_species) + chosen_species = GLOB.all_species[pref_species] use_species_name = chosen_species.get_station_variant() //Only used by pariahs atm. if(chosen_species && use_species_name) @@ -475,8 +476,9 @@ /mob/new_player/get_species() var/datum/species/chosen_species - if(client.prefs.species) - chosen_species = GLOB.all_species[client.prefs.species] + var/pref_species = client.prefs.read_preference(/datum/preference/choiced/species) + if(pref_species) + chosen_species = GLOB.all_species[pref_species] if(!chosen_species) return SPECIES_HUMAN diff --git a/code/modules/mob/new_player/new_player_vr.dm b/code/modules/mob/new_player/new_player_vr.dm index f104d3e512..f1e62683f6 100644 --- a/code/modules/mob/new_player/new_player_vr.dm +++ b/code/modules/mob/new_player/new_player_vr.dm @@ -27,18 +27,18 @@ to_chat(src,span_warning("You have not set your scale yet. Do this on the VORE tab in character setup.")) //Can they play? - if(!is_alien_whitelisted(src.client,GLOB.all_species[client?.prefs?.species]) && !check_rights(R_ADMIN, 0)) + if(!is_alien_whitelisted(src.client,GLOB.all_species[client?.prefs?.read_preference(/datum/preference/choiced/species)]) && !check_rights(R_ADMIN, 0)) pass = FALSE to_chat(src,span_warning("You are not allowed to spawn in as this species.")) //CHOMPEdit Begin - Check species job bans... (Only used for shadekin) - if(J.is_species_banned(client?.prefs?.species, client?.prefs?.organ_data["brain"])) + if(J.is_species_banned(client?.prefs?.read_preference(/datum/preference/choiced/species), client?.prefs?.read_preference(/datum/preference/organ_data)?[O_BRAIN])) pass = FALSE to_chat(src,span_warning("Your species is not permitted to take this role or job.")) //CHOMPEdit End //Custom species checks - if (client?.prefs?.species == "Custom Species") + if (client?.prefs?.read_preference(/datum/preference/choiced/species) == SPECIES_CUSTOM) //Didn't name it if(!client?.prefs?.custom_species) @@ -82,10 +82,10 @@ if(client?.prefs?.neu_traits) for(var/T in client.prefs.neu_traits) var/datum/trait/instance = GLOB.all_traits[T] - if(client.prefs.species in instance.banned_species) + if(client.prefs.read_preference(/datum/preference/choiced/species)) pass = FALSE to_chat(src,span_warning("One of your traits, [instance.name], is not available for your species! Please fix this conflict and then try again.")) - else if(LAZYLEN(instance.allowed_species) && !(client.prefs.species in instance.allowed_species)) //We use else if here, so as to prevent getting two errors for one trait. + else if(LAZYLEN(instance.allowed_species) && !(client.prefs.read_preference(/datum/preference/choiced/species) in instance.allowed_species)) //We use else if here, so as to prevent getting two errors for one trait. pass = FALSE to_chat(src,span_warning("One of your traits, [instance.name], is not available for your species! Please fix this conflict and then try again.")) //CHOMP Addition End diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index c79f477bfe..a7888bb798 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -276,11 +276,12 @@ /datum/preferences/proc/get_valid_hairstyles(mob/user) var/list/valid_hairstyles = list() + var/pref_species = read_preference(/datum/preference/choiced/species) for(var/hairstyle in GLOB.hair_styles_list) var/datum/sprite_accessory/S = GLOB.hair_styles_list[hairstyle] if(S.name == DEVELOPER_WARNING_NAME) continue - if(!(species in S.species_allowed) && (!custom_base || !(custom_base in S.species_allowed))) + if(!(pref_species in S.species_allowed) && (!custom_base || !(custom_base in S.species_allowed))) continue if(!S.can_be_selected && (!client || !check_rights_for(client, R_HOLDER))) continue @@ -293,6 +294,7 @@ /datum/preferences/proc/get_valid_facialhairstyles() var/list/valid_facialhairstyles = list() var/bio_gender = read_preference(/datum/preference/choiced/gender/biological) + var/pref_species = read_preference(/datum/preference/choiced/species) for(var/facialhairstyle in GLOB.facial_hair_styles_list) var/datum/sprite_accessory/S = GLOB.facial_hair_styles_list[facialhairstyle] if(S.name == DEVELOPER_WARNING_NAME) @@ -301,7 +303,7 @@ continue if(bio_gender == FEMALE && S.gender == MALE) continue - if(!(species in S.species_allowed) && (!custom_base || !(custom_base in S.species_allowed))) + if(!(pref_species in S.species_allowed) && (!custom_base || !(custom_base in S.species_allowed))) continue if(!S.can_be_selected && (!client || !check_rights_for(client, R_HOLDER))) continue diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 0683a18a2c..ef7e8e7422 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -332,7 +332,8 @@ if(owner) handle_organ_mod_special() if(!ignore_prosthetic_prefs && owner && owner.client && owner.client.prefs && owner.client.prefs.read_preference(/datum/preference/name/real_name) == owner.real_name) - var/status = owner.client.prefs.organ_data[organ_tag] + var/list/organ_data = owner.client.prefs.read_preference(/datum/preference/organ_data) + var/status = organ_data?[organ_tag] if(status == FBP_ASSISTED) mechassist() else if(status == FBP_MECHANICAL) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index db3536e240..97f8ac26f7 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -667,11 +667,13 @@ This function completely restores a damaged organ to perfect condition. if(owner && !ignore_prosthetic_prefs) if(owner.client && owner.client.prefs && owner.client.prefs.read_preference(/datum/preference/name/real_name) == owner.real_name) - var/status = owner.client.prefs.organ_data[organ_tag] + var/list/organ_data = owner.client.prefs.read_preference(/datum/preference/organ_data) + var/status = organ_data?[organ_tag] if(status == "amputated") remove_rejuv() else if(status == "cyborg") - var/robodata = owner.client.prefs.rlimb_data[organ_tag] + var/list/rlimb_data = owner.client.prefs.read_preference(/datum/preference/rlimb_data) + var/robodata = rlimb_data?[organ_tag] if(robodata) robotize(robodata) else diff --git a/code/modules/resleeving/autoresleever.dm b/code/modules/resleeving/autoresleever.dm index 2632142dfd..3b4755d335 100644 --- a/code/modules/resleeving/autoresleever.dm +++ b/code/modules/resleeving/autoresleever.dm @@ -85,15 +85,16 @@ GLOBAL_LIST_EMPTY(active_autoresleevers) var/client/ghost_client = ghost.client - if(!is_alien_whitelisted(ghost.client, GLOB.all_species[ghost_client?.prefs?.species]) && !check_rights(R_ADMIN, 0)) // Prevents a ghost ghosting in on a slot and spawning via a resleever with race they're not whitelisted for, getting around normal join restrictions. + if(!is_alien_whitelisted(ghost.client, GLOB.all_species[ghost_client?.prefs?.read_preference(/datum/preference/choiced/species)]) && !check_rights(R_ADMIN, 0)) // Prevents a ghost ghosting in on a slot and spawning via a resleever with race they're not whitelisted for, getting around normal join restrictions. to_chat(ghost, span_warning("You are not whitelisted to spawn as this species!")) return // CHOMPedit start var/datum/species/chosen_species - if(ghost.client.prefs.species) // In case we somehow don't have a species set here. - chosen_species = GLOB.all_species[ghost_client.prefs.species] + var/pref_species = ghost.client.prefs.read_preference(/datum/preference/choiced/species) + if(pref_species) // In case we somehow don't have a species set here. + chosen_species = GLOB.all_species[pref_species] if((chosen_species.spawn_flags & SPECIES_IS_WHITELISTED) || (chosen_species.spawn_flags & SPECIES_IS_RESTRICTED)) to_chat(ghost, span_warning("This species cannot be resleeved!")) diff --git a/code/modules/tgui/modules/late_choices.dm b/code/modules/tgui/modules/late_choices.dm index c2f2b18d06..4216aab432 100644 --- a/code/modules/tgui/modules/late_choices.dm +++ b/code/modules/tgui/modules/late_choices.dm @@ -49,7 +49,7 @@ if(!job.minimum_character_age && !job.min_age_by_species) return TRUE - var/min_age = job.get_min_age(prefs.species, prefs.organ_data[O_BRAIN]) + var/min_age = job.get_min_age(prefs.read_preference(/datum/preference/choiced/species), prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN]) if(prefs.read_preference(/datum/preference/numeric/human/age) >= min_age) return TRUE return FALSE @@ -81,7 +81,7 @@ continue //CHOMPEdit Begin - Check species job bans... (Only used for shadekin) - if(job.is_species_banned(user.client.prefs.species, user.client.prefs.organ_data["brain"])) + if(job.is_species_banned(user.client.prefs.read_preference(/datum/preference/choiced/species), user.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])) continue //CHOMPEdit End @@ -130,13 +130,14 @@ to_chat(new_user, span_danger("The station is currently exploding. Joining would go poorly.")) return - var/datum/species/S = GLOB.all_species[new_user.client.prefs.species] + var/pref_species = new_user.client.prefs.read_preference(/datum/preference/choiced/species) + var/datum/species/S = GLOB.all_species[pref_species] if(!is_alien_whitelisted(new_user.client, S)) - tgui_alert(new_user, "You are currently not whitelisted to play [new_user.client.prefs.species].") + tgui_alert(new_user, "You are currently not whitelisted to play [pref_species].") return 0 if(!(S.spawn_flags & SPECIES_CAN_JOIN)) - tgui_alert_async(new_user,"Your current species, [new_user.client.prefs.species], is not available for play on the station.") + tgui_alert_async(new_user,"Your current species, [pref_species], is not available for play on the station.") return 0 new_user.AttemptLateSpawn(job) diff --git a/code/modules/vore/eating/inbelly_spawn.dm b/code/modules/vore/eating/inbelly_spawn.dm index 4e5151e424..ce8af1c702 100644 --- a/code/modules/vore/eating/inbelly_spawn.dm +++ b/code/modules/vore/eating/inbelly_spawn.dm @@ -55,7 +55,7 @@ if(confirmation_prey == "Yes" && potential_prey && src && belly_choice) //Now we finally spawn them in! - if(!is_alien_whitelisted(potential_prey, GLOB.all_species[potential_prey.prefs.species])) + if(!is_alien_whitelisted(potential_prey, GLOB.all_species[potential_prey.prefs.read_preference(/datum/preference/choiced/species)])) to_chat(potential_prey, span_notice("You are not whitelisted to play as currently selected character.")) to_chat(src, span_notice("Prey accepted the confirmation, but something went wrong with spawning their character.")) return diff --git a/code/modules/vore/persist/persist_vr.dm b/code/modules/vore/persist/persist_vr.dm index 0a3c815ad1..0992e3a9e1 100644 --- a/code/modules/vore/persist/persist_vr.dm +++ b/code/modules/vore/persist/persist_vr.dm @@ -166,35 +166,39 @@ // This basically needs to be the reverse of /datum/category_item/player_setup_item/general/body/copy_to_mob() ~Leshana /proc/apply_organs_to_prefs(var/mob/living/carbon/human/character, var/datum/preferences/prefs) if(!istype(character) || !character.species) return + var/list/organ_data = prefs.read_preference(/datum/preference/organ_data) || list() + var/list/rlimb_data = prefs.read_preference(/datum/preference/rlimb_data) || list() // Checkify the limbs! for(var/name in character.species.has_limbs) - var/obj/item/organ/external/O = character.organs_by_name[name] - if(!O) + var/obj/item/organ/external/external_organ = character.organs_by_name[name] + if(!external_organ) if(name in GLOB.storable_amputated_organs) - prefs.organ_data[name] = "amputated" + organ_data[name] = "amputated" else - prefs.rlimb_data.Remove(name) // Missing limb and not in the global list means default model - else if(O.robotic >= ORGAN_ROBOT) - prefs.organ_data[name] = "cyborg" - if(O.model) - prefs.rlimb_data[name] = O.model + rlimb_data.Remove(name) // Missing limb and not in the global list means default model + else if(external_organ.robotic >= ORGAN_ROBOT) + organ_data[name] = "cyborg" + if(external_organ.model) + rlimb_data[name] = external_organ.model else - prefs.rlimb_data.Remove(name) // Missing rlimb_data entry means default model + rlimb_data.Remove(name) // Missing rlimb_data entry means default model else - prefs.organ_data.Remove(name) // Misisng organ_data entry means normal + organ_data.Remove(name) // Misisng organ_data entry means normal // Internal organs also for(var/name in character.species.has_organ) - var/obj/item/organ/I = character.internal_organs_by_name[name] - if(I) - if(istype(I, /obj/item/organ/internal/mmi_holder/robot)) - prefs.organ_data[name] = FBP_DIGITAL // Need a better way to detect this special type - else if(I.robotic == ORGAN_ASSISTED) - prefs.organ_data[name] = FBP_ASSISTED - else if(I.robotic >= ORGAN_ROBOT) - prefs.organ_data[name] = FBP_MECHANICAL + var/obj/item/organ/internal_organ = character.internal_organs_by_name[name] + if(internal_organ) + if(istype(internal_organ, /obj/item/organ/internal/mmi_holder/robot)) + organ_data[name] = FBP_DIGITAL // Need a better way to detect this special type + else if(internal_organ.robotic == ORGAN_ASSISTED) + organ_data[name] = FBP_ASSISTED + else if(internal_organ.robotic >= ORGAN_ROBOT) + organ_data[name] = FBP_MECHANICAL else - prefs.organ_data.Remove(name) // Missing organ_data entry means normal + organ_data.Remove(name) // Missing organ_data entry means normal + prefs.write_preference(GLOB.preference_entries[/datum/preference/organ_data], organ_data) + prefs.write_preference(GLOB.preference_entries[/datum/preference/rlimb_data], rlimb_data) // Saves mob's current body markings state to prefs. // This basically needs to be the reverse of /datum/category_item/player_setup_item/general/body/copy_to_mob() ~Leshana diff --git a/vorestation.dme b/vorestation.dme index b0ed55e318..aa729af5a8 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -2580,6 +2580,9 @@ #include "code\modules\client\preferences\migrations\19_paifile.dm" #include "code\modules\client\preferences\types\character\gender.dm" #include "code\modules\client\preferences\types\character\names.dm" +#include "code\modules\client\preferences\types\character\organ_data.dm" +#include "code\modules\client\preferences\types\character\rlimb_data.dm" +#include "code\modules\client\preferences\types\character\species.dm" #include "code\modules\client\preferences\types\character\antagonism\01_basic.dm" #include "code\modules\client\preferences\types\character\general\01_basic.dm" #include "code\modules\client\preferences\types\character\general\03_body.dm"