mirror of
https://github.com/fulpstation/fulpstation.git
synced 2025-12-10 10:01:40 +00:00
Refactors language holder (#48106)
* Language holder refactor * Ironed out bugs, testing * adds sourced language, blocking list. more useful helpers. * Replaced old usage * Adresses requests * Autodoc attempt #1 * Fixed monkeyize (again) * Travis happy * Language menu updated * Final pass
This commit is contained in:
@@ -3,5 +3,21 @@
|
|||||||
#define LANGUAGE_HIDE_ICON_IF_UNDERSTOOD 4
|
#define LANGUAGE_HIDE_ICON_IF_UNDERSTOOD 4
|
||||||
#define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8
|
#define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8
|
||||||
|
|
||||||
#define LANGUAGE_KNOWN "language_known"
|
// LANGUAGE SOURCE DEFINES
|
||||||
#define LANGUAGE_SHADOWED "language_shadowed"
|
#define LANGUAGE_ALL "all" // For use in full removal only.
|
||||||
|
#define LANGUAGE_ATOM "atom"
|
||||||
|
#define LANGUAGE_MIND "mind"
|
||||||
|
|
||||||
|
#define LANGUAGE_ABSORB "absorb"
|
||||||
|
#define LANGUAGE_APHASIA "aphasia"
|
||||||
|
#define LANGUAGE_CULTIST "cultist"
|
||||||
|
#define LANGUAGE_CURATOR "curator"
|
||||||
|
#define LANGUAGE_DEVIL "devil"
|
||||||
|
#define LANGUAGE_GLAND "gland"
|
||||||
|
#define LANGUAGE_HAT "hat"
|
||||||
|
#define LANGUAGE_HIGH "high"
|
||||||
|
#define LANGUAGE_MALF "malf"
|
||||||
|
#define LANGUAGE_MASTER "master"
|
||||||
|
#define LANGUAGE_SOFTWARE "software"
|
||||||
|
#define LANGUAGE_STONER "stoner"
|
||||||
|
#define LANGUAGE_VOICECHANGE "voicechange"
|
||||||
|
|||||||
@@ -91,7 +91,6 @@
|
|||||||
|
|
||||||
trauma = _trauma
|
trauma = _trauma
|
||||||
owner = trauma.owner
|
owner = trauma.owner
|
||||||
copy_known_languages_from(owner, TRUE)
|
|
||||||
|
|
||||||
setup_friend()
|
setup_friend()
|
||||||
|
|
||||||
|
|||||||
@@ -26,21 +26,15 @@
|
|||||||
scan_desc = "extensive damage to the brain's language center"
|
scan_desc = "extensive damage to the brain's language center"
|
||||||
gain_text = "<span class='warning'>You have trouble forming words in your head...</span>"
|
gain_text = "<span class='warning'>You have trouble forming words in your head...</span>"
|
||||||
lose_text = "<span class='notice'>You suddenly remember how languages work.</span>"
|
lose_text = "<span class='notice'>You suddenly remember how languages work.</span>"
|
||||||
var/datum/language_holder/prev_language
|
|
||||||
var/datum/language_holder/mob_language
|
|
||||||
|
|
||||||
/datum/brain_trauma/severe/aphasia/on_gain()
|
/datum/brain_trauma/severe/aphasia/on_gain()
|
||||||
mob_language = owner.get_language_holder()
|
owner.add_blocked_language(subtypesof(/datum/language/) - /datum/language/aphasia, LANGUAGE_APHASIA)
|
||||||
prev_language = mob_language.copy()
|
owner.grant_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA)
|
||||||
mob_language.remove_all_languages()
|
|
||||||
mob_language.grant_language(/datum/language/aphasia)
|
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/datum/brain_trauma/severe/aphasia/on_lose()
|
/datum/brain_trauma/severe/aphasia/on_lose()
|
||||||
mob_language.remove_language(/datum/language/aphasia)
|
owner.remove_blocked_language(subtypesof(/datum/language/), LANGUAGE_APHASIA)
|
||||||
mob_language.copy_known_languages_from(prev_language) //this will also preserve languages learned during the trauma
|
owner.remove_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA)
|
||||||
QDEL_NULL(prev_language)
|
|
||||||
mob_language = null
|
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/datum/brain_trauma/severe/blindness
|
/datum/brain_trauma/severe/blindness
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ Bonus
|
|||||||
symptom_delay_max = 120
|
symptom_delay_max = 120
|
||||||
var/scramble_language = FALSE
|
var/scramble_language = FALSE
|
||||||
var/datum/language/current_language
|
var/datum/language/current_language
|
||||||
var/datum/language_holder/original_language
|
|
||||||
var/datum/language_holder/mob_language
|
|
||||||
threshold_descs = list(
|
threshold_descs = list(
|
||||||
"Transmission 14" = "The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.",
|
"Transmission 14" = "The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.",
|
||||||
"Stage Speed 7" = "Changes voice more often.",
|
"Stage Speed 7" = "Changes voice more often.",
|
||||||
@@ -49,9 +47,6 @@ Bonus
|
|||||||
symptom_delay_max = 85
|
symptom_delay_max = 85
|
||||||
if(A.properties["transmittable"] >= 14) //random language
|
if(A.properties["transmittable"] >= 14) //random language
|
||||||
scramble_language = TRUE
|
scramble_language = TRUE
|
||||||
var/mob/living/M = A.affected_mob
|
|
||||||
mob_language = M.get_language_holder()
|
|
||||||
original_language = mob_language.copy()
|
|
||||||
|
|
||||||
/datum/symptom/voice_change/Activate(datum/disease/advance/A)
|
/datum/symptom/voice_change/Activate(datum/disease/advance/A)
|
||||||
if(!..())
|
if(!..())
|
||||||
@@ -65,12 +60,10 @@ Bonus
|
|||||||
if(ishuman(M))
|
if(ishuman(M))
|
||||||
var/mob/living/carbon/human/H = M
|
var/mob/living/carbon/human/H = M
|
||||||
H.SetSpecialVoice(H.dna.species.random_name(H.gender))
|
H.SetSpecialVoice(H.dna.species.random_name(H.gender))
|
||||||
if(scramble_language)
|
if(scramble_language && !current_language) // Last part prevents rerolling language with small amounts of cure.
|
||||||
H.remove_language(current_language)
|
|
||||||
current_language = pick(subtypesof(/datum/language) - /datum/language/common)
|
current_language = pick(subtypesof(/datum/language) - /datum/language/common)
|
||||||
H.grant_language(current_language)
|
H.add_blocked_language(subtypesof(/datum/language) - current_language, LANGUAGE_VOICECHANGE)
|
||||||
mob_language = H.get_language_holder()
|
H.grant_language(current_language, TRUE, TRUE, LANGUAGE_VOICECHANGE)
|
||||||
mob_language.only_speaks_language = current_language
|
|
||||||
|
|
||||||
/datum/symptom/voice_change/End(datum/disease/advance/A)
|
/datum/symptom/voice_change/End(datum/disease/advance/A)
|
||||||
..()
|
..()
|
||||||
@@ -78,10 +71,5 @@ Bonus
|
|||||||
var/mob/living/carbon/human/H = A.affected_mob
|
var/mob/living/carbon/human/H = A.affected_mob
|
||||||
H.UnsetSpecialVoice()
|
H.UnsetSpecialVoice()
|
||||||
if(scramble_language)
|
if(scramble_language)
|
||||||
var/mob/living/M = A.affected_mob
|
A.affected_mob.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_VOICECHANGE)
|
||||||
M.copy_known_languages_from(original_language, TRUE)
|
A.affected_mob.remove_all_languages(LANGUAGE_VOICECHANGE) // In case someone managed to get more than one anyway.
|
||||||
mob_language = M.get_language_holder()
|
|
||||||
mob_language.only_speaks_language = null
|
|
||||||
M.selected_default_language = original_language
|
|
||||||
current_language = null
|
|
||||||
QDEL_NULL(original_language)
|
|
||||||
|
|||||||
@@ -124,8 +124,6 @@
|
|||||||
if(ishuman(affected_mob))
|
if(ishuman(affected_mob))
|
||||||
var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSTUNS | TR_KEEPREAGENTS | TR_KEEPSE)
|
var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSTUNS | TR_KEEPREAGENTS | TR_KEEPSE)
|
||||||
M.ventcrawler = VENTCRAWLER_ALWAYS
|
M.ventcrawler = VENTCRAWLER_ALWAYS
|
||||||
M.mind?.language_holder = new M.initial_language_holder(M.mind) // make sure they speak normal monkey
|
|
||||||
|
|
||||||
|
|
||||||
/datum/disease/transformation/jungle_fever/stage_act()
|
/datum/disease/transformation/jungle_fever/stage_act()
|
||||||
..()
|
..()
|
||||||
|
|||||||
@@ -305,6 +305,11 @@
|
|||||||
var/datum/species/old_species = dna.species
|
var/datum/species/old_species = dna.species
|
||||||
dna.species = new_race
|
dna.species = new_race
|
||||||
dna.species.on_species_gain(src, old_species, pref_load)
|
dna.species.on_species_gain(src, old_species, pref_load)
|
||||||
|
if(ishuman(src))
|
||||||
|
qdel(language_holder)
|
||||||
|
var/species_holder = initial(mrace.species_language_holder)
|
||||||
|
language_holder = new species_holder(src)
|
||||||
|
update_atom_languages()
|
||||||
|
|
||||||
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
|
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
|
||||||
..()
|
..()
|
||||||
@@ -510,7 +515,7 @@
|
|||||||
var/datum/mutation/human/HM = dna.get_mutation(mutation)
|
var/datum/mutation/human/HM = dna.get_mutation(mutation)
|
||||||
if(HM)
|
if(HM)
|
||||||
HM.scrambled = TRUE
|
HM.scrambled = TRUE
|
||||||
if(HM.quality & resilient)
|
if(HM.quality & resilient)
|
||||||
HM.mutadone_proof = TRUE
|
HM.mutadone_proof = TRUE
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
|
|||||||
@@ -85,9 +85,7 @@
|
|||||||
|
|
||||||
/datum/mind/proc/get_language_holder()
|
/datum/mind/proc/get_language_holder()
|
||||||
if(!language_holder)
|
if(!language_holder)
|
||||||
var/datum/language_holder/L = current.get_language_holder(shadow=FALSE)
|
language_holder = new (src)
|
||||||
language_holder = L.copy(src)
|
|
||||||
|
|
||||||
return language_holder
|
return language_holder
|
||||||
|
|
||||||
/datum/mind/proc/transfer_to(mob/new_character, force_key_move = 0)
|
/datum/mind/proc/transfer_to(mob/new_character, force_key_move = 0)
|
||||||
@@ -96,10 +94,6 @@
|
|||||||
UnregisterSignal(current, COMSIG_MOB_DEATH)
|
UnregisterSignal(current, COMSIG_MOB_DEATH)
|
||||||
SStgui.on_transfer(current, new_character)
|
SStgui.on_transfer(current, new_character)
|
||||||
|
|
||||||
if(!language_holder)
|
|
||||||
var/datum/language_holder/mob_holder = new_character.get_language_holder(shadow = FALSE)
|
|
||||||
language_holder = mob_holder.copy(src)
|
|
||||||
|
|
||||||
if(key)
|
if(key)
|
||||||
if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
|
if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
|
||||||
new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
|
new_character.ghostize(1) //we'll need to ghostize so that key isn't mobless.
|
||||||
@@ -127,9 +121,10 @@
|
|||||||
RegisterSignal(new_character, COMSIG_MOB_DEATH, .proc/set_death_time)
|
RegisterSignal(new_character, COMSIG_MOB_DEATH, .proc/set_death_time)
|
||||||
if(active || force_key_move)
|
if(active || force_key_move)
|
||||||
new_character.key = key //now transfer the key to link the client to our new body
|
new_character.key = key //now transfer the key to link the client to our new body
|
||||||
|
current.update_atom_languages()
|
||||||
|
|
||||||
|
|
||||||
///Adjust experience of a specific skill
|
///Adjust experience of a specific skill
|
||||||
/datum/mind/proc/adjust_experience(skill, amt, silent = FALSE)
|
/datum/mind/proc/adjust_experience(skill, amt, silent = FALSE)
|
||||||
var/datum/skill/S = GetSkillRef(skill)
|
var/datum/skill/S = GetSkillRef(skill)
|
||||||
skill_experience[S] = max(0, skill_experience[S] + amt) //Prevent going below 0
|
skill_experience[S] = max(0, skill_experience[S] + amt) //Prevent going below 0
|
||||||
|
|||||||
@@ -266,10 +266,10 @@
|
|||||||
|
|
||||||
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
||||||
..()
|
..()
|
||||||
owner.grant_language(/datum/language/beachbum)
|
owner.grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER)
|
||||||
owner.remove_language(/datum/language/common)
|
owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER)
|
||||||
|
|
||||||
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
||||||
..()
|
..()
|
||||||
owner.grant_language(/datum/language/common)
|
owner.remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER)
|
||||||
owner.remove_language(/datum/language/beachbum)
|
owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
var/throw_range = 7
|
var/throw_range = 7
|
||||||
var/mob/pulledby = null
|
var/mob/pulledby = null
|
||||||
var/initial_language_holder = /datum/language_holder
|
var/initial_language_holder = /datum/language_holder
|
||||||
var/datum/language_holder/language_holder
|
var/datum/language_holder/language_holder // Mindless mobs and objects need language too, some times. Mind holder takes prescedence.
|
||||||
var/verb_say = "says"
|
var/verb_say = "says"
|
||||||
var/verb_ask = "asks"
|
var/verb_ask = "asks"
|
||||||
var/verb_exclaim = "exclaims"
|
var/verb_exclaim = "exclaims"
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
continue
|
continue
|
||||||
var/atom/movable/thing = i
|
var/atom/movable/thing = i
|
||||||
thing.Crossed(src)
|
thing.Crossed(src)
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
/atom/movable/Move(atom/newloc, direct, glide_size_override = 0)
|
/atom/movable/Move(atom/newloc, direct, glide_size_override = 0)
|
||||||
@@ -788,88 +788,94 @@
|
|||||||
animate(src, pixel_y = initial(pixel_y), time = 10)
|
animate(src, pixel_y = initial(pixel_y), time = 10)
|
||||||
setMovetype(movement_type & ~FLOATING)
|
setMovetype(movement_type & ~FLOATING)
|
||||||
|
|
||||||
/* Language procs */
|
|
||||||
/atom/movable/proc/get_language_holder(shadow=TRUE)
|
/* Language procs
|
||||||
if(language_holder)
|
* Unless you are doing something very specific, these are the ones you want to use.
|
||||||
return language_holder
|
*/
|
||||||
else
|
|
||||||
|
/// Gets or creates the relevant language holder. For mindless atoms, gets the local one. For atom with mind, gets the mind one.
|
||||||
|
/atom/movable/proc/get_language_holder(get_minds = TRUE)
|
||||||
|
if(!language_holder)
|
||||||
language_holder = new initial_language_holder(src)
|
language_holder = new initial_language_holder(src)
|
||||||
return language_holder
|
return language_holder
|
||||||
|
|
||||||
/atom/movable/proc/grant_language(datum/language/dt, body = FALSE)
|
/// Grants the supplied language and sets omnitongue true.
|
||||||
var/datum/language_holder/H = get_language_holder(!body)
|
/atom/movable/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ATOM)
|
||||||
H.grant_language(dt, body)
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.grant_language(language, understood, spoken, source)
|
||||||
|
|
||||||
/atom/movable/proc/grant_all_languages(omnitongue=FALSE)
|
/// Grants every language.
|
||||||
var/datum/language_holder/H = get_language_holder()
|
/atom/movable/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND)
|
||||||
H.grant_all_languages(omnitongue)
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.grant_all_languages(understood, spoken, grant_omnitongue, source)
|
||||||
|
|
||||||
|
/// Removes a single language.
|
||||||
|
/atom/movable/proc/remove_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ALL)
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.remove_language(language, understood, spoken, source)
|
||||||
|
|
||||||
|
/// Removes every language and sets omnitongue false.
|
||||||
|
/atom/movable/proc/remove_all_languages(source = LANGUAGE_ALL, remove_omnitongue = FALSE)
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.remove_all_languages(source, remove_omnitongue)
|
||||||
|
|
||||||
|
/// Adds a language to the blocked language list. Use this over remove_language in cases where you will give languages back later.
|
||||||
|
/atom/movable/proc/add_blocked_language(language, source = LANGUAGE_ATOM)
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.add_blocked_language(language, source)
|
||||||
|
|
||||||
|
/// Removes a language from the blocked language list.
|
||||||
|
/atom/movable/proc/remove_blocked_language(language, source = LANGUAGE_ATOM)
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.remove_blocked_language(language, source)
|
||||||
|
|
||||||
|
/// Checks if atom has the language. If spoken is true, only checks if atom can speak the language.
|
||||||
|
/atom/movable/proc/has_language(language, spoken = FALSE)
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.has_language(language, spoken)
|
||||||
|
|
||||||
|
/// Checks if atom can speak the language.
|
||||||
|
/atom/movable/proc/can_speak_language(language)
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.can_speak_language(language)
|
||||||
|
|
||||||
|
/// Returns the result of tongue specific limitations on spoken languages.
|
||||||
|
/atom/movable/proc/could_speak_language(language)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/// Returns selected language, if it can be spoken, or finds, sets and returns a new selected language if possible.
|
||||||
|
/atom/movable/proc/get_selected_language()
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.get_selected_language()
|
||||||
|
|
||||||
|
/// Gets a random understood language, useful for hallucinations and such.
|
||||||
/atom/movable/proc/get_random_understood_language()
|
/atom/movable/proc/get_random_understood_language()
|
||||||
var/datum/language_holder/H = get_language_holder()
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
. = H.get_random_understood_language()
|
return LH.get_random_understood_language()
|
||||||
|
|
||||||
/atom/movable/proc/remove_language(datum/language/dt, body = FALSE)
|
/// Gets a random spoken language, useful for forced speech and such.
|
||||||
var/datum/language_holder/H = get_language_holder(!body)
|
/atom/movable/proc/get_random_spoken_language()
|
||||||
H.remove_language(dt, body)
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.get_random_spoken_language()
|
||||||
|
|
||||||
/atom/movable/proc/remove_all_languages()
|
/// Copies all languages into the supplied atom/language holder. Source should be overridden when you
|
||||||
var/datum/language_holder/H = get_language_holder()
|
/// do not want the language overwritten by later atom updates or want to avoid blocked languages.
|
||||||
H.remove_all_languages()
|
/atom/movable/proc/copy_languages(from_holder, source_override)
|
||||||
|
if(isatom(from_holder))
|
||||||
|
var/atom/movable/thing = from_holder
|
||||||
|
from_holder = thing.get_language_holder()
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
|
return LH.copy_languages(from_holder, source_override)
|
||||||
|
|
||||||
/atom/movable/proc/has_language(datum/language/dt)
|
/// Empties out the atom specific languages and updates them according to the current atoms language holder.
|
||||||
var/datum/language_holder/H = get_language_holder()
|
/// As a side effect, it also creates missing language holders in the process.
|
||||||
. = H.has_language(dt)
|
/atom/movable/proc/update_atom_languages()
|
||||||
|
var/datum/language_holder/LH = get_language_holder()
|
||||||
/atom/movable/proc/copy_known_languages_from(thing, replace=FALSE)
|
return LH.update_atom_languages(src)
|
||||||
var/datum/language_holder/H = get_language_holder()
|
|
||||||
. = H.copy_known_languages_from(thing, replace)
|
|
||||||
|
|
||||||
// Whether an AM can speak in a language or not, independent of whether
|
|
||||||
// it KNOWS the language
|
|
||||||
/atom/movable/proc/could_speak_in_language(datum/language/dt)
|
|
||||||
. = TRUE
|
|
||||||
|
|
||||||
/atom/movable/proc/can_speak_in_language(datum/language/dt)
|
|
||||||
var/datum/language_holder/H = get_language_holder()
|
|
||||||
|
|
||||||
if(!H.has_language(dt))
|
|
||||||
return FALSE
|
|
||||||
else if(H.omnitongue)
|
|
||||||
return TRUE
|
|
||||||
else if(could_speak_in_language(dt) && (!H.only_speaks_language || H.only_speaks_language == dt))
|
|
||||||
return TRUE
|
|
||||||
else
|
|
||||||
return FALSE
|
|
||||||
|
|
||||||
/atom/movable/proc/get_default_language()
|
|
||||||
// if no language is specified, and we want to say() something, which
|
|
||||||
// language do we use?
|
|
||||||
var/datum/language_holder/H = get_language_holder()
|
|
||||||
|
|
||||||
if(H.selected_default_language)
|
|
||||||
if(can_speak_in_language(H.selected_default_language))
|
|
||||||
return H.selected_default_language
|
|
||||||
else
|
|
||||||
H.selected_default_language = null
|
|
||||||
|
|
||||||
|
|
||||||
var/datum/language/chosen_langtype
|
|
||||||
var/highest_priority
|
|
||||||
|
|
||||||
for(var/lt in H.languages)
|
|
||||||
var/datum/language/langtype = lt
|
|
||||||
if(!can_speak_in_language(langtype))
|
|
||||||
continue
|
|
||||||
|
|
||||||
var/pri = initial(langtype.default_priority)
|
|
||||||
if(!highest_priority || (pri > highest_priority))
|
|
||||||
chosen_langtype = langtype
|
|
||||||
highest_priority = pri
|
|
||||||
|
|
||||||
H.selected_default_language = .
|
|
||||||
. = chosen_langtype
|
|
||||||
|
|
||||||
/* End language procs */
|
/* End language procs */
|
||||||
|
|
||||||
|
|
||||||
/atom/movable/proc/ConveyorMove(movedir)
|
/atom/movable/proc/ConveyorMove(movedir)
|
||||||
set waitfor = FALSE
|
set waitfor = FALSE
|
||||||
if(!anchored && has_gravity())
|
if(!anchored && has_gravity())
|
||||||
|
|||||||
@@ -415,7 +415,6 @@ obj/machinery/holopad/secure/Initialize()
|
|||||||
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
||||||
Hologram.Impersonation = user
|
Hologram.Impersonation = user
|
||||||
|
|
||||||
Hologram.copy_known_languages_from(user,replace = TRUE)
|
|
||||||
Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||||
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||||
Hologram.setAnchored(TRUE)//So space wind cannot drag it.
|
Hologram.setAnchored(TRUE)//So space wind cannot drag it.
|
||||||
@@ -572,9 +571,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
|||||||
Hologram.alpha = 170
|
Hologram.alpha = 170
|
||||||
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
||||||
Hologram.dir = SOUTH //for now
|
Hologram.dir = SOUTH //for now
|
||||||
Hologram.grant_all_languages(omnitongue=TRUE)
|
|
||||||
var/datum/language_holder/holder = Hologram.get_language_holder()
|
var/datum/language_holder/holder = Hologram.get_language_holder()
|
||||||
holder.selected_default_language = record.language
|
holder.selected_language = record.language
|
||||||
Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it.
|
||||||
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||||
Hologram.setAnchored(TRUE)//So space wind cannot drag it.
|
Hologram.setAnchored(TRUE)//So space wind cannot drag it.
|
||||||
@@ -666,7 +664,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
|||||||
return
|
return
|
||||||
if(HOLORECORD_LANGUAGE)
|
if(HOLORECORD_LANGUAGE)
|
||||||
var/datum/language_holder/holder = replay_holo.get_language_holder()
|
var/datum/language_holder/holder = replay_holo.get_language_holder()
|
||||||
holder.selected_default_language = entry[2]
|
holder.selected_language = entry[2]
|
||||||
if(HOLORECORD_PRESET)
|
if(HOLORECORD_PRESET)
|
||||||
var/preset_type = entry[2]
|
var/preset_type = entry[2]
|
||||||
var/datum/preset_holoimage/H = new preset_type
|
var/datum/preset_holoimage/H = new preset_type
|
||||||
@@ -689,6 +687,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
|||||||
updateDialog()
|
updateDialog()
|
||||||
|
|
||||||
/obj/effect/overlay/holo_pad_hologram
|
/obj/effect/overlay/holo_pad_hologram
|
||||||
|
initial_language_holder = /datum/language_holder/universal
|
||||||
var/mob/living/Impersonation
|
var/mob/living/Impersonation
|
||||||
var/datum/holocall/HC
|
var/datum/holocall/HC
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@
|
|||||||
obj/source, // the originating radio
|
obj/source, // the originating radio
|
||||||
frequency, // the frequency the signal is taking place on
|
frequency, // the frequency the signal is taking place on
|
||||||
atom/movable/virtualspeaker/speaker, // representation of the method's speaker
|
atom/movable/virtualspeaker/speaker, // representation of the method's speaker
|
||||||
datum/language/language, // the langauge of the message
|
datum/language/language, // the language of the message
|
||||||
message, // the text content of the message
|
message, // the text content of the message
|
||||||
spans // the list of spans applied to the message
|
spans // the list of spans applied to the message
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -198,7 +198,7 @@
|
|||||||
if(!spans)
|
if(!spans)
|
||||||
spans = list(M.speech_span)
|
spans = list(M.speech_span)
|
||||||
if(!language)
|
if(!language)
|
||||||
language = M.get_default_language()
|
language = M.get_selected_language()
|
||||||
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language)
|
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language)
|
||||||
return ITALICS | REDUCE_RANGE
|
return ITALICS | REDUCE_RANGE
|
||||||
|
|
||||||
|
|||||||
@@ -452,7 +452,9 @@
|
|||||||
S.ckey = C.ckey
|
S.ckey = C.ckey
|
||||||
S.fully_replace_character_name(null, "The spirit of [name]")
|
S.fully_replace_character_name(null, "The spirit of [name]")
|
||||||
S.status_flags |= GODMODE
|
S.status_flags |= GODMODE
|
||||||
S.language_holder = user.language_holder.copy(S)
|
S.copy_languages(user, LANGUAGE_MASTER) //Make sure the sword can understand and communicate with the user.
|
||||||
|
S.update_atom_languages()
|
||||||
|
grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue
|
||||||
var/input = sanitize_name(stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN))
|
var/input = sanitize_name(stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN))
|
||||||
|
|
||||||
if(src && input)
|
if(src && input)
|
||||||
|
|||||||
@@ -57,10 +57,6 @@
|
|||||||
new_spawn.fully_replace_character_name(null,random_unique_lizard_name(gender))
|
new_spawn.fully_replace_character_name(null,random_unique_lizard_name(gender))
|
||||||
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Don't leave your nest undefended, protect it with your life. Glory to the Necropolis!</b>")
|
to_chat(new_spawn, "<b>Drag the corpses of men and beasts to your nest. It will absorb them to create more of your kind. Don't leave your nest undefended, protect it with your life. Glory to the Necropolis!</b>")
|
||||||
|
|
||||||
new_spawn.grant_language(/datum/language/draconic)
|
|
||||||
var/datum/language_holder/holder = new_spawn.get_language_holder()
|
|
||||||
holder.selected_default_language = /datum/language/draconic
|
|
||||||
|
|
||||||
new_spawn.mind.add_antag_datum(/datum/antagonist/ashwalker, team)
|
new_spawn.mind.add_antag_datum(/datum/antagonist/ashwalker, team)
|
||||||
|
|
||||||
if(ishuman(new_spawn))
|
if(ishuman(new_spawn))
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
|||||||
return
|
return
|
||||||
spans |= speech_span
|
spans |= speech_span
|
||||||
if(!language)
|
if(!language)
|
||||||
language = get_default_language()
|
language = get_selected_language()
|
||||||
send_speech(message, 7, src, , spans, message_language=language)
|
send_speech(message, 7, src, , spans, message_language=language)
|
||||||
|
|
||||||
/atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
/atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||||
|
|||||||
@@ -10,7 +10,12 @@
|
|||||||
/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0)
|
/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0)
|
||||||
..()
|
..()
|
||||||
owner.faction |= "slime"
|
owner.faction |= "slime"
|
||||||
owner.grant_language(/datum/language/slime)
|
owner.grant_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND)
|
||||||
|
|
||||||
|
/obj/item/organ/heart/gland/slime/Remove(mob/living/carbon/M, special = 0)
|
||||||
|
..()
|
||||||
|
owner.faction -= "slime"
|
||||||
|
owner.remove_language(/datum/language/slime, TRUE, TRUE, LANGUAGE_GLAND)
|
||||||
|
|
||||||
/obj/item/organ/heart/gland/slime/activate()
|
/obj/item/organ/heart/gland/slime/activate()
|
||||||
to_chat(owner, "<span class='warning'>You feel nauseated!</span>")
|
to_chat(owner, "<span class='warning'>You feel nauseated!</span>")
|
||||||
|
|||||||
@@ -90,6 +90,7 @@
|
|||||||
if(team_mode)
|
if(team_mode)
|
||||||
forge_team_objectives()
|
forge_team_objectives()
|
||||||
forge_objectives()
|
forge_objectives()
|
||||||
|
owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all.
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|
||||||
/datum/antagonist/changeling/on_removal()
|
/datum/antagonist/changeling/on_removal()
|
||||||
|
|||||||
@@ -59,10 +59,10 @@
|
|||||||
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
||||||
user.set_nutrition(min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED))
|
user.set_nutrition(min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED))
|
||||||
|
|
||||||
if(target.mind && user.mind)//if the victim and user have minds
|
// Absorb a lizard, speak Draconic.
|
||||||
// Absorb a lizard, speak Draconic.
|
owner.copy_languages(target, LANGUAGE_ABSORB)
|
||||||
user.copy_known_languages_from(target)
|
|
||||||
|
|
||||||
|
if(target.mind && user.mind)//if the victim and user have minds
|
||||||
var/datum/mind/suckedbrain = target.mind
|
var/datum/mind/suckedbrain = target.mind
|
||||||
user.mind.memory += "<BR><b>We've absorbed [target]'s memories into our own...</b><BR>[suckedbrain.memory]<BR>"
|
user.mind.memory += "<BR><b>We've absorbed [target]'s memories into our own...</b><BR>[suckedbrain.memory]<BR>"
|
||||||
for(var/A in suckedbrain.antag_datums)
|
for(var/A in suckedbrain.antag_datums)
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
add_antag_hud(antag_hud_type, antag_hud_name, current)
|
add_antag_hud(antag_hud_type, antag_hud_name, current)
|
||||||
handle_clown_mutation(current, mob_override ? null : "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
handle_clown_mutation(current, mob_override ? null : "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.")
|
||||||
current.faction |= "cult"
|
current.faction |= "cult"
|
||||||
current.grant_language(/datum/language/narsie)
|
current.grant_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST)
|
||||||
if(!cult_team.cult_master)
|
if(!cult_team.cult_master)
|
||||||
vote.Grant(current)
|
vote.Grant(current)
|
||||||
communion.Grant(current)
|
communion.Grant(current)
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
remove_antag_hud(antag_hud_type, current)
|
remove_antag_hud(antag_hud_type, current)
|
||||||
handle_clown_mutation(current, removing = FALSE)
|
handle_clown_mutation(current, removing = FALSE)
|
||||||
current.faction -= "cult"
|
current.faction -= "cult"
|
||||||
current.remove_language(/datum/language/narsie)
|
current.remove_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST)
|
||||||
vote.Remove(current)
|
vote.Remove(current)
|
||||||
communion.Remove(current)
|
communion.Remove(current)
|
||||||
magic.Remove(current)
|
magic.Remove(current)
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
|||||||
var/mob/living/M = mob_override || owner.current
|
var/mob/living/M = mob_override || owner.current
|
||||||
add_antag_hud(antag_hud_type, antag_hud_name, M)
|
add_antag_hud(antag_hud_type, antag_hud_name, M)
|
||||||
handle_clown_mutation(M, mob_override ? null : "Your infernal nature has allowed you to overcome your clownishness.")
|
handle_clown_mutation(M, mob_override ? null : "Your infernal nature has allowed you to overcome your clownishness.")
|
||||||
owner.current.grant_all_languages(TRUE)
|
owner.current.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_DEVIL)
|
||||||
update_hud()
|
update_hud()
|
||||||
.=..()
|
.=..()
|
||||||
|
|
||||||
@@ -535,6 +535,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
|||||||
var/mob/living/M = mob_override || owner.current
|
var/mob/living/M = mob_override || owner.current
|
||||||
remove_antag_hud(antag_hud_type, M)
|
remove_antag_hud(antag_hud_type, M)
|
||||||
handle_clown_mutation(M, removing = FALSE)
|
handle_clown_mutation(M, removing = FALSE)
|
||||||
|
owner.current.remove_all_languages(LANGUAGE_DEVIL)
|
||||||
.=..()
|
.=..()
|
||||||
|
|
||||||
/datum/antagonist/devil/proc/printdevilinfo()
|
/datum/antagonist/devil/proc/printdevilinfo()
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
/mob/living/carbon/true_devil/Initialize()
|
/mob/living/carbon/true_devil/Initialize()
|
||||||
create_bodyparts() //initialize bodyparts
|
create_bodyparts() //initialize bodyparts
|
||||||
create_internal_organs()
|
create_internal_organs()
|
||||||
grant_all_languages(omnitongue=TRUE)
|
grant_all_languages()
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/mob/living/carbon/true_devil/create_internal_organs()
|
/mob/living/carbon/true_devil/create_internal_organs()
|
||||||
|
|||||||
@@ -203,7 +203,7 @@
|
|||||||
if(TRAITOR_AI)
|
if(TRAITOR_AI)
|
||||||
add_law_zero()
|
add_law_zero()
|
||||||
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
|
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||||
owner.current.grant_language(/datum/language/codespeak)
|
owner.current.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MALF)
|
||||||
if(TRAITOR_HUMAN)
|
if(TRAITOR_HUMAN)
|
||||||
if(should_equip)
|
if(should_equip)
|
||||||
equip(silent)
|
equip(silent)
|
||||||
|
|||||||
@@ -292,7 +292,10 @@
|
|||||||
S.name = "Shade of [T.real_name]"
|
S.name = "Shade of [T.real_name]"
|
||||||
S.real_name = "Shade of [T.real_name]"
|
S.real_name = "Shade of [T.real_name]"
|
||||||
S.key = shade_controller.key
|
S.key = shade_controller.key
|
||||||
S.language_holder = user.language_holder.copy(S)
|
S.copy_languages(T, LANGUAGE_MIND)//Copies the old mobs languages into the new mob holder.
|
||||||
|
S.copy_languages(user, LANGUAGE_MASTER)
|
||||||
|
S.update_atom_languages()
|
||||||
|
grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue
|
||||||
if(user)
|
if(user)
|
||||||
S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation
|
S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation
|
||||||
if(user && iscultist(user))
|
if(user && iscultist(user))
|
||||||
|
|||||||
@@ -134,7 +134,7 @@
|
|||||||
if(!ishuman(user))
|
if(!ishuman(user))
|
||||||
return
|
return
|
||||||
if(slot == ITEM_SLOT_HEAD)
|
if(slot == ITEM_SLOT_HEAD)
|
||||||
user.grant_language(/datum/language/piratespeak/)
|
user.grant_language(/datum/language/piratespeak/, TRUE, TRUE, LANGUAGE_HAT)
|
||||||
to_chat(user, "<span class='boldnotice'>You suddenly know how to speak like a pirate!</span>")
|
to_chat(user, "<span class='boldnotice'>You suddenly know how to speak like a pirate!</span>")
|
||||||
|
|
||||||
/obj/item/clothing/head/pirate/dropped(mob/user)
|
/obj/item/clothing/head/pirate/dropped(mob/user)
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
return
|
return
|
||||||
var/mob/living/carbon/human/H = user
|
var/mob/living/carbon/human/H = user
|
||||||
if(H.get_item_by_slot(ITEM_SLOT_HEAD) == src)
|
if(H.get_item_by_slot(ITEM_SLOT_HEAD) == src)
|
||||||
user.remove_language(/datum/language/piratespeak/)
|
user.remove_language(/datum/language/piratespeak/, TRUE, TRUE, LANGUAGE_HAT)
|
||||||
to_chat(user, "<span class='boldnotice'>You can no longer speak like a pirate.</span>")
|
to_chat(user, "<span class='boldnotice'>You can no longer speak like a pirate.</span>")
|
||||||
|
|
||||||
/obj/item/clothing/head/pirate/captain
|
/obj/item/clothing/head/pirate/captain
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list(
|
|||||||
|
|
||||||
SA.key = SG.key
|
SA.key = SG.key
|
||||||
|
|
||||||
SA.grant_all_languages(TRUE)
|
SA.grant_all_languages(TRUE, FALSE, FALSE)
|
||||||
|
|
||||||
SA.sentience_act()
|
SA.sentience_act()
|
||||||
|
|
||||||
|
|||||||
@@ -42,4 +42,4 @@
|
|||||||
if(visualsOnly)
|
if(visualsOnly)
|
||||||
return
|
return
|
||||||
|
|
||||||
H.grant_all_languages(omnitongue=TRUE)
|
H.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_CURATOR)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
to_chat(user, "<span class='boldannounce'>You start skimming through [src], and suddenly your mind is filled with codewords and responses.</span>")
|
to_chat(user, "<span class='boldannounce'>You start skimming through [src], and suddenly your mind is filled with codewords and responses.</span>")
|
||||||
user.grant_language(/datum/language/codespeak)
|
user.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
|
||||||
|
|
||||||
use_charge(user)
|
use_charge(user)
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", "<span class='userdanger'>[user] beats you over the head with [src]!</span>", "<span class='hear'>You hear smacking.</span>")
|
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", "<span class='userdanger'>[user] beats you over the head with [src]!</span>", "<span class='hear'>You hear smacking.</span>")
|
||||||
else
|
else
|
||||||
M.visible_message("<span class='notice'>[user] teaches [M] by beating [M.p_them()] over the head with [src]!</span>", "<span class='boldnotice'>As [user] hits you with [src], codewords and responses flow through your mind.</span>", "<span class='hear'>You hear smacking.</span>")
|
M.visible_message("<span class='notice'>[user] teaches [M] by beating [M.p_them()] over the head with [src]!</span>", "<span class='boldnotice'>As [user] hits you with [src], codewords and responses flow through your mind.</span>", "<span class='hear'>You hear smacking.</span>")
|
||||||
M.grant_language(/datum/language/codespeak)
|
M.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
|
||||||
use_charge(user)
|
use_charge(user)
|
||||||
|
|
||||||
/obj/item/codespeak_manual/proc/use_charge(mob/user)
|
/obj/item/codespeak_manual/proc/use_charge(mob/user)
|
||||||
|
|||||||
@@ -1,141 +1,310 @@
|
|||||||
/datum/language_holder
|
/*!Language holders will either exist in an atom/movable or a mind. Creation of language holders happens
|
||||||
var/list/languages = list(/datum/language/common)
|
automatically when they are needed, for example when something tries to speak.
|
||||||
var/list/shadow_languages = list()
|
Where a mind is available, the mind language holder will be the one "in charge". The mind holder
|
||||||
var/only_speaks_language = null
|
will update its languages based on the atom holder, and will get updated as part of
|
||||||
var/selected_default_language = null
|
transformations and other events that cause new languages to become available.
|
||||||
var/datum/language_menu/language_menu
|
|
||||||
|
|
||||||
|
Every language holder has three lists of languages (and sources for each of them):
|
||||||
|
- understood_languages
|
||||||
|
- spoken_languages
|
||||||
|
- blocked_languages
|
||||||
|
|
||||||
|
Understood languages let you understand them, spoken languages lets you speak them
|
||||||
|
(if your tongue is compatible), and blocked languages will let you do neither no matter
|
||||||
|
what the source of the language is.
|
||||||
|
|
||||||
|
Language holders are designed to mostly only ever require the use the helpers in atom/movable
|
||||||
|
to achieve your goals, but it is also possible to work on them directly if needed. Any adding
|
||||||
|
and removing of languages and sources should only happen through the procs, as directly changing
|
||||||
|
these will mess something up somewhere down the line.
|
||||||
|
|
||||||
|
All atom movables have the initial_language_holder var which allows you to set the default language
|
||||||
|
holder to create. For example, /datum/language_holder/alien will give you xenocommon and a block for
|
||||||
|
galactic common. Human species also have a default language holder var that will be updated on
|
||||||
|
species change, initial_species_holder.
|
||||||
|
|
||||||
|
Key procs
|
||||||
|
* [grant_language](atom/movable.html#proc/grant_language)
|
||||||
|
* [remove_language](atom/movable.html#proc/remove_language)
|
||||||
|
* [add_blocked_language](atom/movable.html#proc/add_blocked_language)
|
||||||
|
* [remove_blocked_language](atom/movable.html#proc/remove_blocked_language)
|
||||||
|
* [grant_all_languages](atom/movable.html#proc/grant_all_languages)
|
||||||
|
* [remove_all_languages](atom/movable.html#proc/remove_all_languages)
|
||||||
|
* [has_language](atom/movable.html#proc/has_language)
|
||||||
|
* [can_speak_language](atom/movable.html#proc/can_speak_language)
|
||||||
|
* [get_selected_language](atom/movable.html#proc/get_selected_language)
|
||||||
|
* [update_atom_languages](atom/movable.html#proc/update_atom_languages)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/datum/language_holder
|
||||||
|
/// Understood languages.
|
||||||
|
var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_MIND))
|
||||||
|
/// A list of languages that can be spoken. Tongue organ may also set limits beyond this list.
|
||||||
|
var/list/spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||||
|
/// A list of blocked languages. Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc.
|
||||||
|
var/list/blocked_languages = list()
|
||||||
|
/// If true, overrides tongue limitations.
|
||||||
var/omnitongue = FALSE
|
var/omnitongue = FALSE
|
||||||
|
/// Handles displaying the language menu UI.
|
||||||
|
var/datum/language_menu/language_menu
|
||||||
|
/// Currently spoken language
|
||||||
|
var/selected_language
|
||||||
|
/// Tracks the entity that owns the holder.
|
||||||
var/owner
|
var/owner
|
||||||
|
|
||||||
/datum/language_holder/New(owner)
|
/// Initializes, and copies in the languages from the current atom if available.
|
||||||
src.owner = owner
|
/datum/language_holder/New(_owner)
|
||||||
|
owner = _owner
|
||||||
languages = typecacheof(languages)
|
if(istype(owner, /datum/mind))
|
||||||
shadow_languages = typecacheof(shadow_languages)
|
|
||||||
|
|
||||||
/datum/language_holder/Destroy()
|
|
||||||
owner = null
|
|
||||||
QDEL_NULL(language_menu)
|
|
||||||
languages.Cut()
|
|
||||||
shadow_languages.Cut()
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
/datum/language_holder/proc/copy(newowner)
|
|
||||||
var/datum/language_holder/copy = new(newowner)
|
|
||||||
copy.languages = src.languages.Copy()
|
|
||||||
// shadow languages are not copied.
|
|
||||||
copy.only_speaks_language = src.only_speaks_language
|
|
||||||
copy.selected_default_language = src.selected_default_language
|
|
||||||
// language menu is not copied, that's tied to the holder.
|
|
||||||
copy.omnitongue = src.omnitongue
|
|
||||||
return copy
|
|
||||||
|
|
||||||
/datum/language_holder/proc/grant_language(datum/language/dt, shadow = FALSE)
|
|
||||||
if(shadow)
|
|
||||||
shadow_languages[dt] = TRUE
|
|
||||||
else
|
|
||||||
languages[dt] = TRUE
|
|
||||||
|
|
||||||
/datum/language_holder/proc/grant_all_languages(omnitongue=FALSE)
|
|
||||||
for(var/la in GLOB.all_languages)
|
|
||||||
grant_language(la)
|
|
||||||
|
|
||||||
if(omnitongue)
|
|
||||||
src.omnitongue = TRUE
|
|
||||||
|
|
||||||
/datum/language_holder/proc/get_random_understood_language()
|
|
||||||
var/list/possible = list()
|
|
||||||
for(var/dt in languages)
|
|
||||||
possible += dt
|
|
||||||
. = safepick(possible)
|
|
||||||
|
|
||||||
/datum/language_holder/proc/remove_language(datum/language/dt, shadow = FALSE)
|
|
||||||
if(shadow)
|
|
||||||
shadow_languages -= dt
|
|
||||||
else
|
|
||||||
languages -= dt
|
|
||||||
|
|
||||||
/datum/language_holder/proc/remove_all_languages()
|
|
||||||
languages.Cut()
|
|
||||||
|
|
||||||
/datum/language_holder/proc/has_language(datum/language/dt)
|
|
||||||
if(is_type_in_typecache(dt, languages))
|
|
||||||
return LANGUAGE_KNOWN
|
|
||||||
else
|
|
||||||
var/atom/movable/AM = get_atom()
|
|
||||||
var/datum/language_holder/L = AM.get_language_holder(shadow=FALSE)
|
|
||||||
if(L != src)
|
|
||||||
if(is_type_in_typecache(dt, L.shadow_languages))
|
|
||||||
return LANGUAGE_SHADOWED
|
|
||||||
return FALSE
|
|
||||||
|
|
||||||
/datum/language_holder/proc/copy_known_languages_from(thing, replace=FALSE)
|
|
||||||
var/datum/language_holder/other
|
|
||||||
if(istype(thing, /datum/language_holder))
|
|
||||||
other = thing
|
|
||||||
else if(ismovableatom(thing))
|
|
||||||
var/atom/movable/AM = thing
|
|
||||||
other = AM.get_language_holder()
|
|
||||||
else if(istype(thing, /datum/mind))
|
|
||||||
var/datum/mind/M = thing
|
|
||||||
other = M.get_language_holder()
|
|
||||||
|
|
||||||
if(replace)
|
|
||||||
src.remove_all_languages()
|
|
||||||
|
|
||||||
for(var/l in other.languages)
|
|
||||||
src.grant_language(l)
|
|
||||||
|
|
||||||
|
|
||||||
/datum/language_holder/proc/open_language_menu(mob/user)
|
|
||||||
if(!language_menu)
|
|
||||||
language_menu = new(src)
|
|
||||||
language_menu.ui_interact(user)
|
|
||||||
|
|
||||||
/datum/language_holder/proc/get_atom()
|
|
||||||
if(ismovableatom(owner))
|
|
||||||
. = owner
|
|
||||||
else if(istype(owner, /datum/mind))
|
|
||||||
var/datum/mind/M = owner
|
var/datum/mind/M = owner
|
||||||
if(M.current)
|
if(M.current)
|
||||||
. = M.current
|
update_atom_languages(M.current)
|
||||||
|
get_selected_language()
|
||||||
|
|
||||||
|
/datum/language_holder/Destroy()
|
||||||
|
QDEL_NULL(language_menu)
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/// Grants the supplied language.
|
||||||
|
/datum/language_holder/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_MIND)
|
||||||
|
if(understood)
|
||||||
|
if(!understood_languages[language])
|
||||||
|
understood_languages[language] = list()
|
||||||
|
understood_languages[language] |= source
|
||||||
|
. = TRUE
|
||||||
|
if(spoken)
|
||||||
|
if(!spoken_languages[language])
|
||||||
|
spoken_languages[language] = list()
|
||||||
|
spoken_languages[language] |= source
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
|
/// Grants every language to understood and spoken, and gives omnitongue.
|
||||||
|
/datum/language_holder/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND)
|
||||||
|
for(var/language in GLOB.all_languages)
|
||||||
|
grant_language(language, understood, spoken, source)
|
||||||
|
if(grant_omnitongue) // Overrides tongue limitations.
|
||||||
|
omnitongue = TRUE
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/// Removes a single language or source, removing all sources returns the pre-removal state of the language.
|
||||||
|
/datum/language_holder/proc/remove_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ALL)
|
||||||
|
if(understood && understood_languages[language])
|
||||||
|
if(source == LANGUAGE_ALL)
|
||||||
|
understood_languages -= language
|
||||||
|
else
|
||||||
|
understood_languages[language] -= source
|
||||||
|
if(!length(understood_languages[language]))
|
||||||
|
understood_languages -= language
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
|
if(spoken && spoken_languages[language])
|
||||||
|
if(source == LANGUAGE_ALL)
|
||||||
|
spoken_languages -= language
|
||||||
|
else
|
||||||
|
spoken_languages[language] -= source
|
||||||
|
if(!length(spoken_languages[language]))
|
||||||
|
spoken_languages -= language
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
|
/// Removes every language and optionally sets omnitongue false. If a non default source is supplied, only removes that source.
|
||||||
|
/datum/language_holder/proc/remove_all_languages(source = LANGUAGE_ALL, remove_omnitongue = FALSE)
|
||||||
|
for(var/language in GLOB.all_languages)
|
||||||
|
remove_language(language, TRUE, TRUE, source)
|
||||||
|
if(remove_omnitongue)
|
||||||
|
omnitongue = FALSE
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/// Adds a single language or list of languages to the blocked language list.
|
||||||
|
/datum/language_holder/proc/add_blocked_language(languages, source = LANGUAGE_MIND)
|
||||||
|
if(!islist(languages))
|
||||||
|
languages = list(languages)
|
||||||
|
for(var/language in languages)
|
||||||
|
if(!blocked_languages[language])
|
||||||
|
blocked_languages[language] = list()
|
||||||
|
blocked_languages[language] |= source
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/// Removes a single language or list of languages from the blocked language list.
|
||||||
|
/datum/language_holder/proc/remove_blocked_language(languages, source = LANGUAGE_MIND)
|
||||||
|
if(!islist(languages))
|
||||||
|
languages = list(languages)
|
||||||
|
for(var/language in languages)
|
||||||
|
if(blocked_languages[language])
|
||||||
|
if(source == LANGUAGE_ALL)
|
||||||
|
blocked_languages -= language
|
||||||
|
else
|
||||||
|
blocked_languages[language] -= source
|
||||||
|
if(!length(blocked_languages[language]))
|
||||||
|
blocked_languages -= language
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/// Checks if you have the language. If spoken is true, only checks if you can speak the language.
|
||||||
|
/datum/language_holder/proc/has_language(language, spoken = FALSE)
|
||||||
|
if(language in blocked_languages)
|
||||||
|
return FALSE
|
||||||
|
if(spoken)
|
||||||
|
return language in spoken_languages
|
||||||
|
return language in understood_languages
|
||||||
|
|
||||||
|
/// Checks if you can speak the language. Tongue limitations should be supplied as an argument.
|
||||||
|
/datum/language_holder/proc/can_speak_language(language)
|
||||||
|
var/atom/movable/ouratom = get_atom()
|
||||||
|
var/tongue = ouratom.could_speak_language(language)
|
||||||
|
if((omnitongue || tongue) && has_language(language, TRUE))
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/// Returns selected language if it can be spoken, or decides, sets and returns a new selected language if possible.
|
||||||
|
/datum/language_holder/proc/get_selected_language()
|
||||||
|
if(selected_language && can_speak_language(selected_language))
|
||||||
|
return selected_language
|
||||||
|
selected_language = null
|
||||||
|
var/highest_priority
|
||||||
|
for(var/lang in spoken_languages)
|
||||||
|
var/datum/language/language = lang
|
||||||
|
var/priority = initial(language.default_priority)
|
||||||
|
if((!highest_priority || (priority > highest_priority)) && !(language in blocked_languages))
|
||||||
|
if(can_speak_language(language))
|
||||||
|
selected_language = language
|
||||||
|
highest_priority = priority
|
||||||
|
return selected_language
|
||||||
|
|
||||||
|
/// Gets a random understood language, useful for hallucinations and such.
|
||||||
|
/datum/language_holder/proc/get_random_understood_language()
|
||||||
|
return pick(understood_languages)
|
||||||
|
|
||||||
|
/// Gets a random spoken language, useful for forced speech and such.
|
||||||
|
/datum/language_holder/proc/get_random_spoken_language()
|
||||||
|
return pick(spoken_languages)
|
||||||
|
|
||||||
|
/// Opens a language menu reading from the language holder.
|
||||||
|
/datum/language_holder/proc/open_language_menu(mob/user)
|
||||||
|
if(!language_menu)
|
||||||
|
language_menu = new (src)
|
||||||
|
language_menu.ui_interact(user)
|
||||||
|
|
||||||
|
/// Gets the atom, since we some times need to check if the tongue has limitations.
|
||||||
|
/datum/language_holder/proc/get_atom()
|
||||||
|
if(owner)
|
||||||
|
if(istype(owner, /datum/mind))
|
||||||
|
var/datum/mind/M = owner
|
||||||
|
return M.current
|
||||||
|
return owner
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
/// Empties out the atom specific languages and updates them according to the supplied atoms language holder.
|
||||||
|
/datum/language_holder/proc/update_atom_languages(atom/movable/thing)
|
||||||
|
var/datum/language_holder/from_atom = thing.get_language_holder(FALSE) //Gets the atoms language holder
|
||||||
|
if(from_atom == src) //This could happen if called on an atom without a mind.
|
||||||
|
return FALSE
|
||||||
|
for(var/language in understood_languages)
|
||||||
|
remove_language(language, TRUE, FALSE, LANGUAGE_ATOM)
|
||||||
|
for(var/language in spoken_languages)
|
||||||
|
remove_language(language, FALSE, TRUE, LANGUAGE_ATOM)
|
||||||
|
for(var/language in blocked_languages)
|
||||||
|
remove_blocked_language(language, LANGUAGE_ATOM)
|
||||||
|
|
||||||
|
copy_languages(from_atom)
|
||||||
|
get_selected_language()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/// Copies all languages from the supplied atom/language holder. Source should be overridden when you
|
||||||
|
/// do not want the language overwritten by later atom updates or want to avoid blocked languages.
|
||||||
|
/datum/language_holder/proc/copy_languages(var/datum/language_holder/from_holder, source_override)
|
||||||
|
if(source_override) //No blocked languages here, for now only used by ling absorb.
|
||||||
|
for(var/language in from_holder.understood_languages)
|
||||||
|
grant_language(language, TRUE, FALSE, source_override)
|
||||||
|
for(var/language in from_holder.spoken_languages)
|
||||||
|
grant_language(language, FALSE, TRUE, source_override)
|
||||||
|
else
|
||||||
|
for(var/language in from_holder.understood_languages)
|
||||||
|
grant_language(language, TRUE, FALSE, from_holder.understood_languages[language])
|
||||||
|
for(var/language in from_holder.spoken_languages)
|
||||||
|
grant_language(language, FALSE, TRUE, from_holder.spoken_languages[language])
|
||||||
|
for(var/language in from_holder.blocked_languages)
|
||||||
|
add_blocked_language(language, from_holder.blocked_languages[language])
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
|
||||||
|
//************************************************
|
||||||
|
//* Specific language holders *
|
||||||
|
//* Use atom language sources only. *
|
||||||
|
//************************************************/
|
||||||
|
|
||||||
|
|
||||||
/datum/language_holder/alien
|
/datum/language_holder/alien
|
||||||
languages = list(/datum/language/xenocommon)
|
understood_languages = list(/datum/language/xenocommon = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/xenocommon = list(LANGUAGE_ATOM))
|
||||||
/datum/language_holder/monkey
|
blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||||
languages = list(/datum/language/monkey)
|
|
||||||
|
|
||||||
/datum/language_holder/swarmer
|
|
||||||
languages = list(/datum/language/swarmer)
|
|
||||||
|
|
||||||
/datum/language_holder/construct
|
/datum/language_holder/construct
|
||||||
languages = list(/datum/language/common, /datum/language/narsie)
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/narsie = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/narsie = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
/datum/language_holder/drone
|
/datum/language_holder/drone
|
||||||
languages = list(/datum/language/common, /datum/language/drone, /datum/language/machine)
|
understood_languages = list(/datum/language/drone = list(LANGUAGE_ATOM),
|
||||||
only_speaks_language = /datum/language/drone
|
/datum/language/machine = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/drone = list(LANGUAGE_ATOM))
|
||||||
|
blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
/datum/language_holder/drone/syndicate
|
/datum/language_holder/drone/syndicate
|
||||||
only_speaks_language = null
|
blocked_languages = list()
|
||||||
|
|
||||||
/datum/language_holder/slime
|
/datum/language_holder/jelly
|
||||||
languages = list(/datum/language/common, /datum/language/slime)
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
only_speaks_language = /datum/language/slime
|
/datum/language/slime = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/slime = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
/datum/language_holder/lightbringer
|
/datum/language_holder/lightbringer
|
||||||
// TODO change to a lightbringer specific sign language
|
understood_languages = list(/datum/language/slime = list(LANGUAGE_ATOM))
|
||||||
languages = list(/datum/language/slime)
|
spoken_languages = list(/datum/language/slime = list(LANGUAGE_ATOM))
|
||||||
|
blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
|
/datum/language_holder/lizard
|
||||||
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/draconic = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/draconic = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
|
/datum/language_holder/lizard/ash
|
||||||
|
selected_language = /datum/language/draconic
|
||||||
|
|
||||||
|
/datum/language_holder/monkey
|
||||||
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/monkey = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/monkey = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
|
/datum/language_holder/mushroom
|
||||||
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/mushroom = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/mushroom = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
|
/datum/language_holder/slime
|
||||||
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/slime = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/slime = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
|
/datum/language_holder/swarmer
|
||||||
|
understood_languages = list(/datum/language/swarmer = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/swarmer = list(LANGUAGE_ATOM))
|
||||||
|
blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
/datum/language_holder/synthetic
|
/datum/language_holder/synthetic
|
||||||
languages = list(/datum/language/common)
|
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
shadow_languages = list(/datum/language/common, /datum/language/machine, /datum/language/draconic)
|
/datum/language/machine = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/draconic = list(LANGUAGE_ATOM))
|
||||||
|
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/machine = list(LANGUAGE_ATOM),
|
||||||
|
/datum/language/draconic = list(LANGUAGE_ATOM))
|
||||||
|
|
||||||
/datum/language_holder/empty
|
/datum/language_holder/empty
|
||||||
languages = list()
|
understood_languages = list()
|
||||||
shadow_languages = list()
|
spoken_languages = list()
|
||||||
|
|
||||||
/datum/language_holder/universal/New()
|
/datum/language_holder/universal/New()
|
||||||
..()
|
..()
|
||||||
grant_all_languages(omnitongue=TRUE)
|
grant_all_languages()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/datum/language_menu
|
/datum/language_menu
|
||||||
var/datum/language_holder/language_holder
|
var/datum/language_holder/language_holder
|
||||||
|
|
||||||
/datum/language_menu/New(language_holder)
|
/datum/language_menu/New(_language_holder)
|
||||||
src.language_holder = language_holder
|
language_holder = _language_holder
|
||||||
|
|
||||||
/datum/language_menu/Destroy()
|
/datum/language_menu/Destroy()
|
||||||
language_holder = null
|
language_holder = null
|
||||||
@@ -24,21 +24,20 @@
|
|||||||
data["is_living"] = FALSE
|
data["is_living"] = FALSE
|
||||||
|
|
||||||
data["languages"] = list()
|
data["languages"] = list()
|
||||||
for(var/ld in GLOB.all_languages)
|
for(var/lang in GLOB.all_languages)
|
||||||
var/result = language_holder.has_language(ld)
|
var/result = language_holder.has_language(lang) || language_holder.has_language(lang, TRUE)
|
||||||
if(!result)
|
if(!result)
|
||||||
continue
|
continue
|
||||||
var/shadow = result == LANGUAGE_SHADOWED
|
var/datum/language/language = lang
|
||||||
var/datum/language/LD = ld
|
|
||||||
var/list/L = list()
|
var/list/L = list()
|
||||||
|
|
||||||
L["name"] = initial(LD.name)
|
L["name"] = initial(language.name)
|
||||||
L["desc"] = initial(LD.desc)
|
L["desc"] = initial(language.desc)
|
||||||
L["key"] = initial(LD.key)
|
L["key"] = initial(language.key)
|
||||||
L["is_default"] = (LD == language_holder.selected_default_language)
|
L["is_default"] = (language == language_holder.selected_language)
|
||||||
L["shadow"] = shadow
|
|
||||||
if(AM)
|
if(AM)
|
||||||
L["can_speak"] = AM.can_speak_in_language(LD)
|
L["can_speak"] = AM.can_speak_language(language)
|
||||||
|
L["can_understand"] = AM.has_language(language)
|
||||||
|
|
||||||
data["languages"] += list(L)
|
data["languages"] += list(L)
|
||||||
|
|
||||||
@@ -47,15 +46,15 @@
|
|||||||
data["omnitongue"] = language_holder.omnitongue
|
data["omnitongue"] = language_holder.omnitongue
|
||||||
|
|
||||||
data["unknown_languages"] = list()
|
data["unknown_languages"] = list()
|
||||||
for(var/ld in GLOB.all_languages)
|
for(var/lang in GLOB.all_languages)
|
||||||
if(language_holder.has_language(ld))
|
if(language_holder.has_language(lang) || language_holder.has_language(lang, TRUE))
|
||||||
continue
|
continue
|
||||||
var/datum/language/LD = ld
|
var/datum/language/language = lang
|
||||||
var/list/L = list()
|
var/list/L = list()
|
||||||
|
|
||||||
L["name"] = initial(LD.name)
|
L["name"] = initial(language.name)
|
||||||
L["desc"] = initial(LD.desc)
|
L["desc"] = initial(language.desc)
|
||||||
L["key"] = initial(LD.key)
|
L["key"] = initial(language.key)
|
||||||
|
|
||||||
data["unknown_languages"] += list(L)
|
data["unknown_languages"] += list(L)
|
||||||
return data
|
return data
|
||||||
@@ -68,27 +67,51 @@
|
|||||||
|
|
||||||
var/language_name = params["language_name"]
|
var/language_name = params["language_name"]
|
||||||
var/datum/language/language_datum
|
var/datum/language/language_datum
|
||||||
for(var/ld in GLOB.all_languages)
|
for(var/lang in GLOB.all_languages)
|
||||||
var/datum/language/LD = ld
|
var/datum/language/language = lang
|
||||||
if(language_name == initial(LD.name))
|
if(language_name == initial(language.name))
|
||||||
language_datum = LD
|
language_datum = language
|
||||||
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
||||||
|
|
||||||
switch(action)
|
switch(action)
|
||||||
if("select_default")
|
if("select_default")
|
||||||
if(language_datum && AM.can_speak_in_language(language_datum))
|
if(language_datum && AM.can_speak_language(language_datum))
|
||||||
language_holder.selected_default_language = language_datum
|
language_holder.selected_language = language_datum
|
||||||
. = TRUE
|
. = TRUE
|
||||||
if("grant_language")
|
if("grant_language")
|
||||||
if((is_admin || isobserver(AM)) && language_datum)
|
if((is_admin || isobserver(AM)) && language_datum)
|
||||||
language_holder.grant_language(language_datum)
|
var/list/choices = list("Only Spoken", "Only Understood", "Both")
|
||||||
|
var/choice = input(user,"How do you want to add this language?","[language_datum]",null) as null|anything in choices
|
||||||
|
var/spoken = FALSE
|
||||||
|
var/understood = FALSE
|
||||||
|
switch(choice)
|
||||||
|
if("Only Spoken")
|
||||||
|
spoken = TRUE
|
||||||
|
if("Only Understood")
|
||||||
|
understood = TRUE
|
||||||
|
if("Both")
|
||||||
|
spoken = TRUE
|
||||||
|
understood = TRUE
|
||||||
|
language_holder.grant_language(language_datum, understood, spoken)
|
||||||
if(is_admin)
|
if(is_admin)
|
||||||
message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(AM)].")
|
message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(AM)].")
|
||||||
log_admin("[key_name(user)] granted the language [language_name] to [key_name(AM)].")
|
log_admin("[key_name(user)] granted the language [language_name] to [key_name(AM)].")
|
||||||
. = TRUE
|
. = TRUE
|
||||||
if("remove_language")
|
if("remove_language")
|
||||||
if((is_admin || isobserver(AM)) && language_datum)
|
if((is_admin || isobserver(AM)) && language_datum)
|
||||||
language_holder.remove_language(language_datum)
|
var/list/choices = list("Only Spoken", "Only Understood", "Both")
|
||||||
|
var/choice = input(user,"Which part do you wish to remove?","[language_datum]",null) as null|anything in choices
|
||||||
|
var/spoken = FALSE
|
||||||
|
var/understood = FALSE
|
||||||
|
switch(choice)
|
||||||
|
if("Only Spoken")
|
||||||
|
spoken = TRUE
|
||||||
|
if("Only Understood")
|
||||||
|
understood = TRUE
|
||||||
|
if("Both")
|
||||||
|
spoken = TRUE
|
||||||
|
understood = TRUE
|
||||||
|
language_holder.remove_language(language_datum, understood, spoken)
|
||||||
if(is_admin)
|
if(is_admin)
|
||||||
message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(AM)].")
|
message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(AM)].")
|
||||||
log_admin("[key_name(user)] removed the language [language_name] to [key_name(AM)].")
|
log_admin("[key_name(user)] removed the language [language_name] to [key_name(AM)].")
|
||||||
|
|||||||
@@ -577,7 +577,7 @@
|
|||||||
if(!user.can_read(src))
|
if(!user.can_read(src))
|
||||||
return FALSE
|
return FALSE
|
||||||
to_chat(user, "<span class='notice'>You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.</span>")
|
to_chat(user, "<span class='notice'>You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.</span>")
|
||||||
user.grant_all_languages(omnitongue=TRUE)
|
user.grant_all_languages()
|
||||||
new /obj/effect/decal/cleanable/ash(get_turf(user))
|
new /obj/effect/decal/cleanable/ash(get_turf(user))
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
|
|||||||
@@ -481,11 +481,11 @@
|
|||||||
if(frn)
|
if(frn)
|
||||||
client.prefs.random_character()
|
client.prefs.random_character()
|
||||||
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
|
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
|
||||||
|
|
||||||
var/is_antag
|
var/is_antag
|
||||||
if(mind in GLOB.pre_setup_antags)
|
if(mind in GLOB.pre_setup_antags)
|
||||||
is_antag = TRUE
|
is_antag = TRUE
|
||||||
|
|
||||||
client.prefs.copy_to(H, antagonist = is_antag)
|
client.prefs.copy_to(H, antagonist = is_antag)
|
||||||
H.dna.update_dna_identity()
|
H.dna.update_dna_identity()
|
||||||
if(mind)
|
if(mind)
|
||||||
@@ -504,7 +504,7 @@
|
|||||||
/mob/dead/new_player/proc/transfer_character()
|
/mob/dead/new_player/proc/transfer_character()
|
||||||
. = new_character
|
. = new_character
|
||||||
if(.)
|
if(.)
|
||||||
new_character.key = key //Manually transfer the key to log them in
|
new_character.key = key //Manually transfer the key to log them in,
|
||||||
new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||||
new_character = null
|
new_character = null
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
|||||||
var/list/no_equip = list() // slots the race can't equip stuff to
|
var/list/no_equip = list() // slots the race can't equip stuff to
|
||||||
var/nojumpsuit = 0 // this is sorta... weird. it basically lets you equip stuff that usually needs jumpsuits without one, like belts and pockets and ids
|
var/nojumpsuit = 0 // this is sorta... weird. it basically lets you equip stuff that usually needs jumpsuits without one, like belts and pockets and ids
|
||||||
var/say_mod = "says" // affects the speech message
|
var/say_mod = "says" // affects the speech message
|
||||||
|
var/species_language_holder = /datum/language_holder
|
||||||
var/list/default_features = list() // Default mutant bodyparts for this species. Don't forget to set one for every mutant bodypart you allow this species to have.
|
var/list/default_features = list() // Default mutant bodyparts for this species. Don't forget to set one for every mutant bodypart you allow this species to have.
|
||||||
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. DO NOT USE THIS AS A LIST OF ALL POSSIBLE BODYPARTS AS IT WILL FUCK SHIT UP! Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below.
|
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. DO NOT USE THIS AS A LIST OF ALL POSSIBLE BODYPARTS AS IT WILL FUCK SHIT UP! Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below.
|
||||||
var/list/mutant_organs = list() //Internal organs that are unique to this race.
|
var/list/mutant_organs = list() //Internal organs that are unique to this race.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
meat = null
|
meat = null
|
||||||
damage_overlay_type = "synth"
|
damage_overlay_type = "synth"
|
||||||
mutanttongue = /obj/item/organ/tongue/robot
|
mutanttongue = /obj/item/organ/tongue/robot
|
||||||
|
species_language_holder = /datum/language_holder/synthetic
|
||||||
limbs_id = "synth"
|
limbs_id = "synth"
|
||||||
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
|
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
|
||||||
|
|
||||||
|
|||||||
@@ -17,16 +17,15 @@
|
|||||||
burnmod = 0.5 // = 1/2x generic burn damage
|
burnmod = 0.5 // = 1/2x generic burn damage
|
||||||
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
|
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT
|
||||||
inherent_factions = list("slime")
|
inherent_factions = list("slime")
|
||||||
|
species_language_holder = /datum/language_holder/jelly
|
||||||
|
|
||||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||||
if(regenerate_limbs)
|
if(regenerate_limbs)
|
||||||
regenerate_limbs.Remove(C)
|
regenerate_limbs.Remove(C)
|
||||||
C.remove_language(/datum/language/slime)
|
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||||
..()
|
..()
|
||||||
C.grant_language(/datum/language/slime)
|
|
||||||
if(ishuman(C))
|
if(ishuman(C))
|
||||||
regenerate_limbs = new
|
regenerate_limbs = new
|
||||||
regenerate_limbs.Grant(C)
|
regenerate_limbs.Grant(C)
|
||||||
|
|||||||
@@ -24,9 +24,7 @@
|
|||||||
inert_mutation = FIREBREATH
|
inert_mutation = FIREBREATH
|
||||||
deathsound = 'sound/voice/lizard/deathsound.ogg'
|
deathsound = 'sound/voice/lizard/deathsound.ogg'
|
||||||
wings_icon = "Dragon"
|
wings_icon = "Dragon"
|
||||||
|
species_language_holder = /datum/language_holder/lizard
|
||||||
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
|
||||||
H.grant_language(/datum/language/draconic)
|
|
||||||
|
|
||||||
/datum/species/lizard/random_name(gender,unique,lastname)
|
/datum/species/lizard/random_name(gender,unique,lastname)
|
||||||
if(unique)
|
if(unique)
|
||||||
@@ -80,3 +78,4 @@
|
|||||||
limbs_id = "lizard"
|
limbs_id = "lizard"
|
||||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
|
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
|
||||||
inherent_traits = list(TRAIT_CHUNKYFINGERS,TRAIT_NOBREATH)
|
inherent_traits = list(TRAIT_CHUNKYFINGERS,TRAIT_NOBREATH)
|
||||||
|
species_language_holder = /datum/language_holder/lizard/ash
|
||||||
|
|||||||
@@ -27,13 +27,11 @@
|
|||||||
mutanteyes = /obj/item/organ/eyes/night_vision/mushroom
|
mutanteyes = /obj/item/organ/eyes/night_vision/mushroom
|
||||||
use_skintones = FALSE
|
use_skintones = FALSE
|
||||||
var/datum/martial_art/mushpunch/mush
|
var/datum/martial_art/mushpunch/mush
|
||||||
|
species_language_holder = /datum/language_holder/mushroom
|
||||||
|
|
||||||
/datum/species/mush/check_roundstart_eligible()
|
/datum/species/mush/check_roundstart_eligible()
|
||||||
return FALSE //hard locked out of roundstart on the order of design lead kor, this can be removed in the future when planetstation is here OR SOMETHING but right now we have a problem with races.
|
return FALSE //hard locked out of roundstart on the order of design lead kor, this can be removed in the future when planetstation is here OR SOMETHING but right now we have a problem with races.
|
||||||
|
|
||||||
/datum/species/mush/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
|
||||||
H.grant_language(/datum/language/mushroom) //pomf pomf
|
|
||||||
|
|
||||||
/datum/species/mush/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
/datum/species/mush/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||||
. = ..()
|
. = ..()
|
||||||
if(ishuman(C))
|
if(ishuman(C))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
var/list/initial_species_traits //for getting these values back for assume_disguise()
|
var/list/initial_species_traits //for getting these values back for assume_disguise()
|
||||||
var/list/initial_inherent_traits
|
var/list/initial_inherent_traits
|
||||||
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC
|
changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC
|
||||||
|
species_language_holder = /datum/language_holder/synthetic
|
||||||
|
|
||||||
/datum/species/synth/New()
|
/datum/species/synth/New()
|
||||||
initial_species_traits = species_traits.Copy()
|
initial_species_traits = species_traits.Copy()
|
||||||
|
|||||||
@@ -42,12 +42,11 @@
|
|||||||
/mob/living/carbon/human/set_drugginess(amount)
|
/mob/living/carbon/human/set_drugginess(amount)
|
||||||
..()
|
..()
|
||||||
if(!amount)
|
if(!amount)
|
||||||
remove_language(/datum/language/beachbum)
|
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||||
|
|
||||||
/mob/living/carbon/human/adjust_drugginess(amount)
|
/mob/living/carbon/human/adjust_drugginess(amount)
|
||||||
..()
|
..()
|
||||||
if(!dna.check_mutation(STONER))
|
if(druggy)
|
||||||
if(druggy)
|
grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||||
grant_language(/datum/language/beachbum)
|
else
|
||||||
else
|
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||||
remove_language(/datum/language/beachbum)
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
return 0
|
return 0
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/mob/living/carbon/could_speak_in_language(datum/language/dt)
|
/mob/living/carbon/could_speak_language(datum/language/language)
|
||||||
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
|
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
|
||||||
if(T)
|
if(T)
|
||||||
. = T.could_speak_in_language(dt)
|
return T.could_speak_language(language)
|
||||||
else
|
else
|
||||||
. = initial(dt.flags) & TONGUELESS_SPEECH
|
return initial(language.flags) & TONGUELESS_SPEECH
|
||||||
|
|||||||
@@ -103,8 +103,6 @@
|
|||||||
|
|
||||||
var/datum/riding/riding_datum
|
var/datum/riding/riding_datum
|
||||||
|
|
||||||
var/datum/language/selected_default_language
|
|
||||||
|
|
||||||
var/last_words //used for database logging
|
var/last_words //used for database logging
|
||||||
|
|
||||||
var/list/obj/effect/proc_holder/abilities = list()
|
var/list/obj/effect/proc_holder/abilities = list()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
|||||||
var/datum/language/message_language = get_message_language(message)
|
var/datum/language/message_language = get_message_language(message)
|
||||||
if(message_language)
|
if(message_language)
|
||||||
// No, you cannot speak in xenocommon just because you know the key
|
// No, you cannot speak in xenocommon just because you know the key
|
||||||
if(can_speak_in_language(message_language))
|
if(can_speak_language(message_language))
|
||||||
language = message_language
|
language = message_language
|
||||||
message = copytext(message, 3)
|
message = copytext(message, 3)
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
|||||||
message = copytext(message, 2)
|
message = copytext(message, 2)
|
||||||
|
|
||||||
if(!language)
|
if(!language)
|
||||||
language = get_default_language()
|
language = get_selected_language()
|
||||||
|
|
||||||
// Detection of language needs to be before inherent channels, because
|
// Detection of language needs to be before inherent channels, because
|
||||||
// AIs use inherent channels for the holopad. Most inherent channels
|
// AIs use inherent channels for the holopad. Most inherent channels
|
||||||
@@ -404,11 +404,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
|||||||
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||||
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
|
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
|
||||||
|
|
||||||
/mob/living/get_language_holder(shadow=TRUE)
|
/mob/living/get_language_holder(get_minds = TRUE)
|
||||||
if(mind && shadow)
|
if(get_minds && mind)
|
||||||
// Mind language holders shadow mob holders.
|
return mind.get_language_holder()
|
||||||
. = mind.get_language_holder()
|
|
||||||
if(.)
|
|
||||||
return .
|
|
||||||
|
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
derpspeech = 1
|
derpspeech = 1
|
||||||
to_chat(src, "<span class='danger'>Warning: Vocabulary databank corrupted.</span>")
|
to_chat(src, "<span class='danger'>Warning: Vocabulary databank corrupted.</span>")
|
||||||
if(prob(40))
|
if(prob(40))
|
||||||
mind.language_holder.selected_default_language = pick(mind.language_holder.languages)
|
mind.language_holder.selected_language = get_random_spoken_language()
|
||||||
|
|
||||||
|
|
||||||
/mob/living/silicon/pai/ex_act(severity, target)
|
/mob/living/silicon/pai/ex_act(severity, target)
|
||||||
|
|||||||
@@ -279,9 +279,8 @@
|
|||||||
encryptmod = TRUE
|
encryptmod = TRUE
|
||||||
|
|
||||||
if("translator")
|
if("translator")
|
||||||
if(href_list["toggle"])
|
if(href_list["toggle"]) //This is permanent.
|
||||||
grant_all_languages(TRUE)
|
grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE)
|
||||||
// this is PERMAMENT.
|
|
||||||
|
|
||||||
if("doorjack")
|
if("doorjack")
|
||||||
if(href_list["jack"])
|
if(href_list["jack"])
|
||||||
|
|||||||
@@ -913,7 +913,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
|||||||
bot_name = name
|
bot_name = name
|
||||||
name = paicard.pai.name
|
name = paicard.pai.name
|
||||||
faction = user.faction.Copy()
|
faction = user.faction.Copy()
|
||||||
language_holder = paicard.pai.language_holder.copy(src)
|
|
||||||
log_combat(user, paicard.pai, "uploaded to [bot_name],")
|
log_combat(user, paicard.pai, "uploaded to [bot_name],")
|
||||||
return TRUE
|
return TRUE
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -458,6 +458,7 @@
|
|||||||
|
|
||||||
new_xeno.a_intent = INTENT_HARM
|
new_xeno.a_intent = INTENT_HARM
|
||||||
new_xeno.key = key
|
new_xeno.key = key
|
||||||
|
update_atom_languages()
|
||||||
|
|
||||||
to_chat(new_xeno, "<B>You are now an alien.</B>")
|
to_chat(new_xeno, "<B>You are now an alien.</B>")
|
||||||
. = new_xeno
|
. = new_xeno
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
|||||||
add_overlay(causality_field, TRUE)
|
add_overlay(causality_field, TRUE)
|
||||||
|
|
||||||
var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated."
|
var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated."
|
||||||
radio.talk_into(src, speaking, common_channel, language = get_default_language())
|
radio.talk_into(src, speaking, common_channel, language = get_selected_language())
|
||||||
for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10)
|
for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10)
|
||||||
if(damage < explosion_point) // Cutting it a bit close there engineers
|
if(damage < explosion_point) // Cutting it a bit close there engineers
|
||||||
radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel)
|
radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel)
|
||||||
|
|||||||
@@ -276,7 +276,6 @@
|
|||||||
|
|
||||||
if(!new_mob)
|
if(!new_mob)
|
||||||
return
|
return
|
||||||
new_mob.grant_language(/datum/language/common)
|
|
||||||
|
|
||||||
// Some forms can still wear some items
|
// Some forms can still wear some items
|
||||||
for(var/obj/item/W in contents)
|
for(var/obj/item/W in contents)
|
||||||
|
|||||||
@@ -929,9 +929,10 @@ datum/status_effect/stabilized/blue/on_remove()
|
|||||||
familiar = new linked.mob_type(get_turf(owner.loc))
|
familiar = new linked.mob_type(get_turf(owner.loc))
|
||||||
familiar.name = linked.mob_name
|
familiar.name = linked.mob_name
|
||||||
familiar.del_on_death = TRUE
|
familiar.del_on_death = TRUE
|
||||||
familiar.copy_known_languages_from(owner, FALSE)
|
familiar.copy_languages(owner, LANGUAGE_MASTER)
|
||||||
if(linked.saved_mind)
|
if(linked.saved_mind)
|
||||||
linked.saved_mind.transfer_to(familiar)
|
linked.saved_mind.transfer_to(familiar)
|
||||||
|
familiar.update_atom_languages()
|
||||||
familiar.ckey = linked.saved_mind.key
|
familiar.ckey = linked.saved_mind.key
|
||||||
else
|
else
|
||||||
if(familiar.mind)
|
if(familiar.mind)
|
||||||
|
|||||||
@@ -686,7 +686,7 @@
|
|||||||
if(SM.flags_1 & HOLOGRAM_1) //Check to see if it's a holodeck creature
|
if(SM.flags_1 & HOLOGRAM_1) //Check to see if it's a holodeck creature
|
||||||
to_chat(SM, "<span class='userdanger'>You also become depressingly aware that you are not a real creature, but instead a holoform. Your existence is limited to the parameters of the holodeck.</span>")
|
to_chat(SM, "<span class='userdanger'>You also become depressingly aware that you are not a real creature, but instead a holoform. Your existence is limited to the parameters of the holodeck.</span>")
|
||||||
to_chat(user, "<span class='notice'>[SM] accepts [src] and suddenly becomes attentive and aware. It worked!</span>")
|
to_chat(user, "<span class='notice'>[SM] accepts [src] and suddenly becomes attentive and aware. It worked!</span>")
|
||||||
SM.copy_known_languages_from(user, FALSE)
|
SM.copy_languages(user)
|
||||||
after_success(user, SM)
|
after_success(user, SM)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
assignedrole = "Lavaland Syndicate"
|
assignedrole = "Lavaland Syndicate"
|
||||||
|
|
||||||
/obj/effect/mob_spawn/human/lavaland_syndicate/special(mob/living/new_spawn)
|
/obj/effect/mob_spawn/human/lavaland_syndicate/special(mob/living/new_spawn)
|
||||||
new_spawn.grant_language(/datum/language/codespeak)
|
new_spawn.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
|
||||||
|
|
||||||
/datum/outfit/lavaland_syndicate
|
/datum/outfit/lavaland_syndicate
|
||||||
name = "Lavaland Syndicate Agent"
|
name = "Lavaland Syndicate Agent"
|
||||||
|
|||||||
@@ -183,7 +183,7 @@
|
|||||||
to_chat(user, "<span class='boldannounce'>You start skimming through [src], but you already know dronespeak.</span>")
|
to_chat(user, "<span class='boldannounce'>You start skimming through [src], but you already know dronespeak.</span>")
|
||||||
else
|
else
|
||||||
to_chat(user, "<span class='boldannounce'>You start skimming through [src], and suddenly the drone chittering makes sense.</span>")
|
to_chat(user, "<span class='boldannounce'>You start skimming through [src], and suddenly the drone chittering makes sense.</span>")
|
||||||
user.grant_language(/datum/language/drone)
|
user.grant_language(/datum/language/drone, TRUE, TRUE, LANGUAGE_MIND)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(user.has_language(/datum/language/drone))
|
if(user.has_language(/datum/language/drone))
|
||||||
@@ -197,14 +197,14 @@
|
|||||||
if(M == user)
|
if(M == user)
|
||||||
attack_self(user)
|
attack_self(user)
|
||||||
return
|
return
|
||||||
|
|
||||||
playsound(loc, "punch", 25, TRUE, -1)
|
playsound(loc, "punch", 25, TRUE, -1)
|
||||||
if(isdrone(M) || issilicon(M))
|
if(isdrone(M) || issilicon(M))
|
||||||
if(M.has_language(/datum/language/drone))
|
if(M.has_language(/datum/language/drone))
|
||||||
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", "<span class='userdanger'>[user] beats you over the head with [src]!</span>", "<span class='hear'>You hear smacking.</span>")
|
M.visible_message("<span class='danger'>[user] beats [M] over the head with [src]!</span>", "<span class='userdanger'>[user] beats you over the head with [src]!</span>", "<span class='hear'>You hear smacking.</span>")
|
||||||
else
|
else
|
||||||
M.visible_message("<span class='notice'>[user] teaches [M] by beating [M.p_them()] over the head with [src]!</span>", "<span class='boldnotice'>As [user] hits you with [src], chitters resonate in your mind.</span>", "<span class='hear'>You hear smacking.</span>")
|
M.visible_message("<span class='notice'>[user] teaches [M] by beating [M.p_them()] over the head with [src]!</span>", "<span class='boldnotice'>As [user] hits you with [src], chitters resonate in your mind.</span>", "<span class='hear'>You hear smacking.</span>")
|
||||||
M.grant_language(/datum/language/drone)
|
M.grant_language(/datum/language/drone, TRUE, TRUE, LANGUAGE_MIND)
|
||||||
return
|
return
|
||||||
|
|
||||||
/obj/structure/fluff/oldturret
|
/obj/structure/fluff/oldturret
|
||||||
|
|||||||
@@ -41,8 +41,8 @@
|
|||||||
UnregisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
|
UnregisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
|
||||||
M.RegisterSignal(M, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech)
|
M.RegisterSignal(M, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech)
|
||||||
|
|
||||||
/obj/item/organ/tongue/could_speak_in_language(datum/language/dt)
|
/obj/item/organ/tongue/could_speak_language(language)
|
||||||
return is_type_in_typecache(dt, languages_possible)
|
return is_type_in_typecache(language, languages_possible)
|
||||||
|
|
||||||
/obj/item/organ/tongue/lizard
|
/obj/item/organ/tongue/lizard
|
||||||
name = "forked tongue"
|
name = "forked tongue"
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
modifies_speech = TRUE
|
modifies_speech = TRUE
|
||||||
taste_sensitivity = 25 // not as good as an organic tongue
|
taste_sensitivity = 25 // not as good as an organic tongue
|
||||||
|
|
||||||
/obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt)
|
/obj/item/organ/tongue/robot/can_speak_language(language)
|
||||||
return TRUE // THE MAGIC OF ELECTRONICS
|
return TRUE // THE MAGIC OF ELECTRONICS
|
||||||
|
|
||||||
/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args)
|
/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args)
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ export const LanguageMenu = props => {
|
|||||||
{' '}
|
{' '}
|
||||||
Key: ,{language.key}
|
Key: ,{language.key}
|
||||||
{' '}
|
{' '}
|
||||||
{!!language.shadow && '(gained from mob)'}
|
{language.can_understand
|
||||||
|
? 'Can understand.'
|
||||||
|
: 'Cannot understand.'}
|
||||||
{' '}
|
{' '}
|
||||||
{language.can_speak ? 'Can speak.' : 'Cannot speak.'}
|
{language.can_speak ? 'Can speak.' : 'Cannot speak.'}
|
||||||
</LabeledList.Item>
|
</LabeledList.Item>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user