Merge pull request #4030 from VOREStation/upstream-merge-5402

[MIRROR] Language and Larynx Additions
This commit is contained in:
Aronai Sieyes
2018-07-21 14:43:47 -04:00
committed by GitHub
37 changed files with 358 additions and 186 deletions

View File

@@ -116,22 +116,28 @@
path = /obj/item/weapon/cell/device
/datum/gear/utility/implant
exploitable = 1
/* VOREStation Edit - Make languages great again
/datum/gear/utility/implant/eal //This does nothing if you don't actually know EAL.
display_name = "implant, language, EAL"
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
exploitable = 1*/
exploitable = 1
/datum/gear/utility/implant/tracking
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 0 //VOREStation Edit. Changed cost to 0
slot = "implant"
exploitable = 1
/* VOREStation Edit - Make languages great again
/datum/gear/utility/implant/language
cost = 2
exploitable = 0
/datum/gear/utility/implant/language/eal
display_name = "vocal synthesizer, EAL"
description = "A surgically implanted vocal synthesizer which allows the owner to speak EAL, if they know it."
path = /obj/item/weapon/implant/language/eal
/datum/gear/utility/implant/language/skrellian
display_name = "vocal synthesizer, Skrellian"
description = "A surgically implanted vocal synthesizer which allows the owner to speak Common Skrellian, if they know it."
path = /obj/item/weapon/implant/language/skrellian
*/
/datum/gear/utility/pen
display_name = "Fountain Pen"
path = /obj/item/weapon/pen/fountain

View File

@@ -133,6 +133,6 @@
key = "s"
flags = SIGNLANG|NO_STUTTER|NONVERBAL
/datum/language/sign/can_speak_special(var/mob/speaker)
/datum/language/sign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
return (hands || !iscarbon(speaker))

View File

@@ -133,7 +133,15 @@
return speech_verb
/datum/language/proc/can_speak_special(var/mob/speaker)
return 1
. = TRUE
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(src.name in H.species.assisted_langs)
. = FALSE
var/obj/item/organ/internal/voicebox/vox = locate() in H.internal_organs // Only voiceboxes for now. Maybe someday it'll include other organs, but I'm not that clever
if(vox)
if(!vox.is_broken() && (src in vox.assists_languages))
. = TRUE
// Language handling.
/mob/proc/add_language(var/language)

View File

@@ -63,6 +63,14 @@
"ka","aasi","far","wa","baq","ara","qara","zir","saam","mak","hrar","nja","rir","khan","jun","dar","rik","kah",
"hal","ket","jurl","mah","tul","cresh","azu","ragh","mro","mra","mrro","mrra")
/datum/language/tajaran/get_random_name(var/gender)
var/new_name = ..(gender,1)
if(prob(50))
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
else
new_name += " [..(gender,1)]"
return new_name
/datum/language/tajaranakhani
name = LANGUAGE_AKHANI
desc = "The language of the sea-faring Njarir'Akhan Tajaran. Borrowing some elements from Siik, the language is distinctly more structured."
@@ -77,15 +85,6 @@
"kar","yar","kzar","rha","hrar","err","fer","rir","rar","yarr","arr","ii'r","jar","kur","ran","rii","ii",
"nai","ou","kah","oa","ama","uuk","bel","chi","ayt","kay","kas","akor","tam","yir","enai")
/datum/language/tajaran/get_random_name(var/gender)
var/new_name = ..(gender,1)
if(prob(50))
new_name += " [pick(list("Hadii","Kaytam","Nazkiin","Zhan-Khazan","Hharar","Njarir'Akhan","Faaira'Nrezi","Rhezar","Mi'dynh","Rrhazkal","Bayan","Al'Manq","Mi'jri","Chur'eech","Sanu'dra","Ii'rka"))]"
else
new_name += " [..(gender,1)]"
return new_name
/datum/language/tajsign
name = LANGUAGE_ALAI
desc = "A standardized Tajaran sign language that was developed in Zarraya and gradually adopted by other nations, incorporating \
@@ -95,6 +94,19 @@
key = "l"
flags = WHITELISTED | SIGNLANG | NO_STUTTER | NONVERBAL
/datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format
var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this.
if(iscarbon(speaker))
var/obj/item/organ/external/hand/hands = locate() in speaker //you can't sign without hands
if(!hands)
return FALSE
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
if(H.species.get_bodytype(H) in allowed_species)
return TRUE
return FALSE
/datum/language/skrell
name = LANGUAGE_SKRELLIAN
desc = "A set of warbles and hums, the language itself a complex mesh of both melodic and rhythmic components, exceptionally capable of conveying intent and emotion of the speaker."
@@ -161,11 +173,6 @@
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz","shh","shk")
space_chance = 10
/datum/language/machine/can_speak_special(var/mob/speaker)
var/obj/item/weapon/implant/language/eal/beep = locate() in speaker
return ((beep && beep.implanted) || speaker.isSynthetic() || isvoice(speaker))
//thank you sweet zuhayr
/datum/language/machine/get_random_name()
if(prob(70))
return "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"

