mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-29 08:08:49 +01:00
Adds Common Second Language quirk, tweaks to partial understanding (#90614)
## About The Pull Request - Tweaks partial understanding. Paragraphs are now split into sentences first creating more natural breaks between sentences. - Adds "Common Second Language" quirk This quirk changes your default understanding of common (up to) 90% (your choice), meaning you drop the occasional word.   Additionally, when your sanity drops below a threshold, you become forced to speak your native language, albeit with a partial understanding applied for everyone else. Incompatible with similar language quirks + can't be taken by humans (yet?) ## Why It's Good For The Game Just a fun way to play around with the new "partial understanding" system. ## Changelog 🆑 Melbert add: "Common Second Language" quirk qol: Language translations chunk sentences together better, making partial understanding a bit easier to parse. /🆑
This commit is contained in:
@@ -138,4 +138,3 @@
|
||||
#define COMSIG_MOVABLE_BUMP_PUSHED "movable_bump_pushed"
|
||||
/// Stop it from moving
|
||||
#define COMPONENT_NO_PUSH (1<<0)
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#define RADIO_EXTENSION "department specific"
|
||||
#define RADIO_KEY "department specific key"
|
||||
#define LANGUAGE_EXTENSION "language specific"
|
||||
/// Message mod which contains a list of bonus "mutual understanding" to allow arbitrary understanding of any speech
|
||||
#define LANGUAGE_MUTUAL_BONUS "language mutual bonus"
|
||||
#define SAY_MOD_VERB "say_mod_verb"
|
||||
|
||||
//Message modes. Each one defines a radio channel, more or less.
|
||||
|
||||
@@ -23,7 +23,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list(
|
||||
list(/datum/quirk/social_anxiety, /datum/quirk/mute),
|
||||
list(/datum/quirk/mute, /datum/quirk/softspoken),
|
||||
list(/datum/quirk/poor_aim, /datum/quirk/bighands),
|
||||
list(/datum/quirk/bilingual, /datum/quirk/foreigner),
|
||||
list(/datum/quirk/bilingual, /datum/quirk/foreigner, /datum/quirk/csl),
|
||||
list(/datum/quirk/spacer_born, /datum/quirk/item_quirk/settler),
|
||||
list(/datum/quirk/photophobia, /datum/quirk/nyctophobia),
|
||||
list(/datum/quirk/item_quirk/settler, /datum/quirk/freerunning),
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/datum/quirk/csl
|
||||
name = "Common Second Language"
|
||||
desc = "Common is not your native tongue - it's something you had to pick up along the way. \
|
||||
Some words in common will sound foreign, and you may drift back to your native tongue \
|
||||
when you are anxious or upset."
|
||||
icon = FA_ICON_LANDMARK_DOME
|
||||
quirk_flags = QUIRK_HIDE_FROM_SCAN
|
||||
value = -2
|
||||
gain_text = span_danger("You have difficulty parsing Common.")
|
||||
lose_text = span_notice("Common starts to click for you.")
|
||||
medical_record_text = "Patient is CSL."
|
||||
/// What language typepath is our primary language?
|
||||
var/native_language
|
||||
|
||||
/datum/quirk/csl/add(client/client_source)
|
||||
if(iscarbon(quirk_holder))
|
||||
quirk_holder.remove_language(/datum/language/common, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES)
|
||||
else
|
||||
quirk_holder.remove_language(/datum/language/common, UNDERSTOOD_LANGUAGE, LANGUAGE_ATOM)
|
||||
quirk_holder.grant_partial_language(/datum/language/common, text2num(client_source?.prefs?.read_preference(/datum/preference/choiced/csl_strength)) || 90, type)
|
||||
RegisterSignal(quirk_holder, COMSIG_SPECIES_GAIN, PROC_REF(reremove_common))
|
||||
RegisterSignal(quirk_holder, COMSIG_MOB_SAY, PROC_REF(translate_parts))
|
||||
native_language = get_native_language()
|
||||
|
||||
/datum/quirk/csl/remove()
|
||||
UnregisterSignal(quirk_holder, COMSIG_SPECIES_GAIN)
|
||||
UnregisterSignal(quirk_holder, COMSIG_MOB_SAY)
|
||||
|
||||
if(QDELING(quirk_holder))
|
||||
return
|
||||
|
||||
quirk_holder.remove_partial_language(/datum/language/common, type)
|
||||
var/mob/living/carbon/carbon_quirk_holder = quirk_holder
|
||||
if(istype(carbon_quirk_holder) && carbon_quirk_holder.dna.species)
|
||||
// only give back common if they're a species that should speak it
|
||||
var/datum/language_holder/species_holder = GLOB.prototype_language_holders[carbon_quirk_holder.dna.species.species_language_holder]
|
||||
if(LAZYACCESS(species_holder.spoken_languages, /datum/language/common))
|
||||
quirk_holder.grant_language(/datum/language/common, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES)
|
||||
else
|
||||
quirk_holder.grant_language(/datum/language/common, UNDERSTOOD_LANGUAGE, LANGUAGE_ATOM)
|
||||
|
||||
/datum/quirk/csl/is_species_appropriate(datum/species/mob_species)
|
||||
var/datum/language_holder/species_holder = GLOB.prototype_language_holders[mob_species.species_language_holder]
|
||||
if(isnull(species_holder))
|
||||
return FALSE
|
||||
if(length(species_holder.spoken_languages) < 2)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/// Gets our native language from our list of spoken languages
|
||||
/datum/quirk/csl/proc/get_native_language()
|
||||
var/list/language_pool = quirk_holder.get_language_holder()?.spoken_languages?.Copy()
|
||||
if(!length(language_pool))
|
||||
return // no languages to pick from at all?
|
||||
|
||||
// Don't want this
|
||||
language_pool -= /datum/language/common
|
||||
// If we have native languages set, prefer them
|
||||
var/list/prioritized_language_pool
|
||||
var/obj/item/organ/tongue/tongue = quirk_holder.get_organ_by_type(/obj/item/organ/tongue)
|
||||
if(length(tongue?.languages_native) > 0)
|
||||
prioritized_language_pool = language_pool & tongue.languages_native
|
||||
|
||||
if(length(language_pool) < 1)
|
||||
return // guess we couldn't find one
|
||||
|
||||
return length(prioritized_language_pool) > 0 ? prioritized_language_pool[1] : language_pool[1]
|
||||
|
||||
// Every time we change species we need to re-remove common from our list
|
||||
/datum/quirk/csl/proc/reremove_common(...)
|
||||
SIGNAL_HANDLER
|
||||
quirk_holder.remove_language(/datum/language/common, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES)
|
||||
native_language = get_native_language()
|
||||
|
||||
// At low sanity we translate everything to our native language
|
||||
/datum/quirk/csl/proc/translate_parts(datum/source, list/say_args)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(say_args[SPEECH_FORCED] || isnull(native_language) || quirk_holder.mob_mood?.sanity > 75)
|
||||
return
|
||||
// init this list if nothing else has
|
||||
LAZYINITLIST(say_args[SPEECH_MODS][LANGUAGE_MUTUAL_BONUS])
|
||||
// force speak language, add mutual bonuses so everyone else can understand
|
||||
say_args[SPEECH_LANGUAGE] = native_language
|
||||
say_args[SPEECH_MODS][LANGUAGE_MUTUAL_BONUS][native_language] = max(round(8 * sqrt(quirk_holder.mob_mood?.sanity), 5), say_args[SPEECH_MODS][LANGUAGE_MUTUAL_BONUS][native_language])
|
||||
|
||||
/datum/quirk_constant_data/csl
|
||||
associated_typepath = /datum/quirk/csl
|
||||
customization_options = list(
|
||||
/datum/preference/choiced/csl_strength,
|
||||
)
|
||||
@@ -1619,7 +1619,8 @@
|
||||
return get_language_holder().get_random_understood_language()
|
||||
|
||||
/// Gets a lazylist of all mutually understood languages.
|
||||
/atom/movable/proc/get_partially_understood_languages()
|
||||
/atom/movable/proc/get_partially_understood_languages() as /list
|
||||
RETURN_TYPE(/list)
|
||||
return get_language_holder().best_mutual_languages
|
||||
|
||||
/// Gets a random spoken language, useful for forced speech and such.
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
message_out = "\"[message_in]\""
|
||||
else if(!user.has_language(language))
|
||||
// Language unknown: scramble
|
||||
message_out = "\"[language_instance.scramble_sentence(message_in, user.get_partially_understood_languages())]\""
|
||||
message_out = "\"[language_instance.scramble_paragraph(message_in, user.get_partially_understood_languages())]\""
|
||||
else
|
||||
message_out = "(Unintelligible)"
|
||||
packet_out["message"] = message_out
|
||||
|
||||
+9
-1
@@ -272,8 +272,16 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
return "makes a strange sound."
|
||||
|
||||
if(!has_language(language))
|
||||
var/list/mutual_languages
|
||||
// Get what we can kinda understand, factor in any bonuses passed in from say mods
|
||||
var/list/partially_understood_languages = get_partially_understood_languages()
|
||||
if(LAZYLEN(partially_understood_languages))
|
||||
mutual_languages = partially_understood_languages.Copy()
|
||||
for(var/bonus_language in message_mods[LANGUAGE_MUTUAL_BONUS])
|
||||
mutual_languages[bonus_language] = max(message_mods[LANGUAGE_MUTUAL_BONUS][bonus_language], mutual_languages[bonus_language])
|
||||
|
||||
var/datum/language/dialect = GLOB.language_datum_instances[language]
|
||||
raw_message = dialect.scramble_sentence(raw_message, get_partially_understood_languages())
|
||||
raw_message = dialect.scramble_paragraph(raw_message, mutual_languages)
|
||||
|
||||
return raw_message
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
invocation = "Ta'gh fara'qha fel d'amar det!"
|
||||
|
||||
/datum/action/innate/cult/blood_spell/emp/Activate()
|
||||
owner.whisper(invocation, language = /datum/language/common)
|
||||
owner.whisper(invocation, language = /datum/language/common, forced = "cult invocation")
|
||||
owner.visible_message(span_warning("[owner]'s hand flashes a bright blue!"), \
|
||||
span_cult_italic("You speak the cursed words, emitting an EMP blast from your hand."))
|
||||
empulse(owner, 2, 5)
|
||||
@@ -219,7 +219,7 @@
|
||||
|
||||
/datum/action/innate/cult/blood_spell/dagger/Activate()
|
||||
var/turf/owner_turf = get_turf(owner)
|
||||
owner.whisper(invocation, language = /datum/language/common)
|
||||
owner.whisper(invocation, language = /datum/language/common, forced = "cult invocation")
|
||||
owner.visible_message(span_warning("[owner]'s hand glows red for a moment."), \
|
||||
span_cult_italic("Your plea for aid is answered, and light begins to shimmer and take form within your hand!"))
|
||||
var/obj/item/summoned_blade = new summoned_type(owner_turf)
|
||||
@@ -293,7 +293,7 @@
|
||||
span_cult_italic("You invoke the veiling spell, hiding nearby runes."))
|
||||
charges--
|
||||
SEND_SOUND(owner, sound('sound/effects/magic/smoke.ogg',0,1,25))
|
||||
owner.whisper(invocation, language = /datum/language/common)
|
||||
owner.whisper(invocation, language = /datum/language/common, forced = "cult invocation")
|
||||
for(var/obj/effect/rune/R in range(5,owner))
|
||||
R.conceal()
|
||||
for(var/obj/structure/destructible/cult/S in range(5,owner))
|
||||
@@ -311,7 +311,7 @@
|
||||
owner.visible_message(span_warning("A flash of light shines from [owner]'s hand!"), \
|
||||
span_cult_italic("You invoke the counterspell, revealing nearby runes."))
|
||||
charges--
|
||||
owner.whisper(invocation, language = /datum/language/common)
|
||||
owner.whisper(invocation, language = /datum/language/common, forced = "cult invocation")
|
||||
SEND_SOUND(owner, sound('sound/effects/magic/enter_blood.ogg',0,1,25))
|
||||
for(var/obj/effect/rune/R in range(7,owner)) //More range in case you weren't standing in exactly the same spot
|
||||
R.reveal()
|
||||
@@ -413,7 +413,7 @@
|
||||
|
||||
/obj/item/melee/blood_magic/proc/cast_spell(atom/target, mob/living/carbon/user)
|
||||
if(invocation)
|
||||
user.whisper(invocation, language = /datum/language/common)
|
||||
user.whisper(invocation, language = /datum/language/common, forced = "cult invocation")
|
||||
if(health_cost)
|
||||
if(user.active_hand_index == 1)
|
||||
user.apply_damage(health_cost, BRUTE, BODY_ZONE_L_ARM, wound_bonus = CANT_WOUND)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
var/my_message
|
||||
if(!message || !user.mind)
|
||||
return
|
||||
user.whisper("O bidai nabora se[pick("'","`")]sma!", language = /datum/language/common)
|
||||
user.whisper("O bidai nabora se[pick("'","`")]sma!", language = /datum/language/common, forced = "cult invocation")
|
||||
user.whisper(html_decode(message), filterproof = TRUE)
|
||||
var/title = "Acolyte"
|
||||
var/span = "cult italic"
|
||||
|
||||
@@ -83,3 +83,21 @@
|
||||
|
||||
/datum/preference/choiced/language_skill/apply_to_human(mob/living/carbon/human/target, value)
|
||||
return
|
||||
|
||||
/datum/preference/choiced/csl_strength
|
||||
category = PREFERENCE_CATEGORY_MANUALLY_RENDERED
|
||||
savefile_key = "csl_strength"
|
||||
savefile_identifier = PREFERENCE_CHARACTER
|
||||
can_randomize = FALSE
|
||||
|
||||
/datum/preference/choiced/csl_strength/create_default_value()
|
||||
return "90%"
|
||||
|
||||
/datum/preference/choiced/csl_strength/is_accessible(datum/preferences/preferences)
|
||||
return ..() && (/datum/quirk/csl::name in preferences.all_quirks)
|
||||
|
||||
/datum/preference/choiced/csl_strength/init_possible_values()
|
||||
return list("90%", "75%", "50%", "33%", "25%", "10%")
|
||||
|
||||
/datum/preference/choiced/csl_strength/apply_to_human(mob/living/carbon/human/target, value)
|
||||
return
|
||||
|
||||
@@ -225,6 +225,22 @@
|
||||
if(length(last_sentence_cache) > SENTENCE_CACHE_LEN)
|
||||
last_sentence_cache.Cut(1, last_sentence_cache.len - SENTENCE_CACHE_LEN + 1)
|
||||
|
||||
/**
|
||||
* Scramble a paragraph in this language.
|
||||
*
|
||||
* Takes into account any languages the hearer knows that has mutual understanding with this language.
|
||||
*/
|
||||
/datum/language/proc/scramble_paragraph(input, list/mutual_languages)
|
||||
// perfect understanding, no need to scramble
|
||||
if(mutual_languages?[type] >= 100)
|
||||
return input
|
||||
|
||||
var/static/regex/first_sentence = regex(@"(.+?(?:[\.!\?]|$))", "g")
|
||||
var/list/new_paragraph = list()
|
||||
while(first_sentence.Find(input))
|
||||
new_paragraph += scramble_sentence(trim(first_sentence.group[1]), mutual_languages)
|
||||
return jointext(new_paragraph, " ")
|
||||
|
||||
/**
|
||||
* Scrambles a sentence in this language.
|
||||
*
|
||||
@@ -232,39 +248,54 @@
|
||||
*/
|
||||
/datum/language/proc/scramble_sentence(input, list/mutual_languages)
|
||||
var/cache_key = "[mutual_languages?[type] || 0]-understanding"
|
||||
var/list/cache = read_sentence_cache(cache_key)
|
||||
var/list/cache = read_sentence_cache(input)
|
||||
if(cache?[cache_key])
|
||||
return cache[cache_key]
|
||||
|
||||
var/list/real_words = splittext(input, " ")
|
||||
// List of words that will be recombined into a sentence
|
||||
var/list/scrambled_words = list()
|
||||
for(var/word in real_words)
|
||||
// List which indexes correspond to words in scrambled_words, records whether the word was translated
|
||||
// Can't be a single assoc list because duplicates are expected
|
||||
var/list/translated_index = list()
|
||||
for(var/word in splittext(input, " "))
|
||||
var/translate_prob = mutual_languages?[type] || 0
|
||||
var/base_word = strip_outer_punctuation(word)
|
||||
if(translate_prob > 0)
|
||||
// the probability of managing to understand a word is based on how common it is
|
||||
// 1000 words in the list, so words outside the list are just treated as "the 1500th most common word"
|
||||
var/commonness = GLOB.most_common_words[LOWER_TEXT(base_word)] || 1500
|
||||
translate_prob += (translate_prob * 0.2 * (1 - (min(commonness, 1500) / 500)))
|
||||
// the probability of managing to understand a word is based on how common it is (+10%, -15%)
|
||||
// 1000 words in the list, so words outside the list are just treated as "the 1250th most common word"
|
||||
var/commonness = GLOB.most_common_words[LOWER_TEXT(base_word)] || 1250
|
||||
translate_prob += (10 * (1 - (min(commonness, 1250) / 500)))
|
||||
if(prob(translate_prob))
|
||||
scrambled_words += base_word
|
||||
scrambled_words += word
|
||||
translated_index += FALSE
|
||||
continue
|
||||
|
||||
scrambled_words += scramble_word(base_word)
|
||||
var/scrambled_word = scramble_word(base_word)
|
||||
scrambled_words += scrambled_word
|
||||
translated_index += (scrambled_word != base_word)
|
||||
|
||||
// start building the new sentence. first word is capitalized and otherwise untouched
|
||||
var/sentence = capitalize(popleft(scrambled_words))
|
||||
for(var/word in scrambled_words)
|
||||
if(prob(between_word_sentence_chance))
|
||||
var/sentence = capitalize(scrambled_words[1])
|
||||
for(var/i in 2 to length(scrambled_words))
|
||||
var/word = scrambled_words[i]
|
||||
// this was not translated so just throw it in
|
||||
if(!translated_index[i])
|
||||
sentence += " [word]"
|
||||
continue
|
||||
// if the last word was scrambled, always include a space
|
||||
if(translated_index[i - 1] || prob(between_word_space_chance))
|
||||
sentence += " "
|
||||
// lastly try inserting a new sentence
|
||||
else if(prob(between_word_sentence_chance))
|
||||
sentence += ". "
|
||||
word = capitalize(word)
|
||||
else if(prob(between_word_space_chance))
|
||||
sentence += " "
|
||||
|
||||
sentence += word
|
||||
|
||||
// scrambling the words will drop punctuation, so re-add it at the end
|
||||
sentence += find_last_punctuation(input)
|
||||
// scrambling the word will drop punctuation, so we need to re-add it at the end
|
||||
// (however we don't need to do anything if the last word was not translated)
|
||||
if(translated_index[length(scrambled_words)])
|
||||
sentence += find_last_punctuation(input)
|
||||
|
||||
write_sentence_cache(input, cache_key, sentence)
|
||||
|
||||
|
||||
@@ -435,16 +435,15 @@
|
||||
taste_sensitivity = 32
|
||||
liked_foodtypes = GROSS | MEAT | RAW | GORE
|
||||
disliked_foodtypes = NONE
|
||||
|
||||
// List of english words that translate to zombie phrases
|
||||
GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
// List of english words that translate to zombie phrases
|
||||
var/static/list/english_to_zombie = list()
|
||||
|
||||
/obj/item/organ/tongue/zombie/proc/add_word_to_translations(english_word, zombie_word)
|
||||
GLOB.english_to_zombie[english_word] = zombie_word
|
||||
english_to_zombie[english_word] = zombie_word
|
||||
// zombies don't care about grammar (any tense or form is all translated to the same word)
|
||||
GLOB.english_to_zombie[english_word + plural_s(english_word)] = zombie_word
|
||||
GLOB.english_to_zombie[english_word + "ing"] = zombie_word
|
||||
GLOB.english_to_zombie[english_word + "ed"] = zombie_word
|
||||
english_to_zombie[english_word + plural_s(english_word)] = zombie_word
|
||||
english_to_zombie[english_word + "ing"] = zombie_word
|
||||
english_to_zombie[english_word + "ed"] = zombie_word
|
||||
|
||||
/obj/item/organ/tongue/zombie/proc/load_zombie_translations()
|
||||
var/list/zombie_translation = strings("zombie_replacement.json", "zombie")
|
||||
@@ -453,20 +452,20 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
var/list/data = islist(zombie_translation[zombie_word]) ? zombie_translation[zombie_word] : list(zombie_translation[zombie_word])
|
||||
for(var/english_word in data)
|
||||
add_word_to_translations(english_word, zombie_word)
|
||||
GLOB.english_to_zombie = sort_list(GLOB.english_to_zombie) // Alphabetizes the list (for debugging)
|
||||
english_to_zombie = sort_list(english_to_zombie) // Alphabetizes the list (for debugging)
|
||||
|
||||
/obj/item/organ/tongue/zombie/modify_speech(datum/source, list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
if(message[1] != "*")
|
||||
// setup the global list for translation if it hasn't already been done
|
||||
if(!length(GLOB.english_to_zombie))
|
||||
if(!length(english_to_zombie))
|
||||
load_zombie_translations()
|
||||
|
||||
// make a list of all words that can be translated
|
||||
var/list/message_word_list = splittext(message, " ")
|
||||
var/list/translated_word_list = list()
|
||||
for(var/word in message_word_list)
|
||||
word = GLOB.english_to_zombie[LOWER_TEXT(word)]
|
||||
word = english_to_zombie[LOWER_TEXT(word)]
|
||||
translated_word_list += word ? word : FALSE
|
||||
|
||||
// all occurrences of characters "eiou" (case-insensitive) are replaced with "r"
|
||||
@@ -501,6 +500,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
|
||||
modifies_speech = TRUE // not really, they just hiss
|
||||
voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.8,aresample=%SAMPLE_RATE%,atempo=1/0.8,aformat=channel_layouts=mono [p0]; [out2] asetrate=%SAMPLE_RATE%*1.2,aresample=%SAMPLE_RATE%,atempo=1/1.2,aformat=channel_layouts=mono[p2]; [p0][0][p2] amix=inputs=3"}
|
||||
|
||||
// Aliens can only speak alien and a few other languages.
|
||||
/obj/item/organ/tongue/alien/get_possible_languages()
|
||||
return list(
|
||||
@@ -557,6 +557,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
modifies_speech = FALSE
|
||||
liked_foodtypes = VEGETABLES
|
||||
disliked_foodtypes = FRUIT | CLOTH
|
||||
languages_native = list(/datum/language/calcic)
|
||||
|
||||
/obj/item/organ/tongue/robot
|
||||
name = "robotic voicebox"
|
||||
@@ -611,6 +612,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
attack_verb_continuous = list("shocks", "jolts", "zaps")
|
||||
attack_verb_simple = list("shock", "jolt", "zap")
|
||||
voice_filter = @{"[0:a] asplit [out0][out2]; [out0] asetrate=%SAMPLE_RATE%*0.99,aresample=%SAMPLE_RATE%,volume=0.3 [p0]; [p0][out2] amix=inputs=2"}
|
||||
languages_native = list(/datum/language/voltaic)
|
||||
|
||||
// Ethereal tongues can speak all default + voltaic
|
||||
/obj/item/organ/tongue/ethereal/get_possible_languages()
|
||||
@@ -623,6 +625,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
liked_foodtypes = SEAFOOD | ORANGES | BUGS | GORE
|
||||
disliked_foodtypes = GROSS | CLOTH | RAW
|
||||
organ_traits = list(TRAIT_WOUND_LICKER, TRAIT_FISH_EATER)
|
||||
languages_native = list(/datum/language/nekomimetic)
|
||||
|
||||
/obj/item/organ/tongue/jelly
|
||||
name = "jelly tongue"
|
||||
@@ -631,6 +634,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
liked_foodtypes = MEAT | BUGS
|
||||
disliked_foodtypes = GROSS
|
||||
toxic_foodtypes = NONE
|
||||
languages_native = list(/datum/language/slime)
|
||||
|
||||
/obj/item/organ/tongue/jelly/get_food_taste_reaction(obj/item/food, foodtypes = NONE)
|
||||
// a silver slime created this? what a delicacy!
|
||||
@@ -644,6 +648,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
say_mod = "chimpers"
|
||||
liked_foodtypes = MEAT | FRUIT | BUGS
|
||||
disliked_foodtypes = CLOTH
|
||||
languages_native = list(/datum/language/monkey)
|
||||
|
||||
/obj/item/organ/tongue/moth
|
||||
name = "moth tongue"
|
||||
@@ -652,11 +657,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
liked_foodtypes = VEGETABLES | DAIRY | CLOTH
|
||||
disliked_foodtypes = FRUIT | GROSS | BUGS | GORE
|
||||
toxic_foodtypes = MEAT | RAW | SEAFOOD
|
||||
|
||||
/obj/item/organ/tongue/zombie
|
||||
name = "rotting tongue"
|
||||
desc = "Makes you speak like you're at the dentist and you just absolutely refuse to spit because you forgot to mention you were allergic to space shellfish."
|
||||
say_mod = "moans"
|
||||
languages_native = list(/datum/language/moffic)
|
||||
|
||||
/obj/item/organ/tongue/mush
|
||||
name = "mush-tongue-room"
|
||||
@@ -664,6 +665,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
icon = 'icons/obj/service/hydroponics/seeds.dmi'
|
||||
icon_state = "mycelium-angel"
|
||||
say_mod = "poofs"
|
||||
languages_native = list(/datum/language/mushroom)
|
||||
|
||||
/obj/item/organ/tongue/pod
|
||||
name = "pod tongue"
|
||||
@@ -673,6 +675,7 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
disliked_foodtypes = GORE | MEAT | DAIRY | SEAFOOD | BUGS
|
||||
foodtype_flags = PODPERSON_ORGAN_FOODTYPES
|
||||
color = COLOR_LIME
|
||||
languages_native = list(/datum/language/sylvan)
|
||||
|
||||
/obj/item/organ/tongue/golem
|
||||
name = "golem tongue"
|
||||
@@ -684,3 +687,4 @@ GLOBAL_LIST_INIT(english_to_zombie, list())
|
||||
liked_foodtypes = STONE
|
||||
disliked_foodtypes = NONE //you don't care for much else besides stone
|
||||
toxic_foodtypes = NONE //you can eat fucking uranium
|
||||
languages_native = list(/datum/language/terrum)
|
||||
|
||||
@@ -1941,6 +1941,7 @@
|
||||
#include "code\datums\quirks\negative_quirks\chronic_illness.dm"
|
||||
#include "code\datums\quirks\negative_quirks\claustrophobia.dm"
|
||||
#include "code\datums\quirks\negative_quirks\clumsy.dm"
|
||||
#include "code\datums\quirks\negative_quirks\csl.dm"
|
||||
#include "code\datums\quirks\negative_quirks\cursed.dm"
|
||||
#include "code\datums\quirks\negative_quirks\deafness.dm"
|
||||
#include "code\datums\quirks\negative_quirks\depression.dm"
|
||||
|
||||
+6
@@ -21,3 +21,9 @@ export const language_skill: FeatureChoiced = {
|
||||
description: 'The percentage of the language you can understand.',
|
||||
component: FeatureDropdownInput,
|
||||
};
|
||||
|
||||
export const csl_strength: FeatureChoiced = {
|
||||
name: 'Language Skill',
|
||||
description: 'The percentage of Common you can understand.',
|
||||
component: FeatureDropdownInput,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user