diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 3c7582b8164..bf18e430407 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -38,8 +38,18 @@ proc/random_facial_hair_style(gender, species = "Human") return f_style proc/random_name(gender, species = "Human") - if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + + var/datum/species/current_species + if(species) + current_species = all_species[species] + + if(!current_species) + if(gender==FEMALE) + return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + else + return current_species.get_random_name(gender) proc/random_skin_tone() switch(pick(60;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino")) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index bde0a469f22..68009eec609 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -84,7 +84,10 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ /obj/machinery/hologram/holopad/hear_talk(mob/living/M, text, verb, datum/language/speaking) if(M&&hologram&&master)//Master is mostly a safety in case lag hits or something. if(!master.say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad. - text = stars(text) + if(speaking) + text = speaking.scramble(text) + else + text = stars(text) var/name_used = M.GetVoice() //This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only. var/rendered diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index c913dcf5696..fcbcb18fd3f 100755 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -73,6 +73,7 @@ datum/preferences var/g_eyes = 0 //Eye color var/b_eyes = 0 //Eye color var/species = "Human" //Species datum to use. + var/species_preview //Used for the species selection window. var/language = "None" //Secondary language var/list/gear //Custom/fluff item loadout. @@ -138,7 +139,7 @@ datum/preferences if(load_character()) return gender = pick(MALE, FEMALE) - real_name = random_name(gender) + real_name = random_name(gender,species) gear = list() @@ -302,7 +303,7 @@ datum/preferences dat += "
Body " dat += "(®)" dat += "
" - dat += "Species: [species]
" + dat += "Species: [species]
" dat += "Secondary Language:
[language]
" dat += "Blood Type: [b_type]
" dat += "Skin Tone: [-s_tone + 35]/220
" @@ -588,6 +589,62 @@ datum/preferences user << browse(HTML, "window=records;size=350x300") return +/datum/preferences/proc/SetSpecies(mob/user) + if(!species_preview || !(species_preview in all_species)) + species_preview = "Human" + var/datum/species/current_species = all_species[species_preview] + var/dat = "" + dat += "

[current_species.name] \[change\]


" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
[current_species.blurb]" + if("preview" in icon_states(current_species.icobase)) + usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png") + dat += "

" + dat += "Language: [current_species.language]
" + dat += "" + if(current_species.flags & IS_WHITELISTED) + dat += "
Whitelist restricted." + if(current_species.flags & NO_BLOOD) + dat += "
Does not have blood." + if(current_species.flags & NO_BREATHE) + dat += "
Does not breathe." + if(current_species.flags & NO_SCAN) + dat += "
Does not have DNA." + if(current_species.flags & NO_PAIN) + dat += "
Does not feel pain." + if(current_species.flags & NO_SLIP) + dat += "
Has excellent traction." + if(current_species.flags & NO_POISON) + dat += "
Immune to most poisons." + if(current_species.flags & HAS_SKIN_TONE) + dat += "
Has a variety of skin tones." + if(current_species.flags & HAS_SKIN_COLOR) + dat += "
Has a variety of skin colours." + if(current_species.flags & HAS_EYE_COLOR) + dat += "
Has a variety of eye colours." + if(current_species.flags & IS_PLANT) + dat += "
Has a plantlike physiology." + if(current_species.flags & IS_SYNTHETIC) + dat += "
Is machine-based." + dat += "

" + + var/restricted + if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it! + if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(user,current_species)) + restricted = 1 + if(restricted) + dat += "You cannot play as this species.
If you wish to be whitelisted, you can make an application post on the forums.
" + else + dat += "\[select\]" + dat += "
" + + user << browse(null, "window=preferences") + user << browse(dat, "window=species;size=700x400") + /datum/preferences/proc/SetAntagoptions(mob/user) if(uplinklocation == "" || !uplinklocation) uplinklocation = "PDA" @@ -1078,10 +1135,18 @@ datum/preferences break switch(href_list["task"]) + if("change") + if(href_list["preference"] == "species") + // Actual whitelist checks are handled elsewhere, this is just for accessing the preview window. + var/choice = input("Which species would you like to look at?") as null|anything in whitelisted_species + if(!choice) return + species_preview = choice + SetSpecies(user) + if("random") switch(href_list["preference"]) if("name") - real_name = random_name(gender) + real_name = random_name(gender,species) if("age") age = rand(AGE_MIN, AGE_MAX) if("hair") @@ -1133,24 +1198,11 @@ datum/preferences var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null if(new_age) age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) + if("species") - - var/list/new_species = list("Human") + user << browse(null, "window=species") var/prev_species = species - var/whitelisted = 0 - - if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it! - for(var/S in whitelisted_species) - if(is_alien_whitelisted(user,S)) - new_species += S - whitelisted = 1 - if(!whitelisted) - alert(user, "You cannot change your species as you need to be whitelisted. If you wish to be whitelisted contact an admin in-game, on the forums, or on IRC.") - else //Not using the whitelist? Aliens for everyone! - new_species = whitelisted_species - - species = input("Please select a species", "Character Generation", null) in new_species - + species = href_list["newspecies"] if(prev_species != species) //grab one of the valid hair styles for the newly chosen species var/list/valid_hairstyles = list() @@ -1553,7 +1605,7 @@ datum/preferences /datum/preferences/proc/copy_to(mob/living/carbon/human/character, safety = 0) if(be_random_name) - real_name = random_name(gender) + real_name = random_name(gender,species) if(config.humans_need_surnames) var/firstspace = findtext(real_name, " ") diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index da07bb0aaf6..c238aef0264 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -36,7 +36,10 @@ var/mob/living/simple_animal/S = speaker message = pick(S.speak) else - message = stars(message) + if(language) + message = language.scramble(message) + else + message = stars(message) var/speaker_name = speaker.name if(istype(speaker, /mob/living/carbon/human)) @@ -97,7 +100,10 @@ else return else - message = stars(message) + if(language) + message = language.scramble(language) + else + message = stars(message) if(hard_to_hear) message = stars(message) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 5fee93197ce..10809d9db57 100755 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -10,10 +10,59 @@ var/exclaim_verb = "exclaims" // Used when sentence ends in a ! var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags - var/colour = "body" // CSS style to use for strings in this language. + var/colour = "body" // CSS style to use for strings in this language. var/key = "x" // Character used to speak in language eg. :o for Unathi. var/flags = 0 // Various language flags. var/native // If set, non-native speakers will have trouble speaking. + var/list/syllables // Used when scrambling text for a non-speaker. + var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string. + +/datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4) + if(!syllables || !syllables.len) + if(gender==FEMALE) + return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) + else + return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + + var/full_name = "" + var/new_name = "" + + for(var/i = 0;i0;x--) + new_name += pick(syllables) + full_name += " [capitalize(lowertext(new_name))]" + + return "[trim(full_name)]" + +/datum/language/proc/scramble(var/input) + + if(!syllables || !syllables.len) + return stars(input) + + var/input_size = length(input) + var/scrambled_text = "" + var/capitalize = 1 + + while(length(scrambled_text) < input_size) + var/next = pick(syllables) + if(capitalize) + next = capitalize(next) + capitalize = 0 + scrambled_text += next + var/chance = rand(100) + if(chance <= 5) + scrambled_text += ". " + capitalize = 1 + else if(chance > 5 && chance <= space_chance) + scrambled_text += " " + + scrambled_text = trim(scrambled_text) + var/ending = copytext(scrambled_text, length(scrambled_text)) + if(ending == ".") + scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1) + scrambled_text += copytext(input, length(input)) + return scrambled_text /datum/language/proc/format_message(message, verb) return "[verb], \"[capitalize(message)]\"" @@ -72,6 +121,14 @@ colour = "soghun" key = "o" flags = WHITELISTED + syllables = list("ss","ss","ss","ss","skak","seeki","resh","las","esi","kor","sh") + +/datum/language/unathi/get_random_name() + + var/new_name = ..() + while(findtextEx(new_name,"sss",1,null)) + new_name = replacetext(new_name, "sss", "ss") + return capitalize(new_name) /datum/language/tajaran name = "Siik'tajr" @@ -82,6 +139,19 @@ colour = "tajaran" key = "j" flags = WHITELISTED + syllables = list("rr","rr","tajr","kir","raj","kii","mir","kra","ahk","nal","vah","khaz","jri","ran","darr", \ + "mi","jri","dynh","manq","rhe","zar","rrhaz","kal","chur","eech","thaa","dra","jurl","mah","sanu","dra","ii'r", \ + "ka","aasi","far","wa","baq","ara","qara","zir","sam","mak","hrar","nja","rir","khan","jun","dar","rik","kah", \ + "hal","ket","jurl","mah","tul","cresh","azu","ragh") + +/datum/language/tajaran/get_random_name(var/gender) + + var/new_name = ..(gender,1) + if(prob(80)) + new_name += " [pick(list("Hadii","Kaytam","Zhan-Khazan","Hharar","Njarir'Akhan"))]" + else + new_name += ..(gender,1) + return new_name /datum/language/skrell name = "Skrellian" @@ -92,6 +162,7 @@ colour = "skrell" key = "k" flags = WHITELISTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") /datum/language/vox name = "Vox-pidgin" @@ -101,7 +172,12 @@ exclaim_verb = "SHRIEKS" colour = "vox" key = "5" - flags = RESTRICTED + flags = WHITELISTED + syllables = list("ti","ti","ti","hi","hi","ki","ki","ki","ki","ya","ta","ha","ka","ya","chi","cha","kah", \ + "SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA") + +/datum/language/vox/get_random_name() + return ..(FEMALE,1,6) /datum/language/diona name = "Rootspeak" @@ -112,6 +188,12 @@ colour = "soghun" key = "q" flags = RESTRICTED + syllables = list("hs","zt","kr","st","sh") + +/datum/language/diona/get_random_name() + var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]" + new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]" + return new_name /datum/language/common name = "Galactic Common" @@ -120,6 +202,7 @@ whisper_verb = "whispers" key = "0" flags = RESTRICTED + syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") //TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. /datum/language/common/get_spoken_verb(var/msg_end) @@ -135,9 +218,10 @@ desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system." speech_verb = "says" whisper_verb = "whispers" - colour = "rough" + colour = "solcom" key = "1" flags = RESTRICTED + syllables = list("tao","shi","tzu","yi","com","be","is","i","op","vi","ed","lec","mo","cle","te","dis","e") /datum/language/human/get_spoken_verb(var/msg_end) switch(msg_end) @@ -154,6 +238,15 @@ speech_verb = "enunciates" colour = "say_quote" key = "2" + space_chance = 100 + syllables = list("lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", + "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", + "magna", "aliqua", "ut", "enim", "ad", "minim", "veniam", "quis", "nostrud", + "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", + "consequat", "duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", + "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", + "pariatur", "excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt", + "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum") /datum/language/gutter name = "Gutter" @@ -161,6 +254,7 @@ speech_verb = "growls" colour = "rough" key = "3" + syllables = list ("gra","ba","ba","breh","bra","rah","dur","ra","ro","gro","go","ber","bar","geh","heh", "gra") /datum/language/xenocommon name = "Xenomorph" @@ -171,6 +265,7 @@ exclaim_verb = "hisses" key = "4" flags = RESTRICTED + syllables = list("sss","sSs","SSS") /datum/language/xenos name = "Hivemind" diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0409cdfc1b3..49266c02dcb 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -11,6 +11,7 @@ var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. var/prone_icon // If set, draws this from icobase when mob is prone. var/eyes = "eyes_s" // Icon for eyes. + var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen. var/primitive // Lesser form, if any (ie. monkey for humans) var/tail // Name of tail image in species effects icon file. @@ -22,7 +23,7 @@ var/rarity_value = 1 // Relative rarity/collector value for this species. Only used by ninja and cultists atm. var/list/unarmed_types = list(/datum/unarmed_attack, /datum/unarmed_attack/bite) - var/language // Default racial language, if any. + var/language = "Galactic Common" // Default racial language, if any. // Default language is used when 'say' is used without modifiers. var/default_language = "Galactic Common" var/secondary_langs = list() // The names of secondary languages that are available to this species. @@ -100,6 +101,10 @@ for(var/u_type in unarmed_types) unarmed_attacks += new u_type() +/datum/species/proc/get_random_name(var/gender) + var/datum/language/species_language = all_languages[language] + return species_language.get_random_name(gender) + /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. //Trying to work out why species changes aren't fixing organs properly. @@ -207,12 +212,14 @@ language = "Sol Common" primitive = /mob/living/carbon/monkey unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) + blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ + colonies across a wide swathe of space. They hold a wide range of forms and creeds.