View File

@@ -14,9 +14,10 @@
var/muzzled = is_muzzled()
//var/m_type = 1
for (var/obj/item/weapon/implant/I in src)
if (I.implanted)
I.trigger(act, src)
for(var/obj/item/organ/O in src.organs)
for (var/obj/item/weapon/implant/I in O)
if (I.implanted)
I.trigger(act, src)
if(src.stat == 2.0 && (act != "deathgasp"))
return

View File

@@ -166,25 +166,12 @@
update |= temp.take_damage(b_loss * 0.05, f_loss * 0.05, used_weapon = weapon_message)
if(update) UpdateDamageIcon()
/mob/living/carbon/human/proc/implant_loadout(var/datum/gear/G = new/datum/gear/utility/implant)
var/obj/item/weapon/implant/I = new G.path(src)
I.imp_in = src
I.implanted = 1
var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD]
affected.implants += I
I.part = affected
I.implanted(src)
/mob/living/carbon/human/proc/implant_loyalty(override = FALSE) // Won't override by default.
if(!config.use_loyalty_implants && !override) return // Nuh-uh.
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(src)
L.imp_in = src
L.implanted = 1
var/obj/item/organ/external/affected = src.organs_by_name[BP_HEAD]
affected.implants += L
L.part = affected
L.implanted(src)
if(L.handle_implant(src, BP_HEAD))
L.post_implant(src)
/mob/living/carbon/human/proc/is_loyalty_implanted()
for(var/L in src.contents)
@@ -1139,6 +1126,8 @@
remove_language(species.language)
if(species.default_language)
remove_language(species.default_language)
for(var/datum/language/L in species.assisted_langs)
remove_language(L)
// Clear out their species abilities.
species.remove_inherent_verbs(src)
holder_type = null

View File

@@ -70,6 +70,7 @@ Variables you may want to make use of are:
num_alternate_languages = 3
species_language = LANGUAGE_GALCOM
secondary_langs = list()
assisted_langs = list()
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 0

View File

@@ -25,6 +25,8 @@
genders = list(NEUTER)
assisted_langs = list()
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
spawn(1)
new /obj/effect/decal/cleanable/ash(H.loc)

View File

@@ -7,6 +7,7 @@
language = LANGUAGE_GALCOM
species_language = LANGUAGE_VOX
num_alternate_languages = 1
assisted_langs = list(LANGUAGE_ROOTGLOBAL)
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
rarity_value = 4
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
@@ -71,6 +72,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart/vox,
O_LUNGS = /obj/item/organ/internal/lungs/vox,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver/vox,
O_KIDNEYS = /obj/item/organ/internal/kidneys/vox,
O_BRAIN = /obj/item/organ/internal/brain/vox,

View File

