diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm
index ac86912c84..f0a8a4e2c6 100644
--- a/code/_globalvars/lists/flavor_misc.dm
+++ b/code/_globalvars/lists/flavor_misc.dm
@@ -284,6 +284,17 @@ GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks"))
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien))
+/proc/get_roundstart_languages()
+ var/list/languages = subtypesof(/datum/language)
+ var/list/roundstart_languages = list("None") //default option for the list
+ for(var/some_language in languages)
+ var/datum/language/language = some_language
+ if(initial(language.chooseable_roundstart))
+ roundstart_languages[initial(language.name)] = some_language
+ return roundstart_languages
+
+GLOBAL_LIST_INIT(roundstart_languages, get_roundstart_languages())
+
//SPECIES BODYPART LISTS
//locked parts are those that your picked species requires to have
//unlocked parts are those that anyone can choose on customisation regardless
diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm
index 659149a123..23fd75f982 100644
--- a/code/datums/traits/good.dm
+++ b/code/datums/traits/good.dm
@@ -219,19 +219,3 @@
/datum/quirk/night_vision/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
H.update_sight()
-
-/datum/quirk/multilingual
- name = "Multi-Lingual"
- desc = "You spent a portion of your life learning to understand an additional language. You may or may not be able to speak it based on your anatomy."
- value = 1
- mob_trait = TRAIT_MULTILINGUAL
- gain_text = "You've learned an extra language!"
- lose_text = "You've forgotten your extra language."
-
-/datum/quirk/multilingual/post_add()
- var/mob/living/carbon/human/H = quirk_holder
- H.grant_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL)
-
-/datum/quirk/multilingual/remove()
- var/mob/living/carbon/human/H = quirk_holder
- H.remove_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 16e1b45843..05c2596f65 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -105,8 +105,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/be_random_body = 0 //whether we'll have a random body every round
var/gender = MALE //gender of character (well duh)
var/age = 30 //age of character
- var/language = "Random" //bonus language
- var/choselanguage = "Random" //language appearance
var/underwear = "Nude" //underwear type
var/undie_color = "FFFFFF"
var/undershirt = "Nude" //undershirt type
@@ -130,6 +128,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/custom_speech_verb = "default" //if your say_mod is to be something other than your races
var/custom_tongue = "default" //if your tongue is to be something other than your races
+ var/additional_language = "None" //additional language your character has
var/modified_limbs = list() //prosthetic/amputated limbs
var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded
@@ -277,10 +276,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Character Settings"
dat += "Character Appearance"
- dat += "Loadout"
+ dat += "Character Speech"
+ dat += "Loadout"
dat += "Game Preferences"
- dat += "Content Preferences"
- dat += "Keybindings"
+ dat += "Content Preferences"
+ dat += "Keybindings"
if(!path)
dat += "
Please create an account to save your preferences
"
@@ -328,7 +328,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Gender: [gender == MALE ? "Male" : (gender == FEMALE ? "Female" : (gender == PLURAL ? "Non-binary" : "Object"))]
"
dat += "Age: [age]
"
- dat += "Language: [choselanguage]
"
dat += "Special Names:
"
var/old_group
@@ -485,13 +484,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else if(use_skintones || mutant_colors)
dat += ""
- dat += APPEARANCE_CATEGORY_COLUMN
- dat += "Speech preferences
"
- dat += "Custom Speech Verb:
"
- dat += "[custom_speech_verb]
"
- dat += "Custom Tongue:
"
- dat += "[custom_tongue]
"
-
if(HAIR in pref_species.species_traits)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -678,6 +670,36 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += ""
dat += ""
+ if(3)
+ if(path)
+ var/savefile/S = new /savefile(path)
+ if(S)
+ dat += ""
+ var/name
+ var/unspaced_slots = 0
+ for(var/i=1, i<=max_save_slots, i++)
+ unspaced_slots++
+ if(unspaced_slots > 4)
+ dat += "
"
+ unspaced_slots = 0
+ S.cd = "/character[i]"
+ S["real_name"] >> name
+ if(!name)
+ name = "Character[i]"
+ dat += "[name] "
+ dat += ""
+
+ dat += ""
+
if (1) // Game Preferences
dat += ""
dat += "General Settings"
@@ -846,7 +868,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += " "
- if(3)
+ if(4)
//calculate your gear points from the chosen item
gear_points = CONFIG_GET(number/initial_gear_points)
var/list/chosen_gear = loadout_data["SAVE_[loadout_slot]"]
@@ -965,7 +987,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += " | [loadout_item ? (loadout_item[LOADOUT_CUSTOM_DESCRIPTION] ? loadout_item[LOADOUT_CUSTOM_DESCRIPTION] : gear.description) : gear.description] Progress: [min(progress_made, unlockable.progress_required)]/[unlockable.progress_required] |
"
dat += "
"
- if(4) // Content preferences
+ if(5) // Content preferences
dat += ""
dat += "
"
- if(5) // Custom keybindings
+ if(6) // Custom keybindings
dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Input"]
"
dat += "Keybindings mode controls how the game behaves with tab and map/input focus.
If it is on Hotkeys, the game will always attempt to force you to map focus, meaning keypresses are sent \
directly to the map instead of the input. You will still be able to use the command bar, but you need to tab to do it every time you click on the game map.
\
@@ -2339,28 +2361,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["body_model"] = chosengender
gender = chosengender
- if("language")
- choselanguage = input(user, "Select a language.", "Language", language) as null|anything in list("Beachtongue","Draconic","Dwarven",
- "Chimpanzee","Space Sign Language","Random")
- if(!choselanguage)
- return
- switch(choselanguage)
- if("Rachidian")
- language = /datum/language/arachnid
- if("Beachtongue")
- language = /datum/language/beachbum
- if("Draconic")
- language = /datum/language/draconic
- if("Dwarven")
- language = /datum/language/dwarf
- if("Chimpanzee")
- language = /datum/language/monkey
- if("Space Sign Language")
- language = /datum/language/signlanguage
- if("Random")
- language = pick(list("Rachidian", "Beachtongue","Draconic","Dwarven",
- "Chimpanzee","Space Sign Language"))
-
if("body_size")
var/new_body_size = input(user, "Choose your desired sprite size: (90-125%)\nWarning: This may make your character look distorted. Additionally, any size under 100% takes a 10% maximum health penalty", "Character Preference", features["body_size"]*100) as num|null
if(new_body_size)
@@ -2370,11 +2370,17 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/selected_custom_tongue = input(user, "Choose your desired tongue (none means your species tongue)", "Character Preference") as null|anything in GLOB.roundstart_tongues
if(selected_custom_tongue)
custom_tongue = selected_custom_tongue
+
if("speech_verb")
var/selected_custom_speech_verb = input(user, "Choose your desired speech verb (none means your species speech verb)", "Character Preference") as null|anything in GLOB.speech_verbs
if(selected_custom_speech_verb)
custom_speech_verb = selected_custom_speech_verb
+ if("language")
+ var/selected_language = input(user, "Choose your desired additional language", "Character Preference") as null|anything in GLOB.roundstart_languages
+ if(selected_language)
+ additional_language = selected_language
+
if("bodysprite")
var/selected_body_sprite = input(user, "Choose your desired body sprite", "Character Preference") as null|anything in pref_species.allowed_limb_ids
if(selected_body_sprite)
@@ -2909,6 +2915,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
new_custom_tongue.Insert(character)
if(custom_speech_verb != "default")
character.dna.species.say_mod = custom_speech_verb
+ if(additional_language && additional_language != "None")
+ var/language_entry = GLOB.roundstart_languages[additional_language]
+ if(language_entry)
+ character.grant_language(language_entry, TRUE, TRUE)
//limb stuff, only done when initially spawning in
if(initial_spawn)
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 141346acde..812e8c4821 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -604,8 +604,6 @@ 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
@@ -626,6 +624,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["uplink_loc"] >> uplink_spawn_loc
S["custom_speech_verb"] >> custom_speech_verb
S["custom_tongue"] >> custom_tongue
+ S["additional_language"] >> additional_language
S["feature_mcolor"] >> features["mcolor"]
S["feature_lizard_tail"] >> features["tail_lizard"]
S["feature_lizard_snout"] >> features["snout"]
@@ -881,6 +880,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
custom_speech_verb = sanitize_inlist(custom_speech_verb, GLOB.speech_verbs, "default")
custom_tongue = sanitize_inlist(custom_tongue, GLOB.roundstart_tongues, "default")
+ additional_language = sanitize_inlist(additional_language, GLOB.roundstart_languages, "None")
security_records = copytext(security_records, 1, MAX_FLAVOR_LEN)
medical_records = copytext(medical_records, 1, MAX_FLAVOR_LEN)
@@ -964,8 +964,6 @@ 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)
@@ -987,6 +985,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["species"] , pref_species.id)
WRITE_FILE(S["custom_speech_verb"] , custom_speech_verb)
WRITE_FILE(S["custom_tongue"] , custom_tongue)
+ WRITE_FILE(S["additional_language"] , additional_language)
// records
WRITE_FILE(S["security_records"] , security_records)
diff --git a/code/modules/language/arachnid.dm b/code/modules/language/arachnid.dm
index 92ea47781e..d021e5a35b 100644
--- a/code/modules/language/arachnid.dm
+++ b/code/modules/language/arachnid.dm
@@ -9,6 +9,7 @@
flags = NO_STUTTER | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD
icon_state = "arachnid"
+ chooseable_roundstart = TRUE
/datum/language/arachnid/scramble(input)
. = prob(65) ? "wiff" : "thump"
diff --git a/code/modules/language/draconic.dm b/code/modules/language/draconic.dm
index aaa998c2c0..ed72252773 100644
--- a/code/modules/language/draconic.dm
+++ b/code/modules/language/draconic.dm
@@ -18,3 +18,4 @@
)
icon_state = "lizard"
default_priority = 90
+ chooseable_roundstart = TRUE
diff --git a/code/modules/language/dwarven.dm b/code/modules/language/dwarven.dm
index 17a4674415..aded22cd6f 100644
--- a/code/modules/language/dwarven.dm
+++ b/code/modules/language/dwarven.dm
@@ -11,3 +11,4 @@
default_priority = 90
icon_state = "dwarf"
+ chooseable_roundstart = TRUE
diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm
index 42b439ba03..f65d928301 100644
--- a/code/modules/language/language.dm
+++ b/code/modules/language/language.dm
@@ -22,6 +22,8 @@
var/list/scramble_cache = list()
var/default_priority = 0 // the language that an atom knows with the highest "default_priority" is selected by default.
+ var/chooseable_roundstart = FALSE // can we pick it from the customization menu as an additional language?
+
// if you are seeing someone speak popcorn language, then something is wrong.
var/icon = 'icons/misc/language.dmi'
var/icon_state = "popcorn"
diff --git a/code/modules/language/monkey.dm b/code/modules/language/monkey.dm
index 53e598b02b..6f3da838bc 100644
--- a/code/modules/language/monkey.dm
+++ b/code/modules/language/monkey.dm
@@ -10,3 +10,4 @@
default_priority = 80
icon_state = "animal"
+ chooseable_roundstart = TRUE
diff --git a/code/modules/language/mushroom.dm b/code/modules/language/mushroom.dm
index b896d11449..038ee0f905 100644
--- a/code/modules/language/mushroom.dm
+++ b/code/modules/language/mushroom.dm
@@ -9,3 +9,4 @@
sentence_chance = 0
default_priority = 80
syllables = list("poof", "pff", "pFfF", "piff", "puff", "pooof", "pfffff", "piffpiff", "puffpuff", "poofpoof", "pifpafpofpuf")
+ chooseable_roundstart = TRUE
diff --git a/code/modules/language/slime.dm b/code/modules/language/slime.dm
index cca56ca933..6b7b1c366d 100644
--- a/code/modules/language/slime.dm
+++ b/code/modules/language/slime.dm
@@ -10,3 +10,4 @@
default_priority = 70
icon_state = "slime"
+ chooseable_roundstart = TRUE
diff --git a/code/modules/language/sylvan.dm b/code/modules/language/sylvan.dm
index 3bbf5f6afd..a1ac6725b9 100644
--- a/code/modules/language/sylvan.dm
+++ b/code/modules/language/sylvan.dm
@@ -16,3 +16,4 @@
)
icon_state = "plant"
default_priority = 90
+ chooseable_roundstart = TRUE
diff --git a/code/modules/language/voltaic.dm b/code/modules/language/voltaic.dm
index ead7fe7c7f..9a64f56889 100644
--- a/code/modules/language/voltaic.dm
+++ b/code/modules/language/voltaic.dm
@@ -12,3 +12,4 @@
)
icon_state = "volt"
default_priority = 90
+ chooseable_roundstart = TRUE