\ + While the central Sol government maintains control of its far-flung people, powerful corporate \ + interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ + worlds tumultous at best." flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR - //If you wanted to add a species-level ability: - /*abilities = list(/client/proc/test_ability)*/ - /datum/species/unathi name = "Unathi" name_plural = "Unathi" @@ -225,6 +232,12 @@ darksight = 3 gluttonous = 1 + blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ + Uuosa-Eso system, which roughly translates to 'burning mother'.

Coming from a harsh, radioactive \ + desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ + else, frequently even their own lives. They prefer warmer temperatures than most species and \ + their native tongue is a heavy hissing laungage called Sinta'Unathi." + cold_level_1 = 280 //Default 260 - Lower is better cold_level_2 = 220 //Default 200 cold_level_3 = 130 //Default 120 @@ -249,6 +262,11 @@ tail = "tajtail" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) darksight = 8 + blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ + S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ + influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ + of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ + using unique inflections their mouths form." cold_level_1 = 200 //Default 260 cold_level_2 = 140 //Default 200 @@ -274,6 +292,11 @@ language = "Skrellian" primitive = /mob/living/carbon/monkey/skrell unarmed_types = list(/datum/unarmed_attack/punch) + blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ + the royals' or 'Light of the Crown'.

Skrell are a highly advanced and logical race who live under the rule \ + of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ + herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ + the secrets of their empire to their allies." flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR @@ -291,6 +314,12 @@ language = "Galactic Common" unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong) rarity_value = 2 + blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ + scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ + alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ + refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ + smell.