@@ -52,13 +52,17 @@
// Language/culture vars.
var/default_language = LANGUAGE_GALCOM // Default language is used when 'say' is used without modifiers.
var/language = LANGUAGE_GALCOM // Default racial language, if any.
var/species_language = LANGUAGE_GALCOM // Used on the Character Setup screen
var/list/species_language = list(LANGUAGE_GALCOM) // Used on the Character Setup screen
var/list/secondary_langs = list() // The names of secondary languages that are available to this species.
var/list/speech_sounds = list() // A list of sounds to potentially play when speaking.
var/list/speech_chance = list() // The likelihood of a speech sound playing.
var/num_alternate_languages = 0 // How many secondary languages are available to select at character creation
var/name_language = LANGUAGE_GALCOM // The language to use when determining names for this species, or null to use the first name/last name generator
// The languages the species can't speak without an assisted organ.
// This list is a guess at things that no one other than the parent species should be able to speak
var/list/assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
//Soundy emotey things.
var/scream_verb = "screams"
var/male_scream_sound //= 'sound/goonstation/voice/male_scream.ogg' Removed due to licensing, replace!
@@ -183,6 +187,7 @@
var/list/has_organ = list( // which required-organ checks are conducted.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,

View File

@@ -11,6 +11,8 @@
spawn_flags = SPECIES_IS_RESTRICTED
siemens_coefficient = 0
assisted_langs = list()
breath_type = null
poison_type = null

View File

@@ -45,6 +45,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,

View File

@@ -30,6 +30,7 @@ var/datum/species/shapeshifter/promethean/prometheans
health_hud_intensity = 2
num_alternate_languages = 3
species_language = LANGUAGE_SOL_COMMON
assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language.
breath_type = null
poison_type = null

View File

@@ -104,6 +104,7 @@
has_organ = list(
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,

View File

@@ -12,6 +12,7 @@
species_language = LANGUAGE_SOL_COMMON
secondary_langs = list(LANGUAGE_SOL_COMMON, LANGUAGE_TERMINUS)
name_language = null // Use the first-name last-name generator rather than a language scrambler
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_SKRELLIAN, LANGUAGE_SKRELLIANFAR, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
min_age = 17
max_age = 130
@@ -217,6 +218,7 @@
has_organ = list( //No appendix.
O_HEART = /obj/item/organ/internal/heart,
O_LUNGS = /obj/item/organ/internal/lungs,
O_VOICE = /obj/item/organ/internal/voicebox,
O_LIVER = /obj/item/organ/internal/liver,
O_KIDNEYS = /obj/item/organ/internal/kidneys,
O_BRAIN = /obj/item/organ/internal/brain,
@@ -243,6 +245,7 @@
secondary_langs = list(LANGUAGE_SKRELLIAN, LANGUAGE_SCHECHI)
name_language = LANGUAGE_SKRELLIAN
species_language = LANGUAGE_SKRELLIAN
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_TERMINUS, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
health_hud_intensity = 2
water_movement = -3
@@ -317,13 +320,14 @@
hud_type = /datum/hud_data/diona
siemens_coefficient = 0.3
show_ssd = "completely quiescent"
num_alternate_languages = 2
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
name_language = LANGUAGE_ROOTLOCAL
species_language = LANGUAGE_ROOTLOCAL
health_hud_intensity = 2.5
item_slowdown_mod = 0.25
num_alternate_languages = 2
name_language = LANGUAGE_ROOTLOCAL
species_language = LANGUAGE_ROOTLOCAL
secondary_langs = list(LANGUAGE_ROOTGLOBAL)
assisted_langs = list(LANGUAGE_VOX) // Diona are weird, let's just assume they can use basically any language.
min_age = 1
max_age = 300

View File

@@ -16,6 +16,8 @@
speech_bubble_appearance = "cyber"
assisted_langs = list()
male_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
female_cough_sounds = list('sound/effects/mob_effects/f_cougha.ogg','sound/effects/mob_effects/f_coughb.ogg')
male_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg'

View File

@@ -5,6 +5,7 @@
default_language = "Xenomorph"
language = "Hivemind"
assisted_langs = list()
unarmed_types = list(/datum/unarmed_attack/claws/strong/xeno, /datum/unarmed_attack/bite/strong/xeno)
hud_type = /datum/hud_data/alien
rarity_value = 3

View File

@@ -0,0 +1,42 @@
/*
* Voicebox/Vocal Synthesizers
* TL;DR: Assists with speaking languages that a species doesn't normally have,
* such as EAL. Not standard or organic, because at the moment it's undesireable to completely mute characters.
*/
/obj/item/organ/internal/voicebox
name = "larynx"
icon_state = "larynx"
parent_organ = BP_TORSO // We don't have a neck area
organ_tag = O_VOICE
will_assist_languages = list(LANGUAGE_GALCOM)
/obj/item/organ/internal/voicebox/New()
..()
amend_assist_langs()
/obj/item/organ/internal/voicebox/proc/amend_assist_langs() // Adds the list of language datums assisted by the voicebox to the list used in speaking
for(var/L in will_assist_languages)
assists_languages |= all_languages[L]
/obj/item/organ/internal/voicebox/proc/add_assistable_langs(var/language) // Adds a new language (by string/define) to the list of things the voicebox can assist
will_assist_languages |= language
amend_assist_langs() // Can't think of a better place to put this, makes the voicebox actually start to assist with the added language
/////////////////////////////////
// Voicebox Subtypes
/////////////////////////////////
/obj/item/organ/internal/voicebox/assist // In the off chance we get a species that doesn't speak GalCom by default
/obj/item/organ/internal/voicebox/assist/New()
..()
mechassist()
/obj/item/organ/internal/voicebox/robot
name = "vocal synthesizer"
will_assist_languages = list(LANGUAGE_GALCOM, LANGUAGE_EAL) // Synthetics spawn with this by default
/obj/item/organ/internal/voicebox/robot/New()
..()
robotize()

View File

@@ -31,6 +31,10 @@ var/list/organ_cache = list()
var/rejecting // Is this organ already being rejected?
var/preserved = 0 // If this is 1, prevents organ decay.
// Language vars. Putting them here in case we decide to do something crazy with sign-or-other-nonverbal languages.
var/list/will_assist_languages = list()
var/list/datum/language/assists_languages = list()
/obj/item/organ/Destroy()
if(owner) owner = null

View File

@@ -23,10 +23,11 @@
organ_rel_size = 70
base_miss_chance = 10
/obj/item/organ/external/chest/robotize(var/company, var/skip_prosthetics = 0, var/keep_organs = 0)
/obj/item/organ/external/chest/robotize()
if(..() && robotic != ORGAN_NANOFORM) //VOREStation Edit
// Give them a new cell.
owner.internal_organs_by_name["cell"] = new /obj/item/organ/internal/cell(owner,1)
// Give them fancy new organs.
owner.internal_organs_by_name[O_CELL] = new /obj/item/organ/internal/cell(owner,1)
owner.internal_organs_by_name[O_VOICE] = new /obj/item/organ/internal/voicebox/robot(owner, 1)
/obj/item/organ/external/chest/handle_germ_effects()
. = ..() //Should return an infection level

View File

@@ -27,13 +27,9 @@
SStranscore.implants -= src
return ..()
/obj/item/weapon/implant/backup/implanted(var/mob/living/carbon/human/H)
..()
/obj/item/weapon/implant/backup/post_implant(var/mob/living/carbon/human/H)
if(istype(H))
var/obj/item/weapon/implant/backup/other_imp = locate(/obj/item/weapon/implant/backup,H)
if(other_imp && other_imp.imp_in == H)
qdel(other_imp) //implant fight
BITSET(H.hud_updateflag, BACKUP_HUD)
SStranscore.implants |= src
return 1
@@ -107,18 +103,10 @@
M.visible_message("<span class='notice'>[M] has been backup implanted by [user].</span>")
var/obj/item/weapon/implant/backup/imp = imps[imps.len]
if(imp.implanted(M))
imp.forceMove(M)
if(imp.handle_implant(M,user.zone_sel.selecting))
imp.post_implant(M)
imps -= imp
imp.imp_in = M
imp.implanted = 1
add_attack_logs(user,M,"Implanted backup implant")
if (ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affected = H.get_organ(user.zone_sel.selecting)
affected.implants += imp
imp.part = affected
BITSET(H.hud_updateflag, BACKUP_HUD)
update()

View File

@@ -538,14 +538,8 @@
//Give them a backup implant
var/obj/item/weapon/implant/backup/new_imp = new()
if(new_imp.implanted(occupant))
new_imp.loc = occupant
new_imp.imp_in = occupant
new_imp.implanted = 1
//Put it in the head! Makes sense.
var/obj/item/organ/external/affected = occupant.get_organ(BP_HEAD)
affected.implants += new_imp
new_imp.part = affected
if(new_imp.handle_implant(occupant, BP_HEAD))
new_imp.post_implant(occupant)
//Inform them and make them a little dizzy.
if(confuse_amount + blur_amount <= 16)

View File

@@ -725,7 +725,7 @@
random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_roiz
/obj/item/weapon/implant/reagent_generator/roiz/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/roiz/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc
@@ -793,7 +793,7 @@
random_emote = list("hisses softly with a blush on her face", "bites down on her lower lip", "lets out a light huff")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_jasmine
/obj/item/weapon/implant/reagent_generator/jasmine/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/jasmine/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc
@@ -861,7 +861,7 @@
random_emote = list("hisses softly with a blush on her face", "yelps in embarrassment", "grunts a little")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_yonra
/obj/item/weapon/implant/reagent_generator/yonra/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/yonra/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc
@@ -945,7 +945,7 @@
random_emote = list("trembles and huffs, panting from the exertion.", "sees what has happened and covers her face with both hands!", "whimpers softly, her legs shivering, knees pointed inward from the feeling.")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_rischi
/obj/item/weapon/implant/reagent_generator/rischi/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/rischi/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc
@@ -1011,7 +1011,7 @@
self_emote_descriptor = list("grab", "pick", "snatch")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_pumila_apple
/obj/item/weapon/implant/reagent_generator/pumila_apple/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/pumila_apple/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc
@@ -1704,7 +1704,7 @@
random_emote = list("hisses softly with a blush on his face", "yelps in embarrassment", "grunts a little")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_evian
/obj/item/weapon/implant/reagent_generator/evian/implanted(mob/living/carbon/source)
/obj/item/weapon/implant/reagent_generator/evian/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc