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,60 @@ 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 += "| [current_species.blurb] | "
+ dat += ""
+ dat += "\[icon goes here\]
"
+ 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 += " | "
+ dat += " "
+ 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 +1133,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 +1196,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 +1603,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..09830da1869 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)
@@ -154,6 +237,8 @@
speech_verb = "enunciates"
colour = "say_quote"
key = "2"
+ space_chance = 70
+ syllables = list("bu","chu","fu","dru","po","cha","lu","du","du","lo","shu","nu","he","gu")
/datum/language/gutter
name = "Gutter"
@@ -161,6 +246,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"
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 67eb8f86e09..9eda5c0330f 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.
@@ -24,7 +25,7 @@
var/unarmed_type = /datum/unarmed_attack
var/secondary_unarmed_type = /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.
@@ -101,6 +102,10 @@
if(unarmed_type) unarmed = new unarmed_type()
if(secondary_unarmed_type) secondary_unarmed = new secondary_unarmed_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.
@@ -208,12 +213,14 @@
language = "Sol Common"
primitive = /mob/living/carbon/monkey
unarmed_type = /datum/unarmed_attack/punch
+ 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"
@@ -227,6 +234,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
@@ -252,6 +265,11 @@
unarmed_type = /datum/unarmed_attack/claws
secondary_unarmed_type = /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
@@ -277,6 +295,11 @@
language = "Skrellian"
primitive = /mob/living/carbon/monkey/skrell
unarmed_type = /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
@@ -295,6 +318,12 @@
unarmed_type = /datum/unarmed_attack/claws/strong
secondary_unarmed_type = /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
@@ -333,6 +362,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"
@@ -385,6 +418,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,
|