Most humans will never meet a Vox raider, instead learning of this insular species through \ + dealing with their traders and merchants; those that do rarely enjoy the experience." speech_sounds = list('sound/voice/shriek1.ogg') speech_chance = 20 @@ -329,6 +358,10 @@ "stack" = /datum/organ/internal/stack/vox ) +/datum/species/vox/get_random_name(var/gender) + var/datum/language/species_language = all_languages[default_language] + return species_language.get_random_name(gender) + /datum/species/vox/armalis name = "Vox Armalis" name_plural = "Vox" @@ -380,6 +413,13 @@ primitive = /mob/living/carbon/alien/diona slowdown = 7 rarity_value = 3 + blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ + species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ + there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ + Minoris primary being ringed with a cloud of singing space-station-sized entities.

The Dionaea coexist peacefully with \ + all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ + even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ + water and other radiation." has_organ = list( "nutrient channel" = /datum/organ/internal/diona/nutrients, diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 2d9020e0f07..c722d86dd5a 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -79,6 +79,7 @@ h1.alert, h2.alert {color: #000000;} .tajaran_signlang {color: #941C1C;} .skrell {color: #00CED1;} .soghun {color: #228B22;} +.solcom {color: #22228B;} .changeling {color: #800080;} .vox {color: #AA00AA;} .rough {font-family: "Trebuchet MS", cursive, sans-serif;} diff --git a/icons/mob/human_races/r_diona.dmi b/icons/mob/human_races/r_diona.dmi index c09acaa9538..91757faf7ca 100644 Binary files a/icons/mob/human_races/r_diona.dmi and b/icons/mob/human_races/r_diona.dmi differ diff --git a/icons/mob/human_races/r_human.dmi b/icons/mob/human_races/r_human.dmi index 8cafd92ce11..7ddd9453810 100644 Binary files a/icons/mob/human_races/r_human.dmi and b/icons/mob/human_races/r_human.dmi differ diff --git a/icons/mob/human_races/r_lizard.dmi b/icons/mob/human_races/r_lizard.dmi index 41b275beef2..85208cff785 100644 Binary files a/icons/mob/human_races/r_lizard.dmi and b/icons/mob/human_races/r_lizard.dmi differ diff --git a/icons/mob/human_races/r_plant.dmi b/icons/mob/human_races/r_plant.dmi deleted file mode 100644 index ef55275d5a9..00000000000 Binary files a/icons/mob/human_races/r_plant.dmi and /dev/null differ diff --git a/icons/mob/human_races/r_skrell.dmi b/icons/mob/human_races/r_skrell.dmi index 913474d3b6f..bb9f0fcfed6 100644 Binary files a/icons/mob/human_races/r_skrell.dmi and b/icons/mob/human_races/r_skrell.dmi differ diff --git a/icons/mob/human_races/r_tajaran.dmi b/icons/mob/human_races/r_tajaran.dmi index 7a7419df414..69fa8ce5c0b 100644 Binary files a/icons/mob/human_races/r_tajaran.dmi and b/icons/mob/human_races/r_tajaran.dmi differ diff --git a/icons/mob/human_races/r_vox.dmi b/icons/mob/human_races/r_vox.dmi index 6aada937c25..f212822aafb 100644 Binary files a/icons/mob/human_races/r_vox.dmi and b/icons/mob/human_races/r_vox.dmi differ