mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-13 16:13:49 +01:00
Conversion of realname and nickname from bay (#19120)
* Automatic changelog compile [ci skip] * replace all bay instances for realname and nickname with tg * add comments where uncertain of sanitisation needed * Fix issue from git conflict.. * Fix issue causing setup menu not opening * Attempt to clean up how name datums are handled * Remove redundant check * Fix number issues with character names --------- Co-authored-by: vorestation-ci[bot] <199609141+vorestation-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -18,16 +18,12 @@
|
||||
sort_order = 1
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/load_character(list/save_data)
|
||||
pref.real_name = save_data["real_name"]
|
||||
pref.nickname = save_data["nickname"]
|
||||
pref.biological_gender = save_data["gender"]
|
||||
pref.identifying_gender = save_data["id_gender"]
|
||||
pref.vore_egg_type = save_data["vore_egg_type"]
|
||||
pref.autohiss = save_data["autohiss"]
|
||||
|
||||
/datum/category_item/player_setup_item/general/basic/save_character(list/save_data)
|
||||
save_data["real_name"] = pref.real_name
|
||||
save_data["nickname"] = pref.nickname
|
||||
save_data["gender"] = pref.biological_gender
|
||||
save_data["id_gender"] = pref.identifying_gender
|
||||
save_data["vore_egg_type"] = pref.vore_egg_type
|
||||
@@ -36,29 +32,31 @@
|
||||
/datum/category_item/player_setup_item/general/basic/sanitize_character()
|
||||
pref.biological_gender = sanitize_inlist(pref.biological_gender, get_genders(), pick(get_genders()))
|
||||
pref.identifying_gender = (pref.identifying_gender in all_genders_define_list) ? pref.identifying_gender : pref.biological_gender
|
||||
pref.real_name = sanitize_name(pref.real_name, pref.species, is_FBP())
|
||||
if(!pref.real_name)
|
||||
pref.real_name = random_name(pref.identifying_gender, pref.species)
|
||||
pref.nickname = sanitize_name(pref.nickname)
|
||||
pref.vore_egg_type = sanitize_inlist(pref.vore_egg_type, GLOB.global_vore_egg_types, initial(pref.vore_egg_type))
|
||||
pref.autohiss = sanitize_inlist(pref.autohiss, list("Off", "Basic", "Full"), initial(pref.autohiss))
|
||||
|
||||
// Moved from /datum/preferences/proc/copy_to()
|
||||
/datum/category_item/player_setup_item/general/basic/copy_to_mob(var/mob/living/carbon/human/character)
|
||||
var/char_real_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
// 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())
|
||||
if(!char_real_name)
|
||||
char_real_name = random_name(pref.identifying_gender, pref.species)
|
||||
if(CONFIG_GET(flag/humans_need_surnames))
|
||||
var/firstspace = findtext(pref.real_name, " ")
|
||||
var/name_length = length(pref.real_name)
|
||||
var/firstspace = findtext(char_real_name, " ")
|
||||
var/name_length = length(char_real_name)
|
||||
if(!firstspace) //we need a surname
|
||||
pref.real_name += " [pick(GLOB.last_names)]"
|
||||
char_real_name += " [pick(GLOB.last_names)]"
|
||||
else if(firstspace == name_length)
|
||||
pref.real_name += "[pick(GLOB.last_names)]"
|
||||
char_real_name += "[pick(GLOB.last_names)]"
|
||||
|
||||
character.real_name = pref.real_name
|
||||
character.real_name = char_real_name
|
||||
character.name = character.real_name
|
||||
if(character.dna)
|
||||
character.dna.real_name = character.real_name
|
||||
|
||||
character.nickname = pref.nickname
|
||||
character.nickname = pref.read_preference(/datum/preference/name/nickname)
|
||||
|
||||
character.gender = pref.biological_gender
|
||||
character.identifying_gender = pref.identifying_gender
|
||||
@@ -80,9 +78,9 @@
|
||||
/datum/category_item/player_setup_item/general/basic/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
data["real_name"] = pref.real_name
|
||||
data["real_name"] = pref.read_preference(/datum/preference/name/real_name)
|
||||
data["be_random_name"] = pref.read_preference(/datum/preference/toggle/human/name_is_always_random)
|
||||
data["nickname"] = pref.nickname
|
||||
data["nickname"] = pref.read_preference(/datum/preference/name/nickname)
|
||||
data["biological_sex"] = gender2text(pref.biological_gender)
|
||||
data["identifying_gender"] = gender2text(pref.identifying_gender)
|
||||
data["age"] = pref.read_preference(/datum/preference/numeric/human/age)
|
||||
@@ -201,18 +199,19 @@
|
||||
|
||||
switch(action)
|
||||
if("rename")
|
||||
var/raw_name = tgui_input_text(user, "Choose your character's name:", "Character Name", pref.real_name, encode = FALSE)
|
||||
var/current_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
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())
|
||||
if(new_name)
|
||||
pref.real_name = new_name
|
||||
pref.update_preference_by_type(/datum/preference/name/real_name, new_name)
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
to_chat(user, span_warning("Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if("random_name")
|
||||
pref.real_name = random_name(pref.identifying_gender, pref.species)
|
||||
pref.update_preference_by_type(/datum/preference/name/real_name, random_name(pref.identifying_gender, pref.species))
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("always_random_name")
|
||||
@@ -220,11 +219,12 @@
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("nickname")
|
||||
var/raw_nickname = tgui_input_text(user, "Choose your character's nickname:", "Character Nickname", pref.nickname, encode = FALSE)
|
||||
var/current_nickname = pref.read_preference(/datum/preference/name/nickname)
|
||||
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())
|
||||
if(new_nickname)
|
||||
pref.nickname = new_nickname
|
||||
pref.update_preference_by_type(/datum/preference/name/nickname, new_nickname)
|
||||
return TOPIC_REFRESH
|
||||
else
|
||||
to_chat(user, span_warning("Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and ."))
|
||||
@@ -233,7 +233,7 @@
|
||||
if("reset_nickname")
|
||||
var/nick_choice = tgui_alert(user, "Wipe your Nickname? This will completely remove any chosen nickname(s).","Wipe Nickname",list("Yes","No"))
|
||||
if(nick_choice == "Yes")
|
||||
pref.nickname = null
|
||||
pref.update_preference_by_type(/datum/preference/name/nickname, null)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if("bio_gender")
|
||||
|
||||
@@ -26,17 +26,18 @@
|
||||
save_data["runechat_color"] = pref.runechat_color
|
||||
|
||||
/datum/category_item/player_setup_item/general/language/sanitize_character()
|
||||
var/char_name = pref.read_preference(/datum/preference/name/real_name) || "-name not yet loaded-"
|
||||
if(!islist(pref.alternate_languages))
|
||||
testing("LANGSANI: Sanitizing languages on [pref.client]'s character [pref.real_name || "-name not yet loaded-"] because their character has no languages list")
|
||||
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]
|
||||
if(!istype(S))
|
||||
testing("LANGSANI: Failed sani on [pref.client]'s character [pref.real_name || "-name not yet loaded-"] 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))
|
||||
testing("LANGSANI: Truncated [pref.client]'s character [pref.real_name || "-name not yet loaded-"] language list because it was too long (len: [pref.alternate_languages.len], allowed: [S.num_alternate_languages])")
|
||||
testing("LANGSANI: Truncated [pref.client]'s character [char_name] language list because it was too long (len: [pref.alternate_languages.len], allowed: [S.num_alternate_languages])")
|
||||
pref.alternate_languages.len = (S.num_alternate_languages + pref.extra_languages) // Truncate to allowed length
|
||||
|
||||
// VOREStation Edit Start
|
||||
@@ -48,7 +49,7 @@
|
||||
for(var/language in pref.alternate_languages)
|
||||
var/datum/language/L = GLOB.all_languages[language]
|
||||
if(!istype(L) || (L.flags & RESTRICTED) || (!(language in S.secondary_langs) && pref.client && !is_lang_whitelisted(pref.client, L)))
|
||||
testing("LANGSANI: Removed [L?.name || "lang not found"] from [pref.client]'s character [pref.real_name || "-name not yet loaded-"] because it failed allowed checks")
|
||||
testing("LANGSANI: Removed [L?.name || "lang not found"] from [pref.client]'s character [char_name] because it failed allowed checks")
|
||||
pref.alternate_languages -= language
|
||||
|
||||
if(isnull(pref.language_prefixes) || !pref.language_prefixes.len)
|
||||
|
||||
@@ -267,9 +267,12 @@
|
||||
pref.rlimb_data -= null
|
||||
|
||||
// Sanitize the name so that there aren't any numbers sticking around.
|
||||
pref.real_name = sanitize_name(pref.real_name, pref.species)
|
||||
if(!pref.real_name)
|
||||
pref.real_name = random_name(pref.identifying_gender, pref.species)
|
||||
// Is this still necessary with TG conversation?
|
||||
var/current_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
current_name = sanitize_name(current_name, pref.species)
|
||||
if(!current_name)
|
||||
current_name = random_name(pref.identifying_gender, 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 = ..()
|
||||
|
||||
@@ -252,22 +252,26 @@
|
||||
pref.vantag_preference = names_list[selection]
|
||||
return TOPIC_REFRESH
|
||||
if("custom_say")
|
||||
var/say_choice = tgui_input_text(user, "This word or phrase will appear instead of 'says': [pref.real_name] says, \"Hi.\"", "Custom Say", pref.custom_say, 12)
|
||||
var/char_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
var/say_choice = tgui_input_text(user, "This word or phrase will appear instead of 'says': [char_name] says, \"Hi.\"", "Custom Say", pref.custom_say, 12)
|
||||
if(say_choice)
|
||||
pref.custom_say = say_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_whisper")
|
||||
var/whisper_choice = tgui_input_text(user, "This word or phrase will appear instead of 'whispers': [pref.real_name] whispers, \"Hi...\"", "Custom Whisper", pref.custom_whisper, 12)
|
||||
var/char_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
var/whisper_choice = tgui_input_text(user, "This word or phrase will appear instead of 'whispers': [char_name] whispers, \"Hi...\"", "Custom Whisper", pref.custom_whisper, 12)
|
||||
if(whisper_choice)
|
||||
pref.custom_whisper = whisper_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_ask")
|
||||
var/ask_choice = tgui_input_text(user, "This word or phrase will appear instead of 'asks': [pref.real_name] asks, \"Hi?\"", "Custom Ask", pref.custom_ask, 12)
|
||||
var/char_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
var/ask_choice = tgui_input_text(user, "This word or phrase will appear instead of 'asks': [char_name] asks, \"Hi?\"", "Custom Ask", pref.custom_ask, 12)
|
||||
if(ask_choice)
|
||||
pref.custom_ask = ask_choice
|
||||
return TOPIC_REFRESH
|
||||
if("custom_exclaim")
|
||||
var/exclaim_choice = tgui_input_text(user, "This word or phrase will appear instead of 'exclaims', 'shouts' or 'yells': [pref.real_name] exclaims, \"Hi!\"", "Custom Exclaim", pref.custom_exclaim, 12)
|
||||
var/char_name = pref.read_preference(/datum/preference/name/real_name)
|
||||
var/exclaim_choice = tgui_input_text(user, "This word or phrase will appear instead of 'exclaims', 'shouts' or 'yells': [char_name] exclaims, \"Hi!\"", "Custom Exclaim", pref.custom_exclaim, 12)
|
||||
if(exclaim_choice)
|
||||
pref.custom_exclaim = exclaim_choice
|
||||
return TOPIC_REFRESH
|
||||
|
||||
@@ -35,18 +35,19 @@
|
||||
savefile.save()
|
||||
|
||||
/datum/category_item/player_setup_item/general/nif/sanitize_character()
|
||||
var/char_name = pref.read_preference(/datum/preference/name/real_name) || "-name not yet loaded-"
|
||||
if(pref.nif_path && !ispath(pref.nif_path)) //We have at least a text string that should be a path.
|
||||
pref.nif_path = text2path(pref.nif_path) //Try to convert it to a hard path.
|
||||
if(!pref.nif_path) //If we couldn't, kill it.
|
||||
pref.nif_path = null //Kill!
|
||||
WARNING("Loaded a NIF but it was an invalid path, [pref.real_name]")
|
||||
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
|
||||
pref.nif_path = null
|
||||
|
||||
if(ispath(pref.nif_path) && isnull(pref.nif_durability)) //How'd you lose this?
|
||||
pref.nif_durability = initial(pref.nif_path.durability) //Well, have a new one, my bad.
|
||||
WARNING("Loaded a NIF but with no durability, [pref.real_name]")
|
||||
WARNING("Loaded a NIF but with no durability, [char_name]")
|
||||
|
||||
if(!islist(pref.nif_savedata))
|
||||
pref.nif_savedata = list()
|
||||
|
||||
@@ -80,7 +80,7 @@ var/list/gear_datums = list()
|
||||
if(pref.client)
|
||||
if(G.ckeywhitelist && !(pref.client_ckey in G.ckeywhitelist))
|
||||
return FALSE
|
||||
if(G.character_name && !(pref.real_name in G.character_name))
|
||||
if(G.character_name && !(pref.read_preference(/datum/preference/name/real_name) in G.character_name))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/be_special = 0 //Special role selection
|
||||
|
||||
//character preferences
|
||||
var/real_name //our character's name
|
||||
var/nickname //our character's nickname
|
||||
var/b_type = DEFAULT_BLOOD_TYPE //blood type (not-chooseable)
|
||||
var/blood_reagents = "default" //blood restoration reagents
|
||||
var/headset = 1 //headset type
|
||||
@@ -160,7 +158,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
// Didn't load a character, so let's randomize
|
||||
set_biological_gender(pick(MALE, FEMALE))
|
||||
real_name = random_name(identifying_gender,species)
|
||||
update_preference_by_type(/datum/preference/name/real_name, random_name(identifying_gender, species))
|
||||
b_type = RANDOM_BLOOD_TYPE
|
||||
|
||||
if(client)
|
||||
@@ -177,7 +175,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
return ..()
|
||||
|
||||
/datum/preferences/proc/ShowChoices(mob/user)
|
||||
if(!user || !user.client) return
|
||||
if(!user || !user.client)
|
||||
return
|
||||
|
||||
if(!get_mob_by_key(client_ckey))
|
||||
to_chat(user, span_danger("No mob exists for the given client!"))
|
||||
@@ -260,7 +259,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
if(href_list["save"])
|
||||
if(save_character())
|
||||
to_chat(usr,span_notice("Character [player_setup?.preferences?.real_name] saved!"))
|
||||
to_chat(usr,span_notice("Character [player_setup?.preferences?.read_preference(/datum/preference/name/real_name)] saved!"))
|
||||
save_preferences()
|
||||
else if(href_list["reload"])
|
||||
load_preferences(TRUE)
|
||||
@@ -301,7 +300,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
character.set_species(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))
|
||||
real_name = random_name(identifying_gender,species)
|
||||
update_preference_by_type(/datum/preference/name/real_name, random_name(identifying_gender, species))
|
||||
|
||||
// Ask the preferences datums to apply their own settings to the new mob
|
||||
player_setup.copy_to_mob(character)
|
||||
@@ -424,18 +423,19 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
blood color
|
||||
*/
|
||||
if (copy_name)
|
||||
var/char_real_name = read_preference(/datum/preference/name/real_name)
|
||||
if(CONFIG_GET(flag/humans_need_surnames))
|
||||
var/firstspace = findtext(real_name, " ")
|
||||
var/name_length = length(real_name)
|
||||
var/firstspace = findtext(char_real_name, " ")
|
||||
var/name_length = length(char_real_name)
|
||||
if(!firstspace) //we need a surname
|
||||
real_name += " [pick(GLOB.last_names)]"
|
||||
char_real_name += " [pick(GLOB.last_names)]"
|
||||
else if(firstspace == name_length)
|
||||
real_name += "[pick(GLOB.last_names)]"
|
||||
character.real_name = real_name
|
||||
char_real_name += "[pick(GLOB.last_names)]"
|
||||
character.real_name = char_real_name
|
||||
character.name = character.real_name
|
||||
if(character.dna)
|
||||
character.dna.real_name = character.real_name
|
||||
character.nickname = nickname
|
||||
character.nickname = read_preference(/datum/preference/name/nickname)
|
||||
character.gender = biological_gender
|
||||
character.identifying_gender = identifying_gender
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// Name preferences for character creation
|
||||
// Handles name related validation, including per species.
|
||||
|
||||
/// Abstract name preference type that provides species-aware sanitization
|
||||
/datum/preference/name
|
||||
abstract_type = /datum/preference/name
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
priority = PREFERENCE_PRIORITY_NAMES
|
||||
var/maximum_value_length = MAX_NAME_LEN
|
||||
var/default_species = SPECIES_HUMAN
|
||||
|
||||
/// 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)
|
||||
return FALSE
|
||||
return preferences.organ_data[BP_TORSO] == "cyborg"
|
||||
|
||||
/datum/preference/name/is_valid(value)
|
||||
if(!istext(value))
|
||||
return FALSE
|
||||
if(length(value) > maximum_value_length)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/preference/name/pref_deserialize(input, datum/preferences/preferences)
|
||||
if(!istext(input))
|
||||
return create_default_value()
|
||||
var/species = default_species
|
||||
if(preferences?.species)
|
||||
species = preferences.species
|
||||
var/allow_numbers = is_fbp(preferences)
|
||||
var/sanitized = sanitize_name(input, species, allow_numbers)
|
||||
if(!sanitized)
|
||||
return create_default_value()
|
||||
return sanitized
|
||||
|
||||
// Note: pref_serialize intentionally does NOT re-sanitize the value.
|
||||
// The base proc doesn't pass preferences, so we can't check is_fbp().
|
||||
// Sanitization happens on read via pref_deserialize which DOES have access to preferences.
|
||||
/datum/preference/name/pref_serialize(input)
|
||||
if(!istext(input))
|
||||
return create_default_value()
|
||||
return input
|
||||
|
||||
/datum/preference/name/apply_to_human(mob/living/carbon/human/target, value)
|
||||
return // Handled in copy_to_mob
|
||||
|
||||
/datum/preference/name/apply_to_living(mob/living/target, value)
|
||||
return
|
||||
|
||||
/datum/preference/name/apply_to_silicon(mob/living/silicon/target, value)
|
||||
return
|
||||
|
||||
/datum/preference/name/apply_to_animal(mob/living/simple_mob, value)
|
||||
return
|
||||
|
||||
/// Character's real name
|
||||
/datum/preference/name/real_name
|
||||
savefile_key = "real_name"
|
||||
|
||||
/datum/preference/name/real_name/create_default_value()
|
||||
return "Character"
|
||||
|
||||
/datum/preference/name/real_name/create_informed_default_value(datum/preferences/preferences)
|
||||
var/gender = preferences?.identifying_gender || MALE
|
||||
var/species = preferences?.species || SPECIES_HUMAN
|
||||
return random_name(gender, species)
|
||||
|
||||
/datum/preference/name/real_name/create_random_value(datum/preferences/preferences, datum/species/current_species)
|
||||
var/gender = preferences?.identifying_gender || MALE
|
||||
var/species_name = current_species?.name || SPECIES_HUMAN
|
||||
return random_name(gender, species_name)
|
||||
|
||||
/// Character's nickname (optional)
|
||||
/datum/preference/name/nickname
|
||||
savefile_key = "nickname"
|
||||
|
||||
/datum/preference/name/nickname/is_valid(value)
|
||||
if(isnull(value) || value == "")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/preference/name/nickname/pref_deserialize(input, datum/preferences/preferences)
|
||||
if(isnull(input) || input == "")
|
||||
return null
|
||||
return ..()
|
||||
|
||||
/datum/preference/name/nickname/pref_serialize(value, datum/preferences/preferences)
|
||||
if(isnull(value) || value == "")
|
||||
return null
|
||||
return ..()
|
||||
|
||||
/datum/preference/name/nickname/create_default_value()
|
||||
return null
|
||||
Reference in New Issue
Block a user