diff --git a/code/datums/brain_damage/severe.dm b/code/datums/brain_damage/severe.dm index bd821037419..57cfae25cf5 100644 --- a/code/datums/brain_damage/severe.dm +++ b/code/datums/brain_damage/severe.dm @@ -29,13 +29,13 @@ lose_text = span_notice("You suddenly remember how languages work.") /datum/brain_trauma/severe/aphasia/on_gain() - owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/aphasia, LANGUAGE_APHASIA) + owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/aphasia, source = LANGUAGE_APHASIA) owner.grant_language(/datum/language/aphasia, source = LANGUAGE_APHASIA) . = ..() /datum/brain_trauma/severe/aphasia/on_lose() if(!QDELING(owner)) - owner.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_APHASIA) + owner.remove_blocked_language(subtypesof(/datum/language), source = LANGUAGE_APHASIA) owner.remove_language(/datum/language/aphasia, source = LANGUAGE_APHASIA) ..() diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 9654365c49d..92583e1fca7 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -57,7 +57,7 @@ H.SetSpecialVoice(H.generate_random_mob_name()) if(scramble_language && !current_language) // Last part prevents rerolling language with small amounts of cure. current_language = pick(subtypesof(/datum/language) - /datum/language/common) - H.add_blocked_language(subtypesof(/datum/language) - current_language, LANGUAGE_VOICECHANGE) + H.add_blocked_language(subtypesof(/datum/language) - current_language, source = LANGUAGE_VOICECHANGE) H.grant_language(current_language, source = LANGUAGE_VOICECHANGE) /datum/symptom/voice_change/End(datum/disease/advance/A) @@ -66,5 +66,5 @@ var/mob/living/carbon/human/H = A.affected_mob H.UnsetSpecialVoice() if(scramble_language) - A.affected_mob.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_VOICECHANGE) + A.affected_mob.remove_blocked_language(subtypesof(/datum/language), source = LANGUAGE_VOICECHANGE) A.affected_mob.remove_all_languages(LANGUAGE_VOICECHANGE) // In case someone managed to get more than one anyway. diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 7fd59cb1930..7345e87e798 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -231,12 +231,12 @@ if(!.) return owner.grant_language(/datum/language/beachbum, source = LANGUAGE_STONER) - owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) + owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, source = LANGUAGE_STONER) /datum/mutation/stoner/on_losing(mob/living/carbon/human/owner) ..() owner.remove_language(/datum/language/beachbum, source = LANGUAGE_STONER) - owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) + owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, source = LANGUAGE_STONER) /datum/mutation/medieval name = "Medieval" diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index a1de74bc00a..e08e055fd7d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1573,12 +1573,12 @@ return get_language_holder().remove_all_partial_languages(source) /// 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) - return get_language_holder().add_blocked_language(language, source) +/atom/movable/proc/add_blocked_language(language, language_flags = ALL, source = LANGUAGE_ATOM) + return get_language_holder().add_blocked_language(language, language_flags, source) /// Removes a language from the blocked language list. -/atom/movable/proc/remove_blocked_language(language, source = LANGUAGE_ATOM) - return get_language_holder().remove_blocked_language(language, source) +/atom/movable/proc/remove_blocked_language(language, language_flags = ALL, source = LANGUAGE_ATOM) + return get_language_holder().remove_blocked_language(language, language_flags, 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, flags_to_check) diff --git a/code/modules/language/_language_holder.dm b/code/modules/language/_language_holder.dm index 79172b72e50..dc65a708841 100644 --- a/code/modules/language/_language_holder.dm +++ b/code/modules/language/_language_holder.dm @@ -41,9 +41,10 @@ Key procs /// Lazyassoclist of languages that can be spoken. /// Tongue organ may also set limits beyond this list. var/list/spoken_languages - /// Lazyassoclist of blocked languages. - /// Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc. - var/list/blocked_languages + /// Lazyassoclist of languages we are blocked from understanding, used for certain mobs, mutations, quirks, etc. + var/list/blocked_understanding + /// Lazyassoclist of languages we are blocked from speaking, used for certain mobs, mutations, quirks, etc. + var/list/blocked_speaking /// If true, overrides tongue aforementioned limitations. var/omnitongue = FALSE /// Handles displaying the language menu UI. @@ -104,7 +105,7 @@ Key procs for(var/language in mutual_understanding) for(var/source in mutual_understanding[language]) // if this mutual understanding comes from a language, and that language is blocked, skip it - if(LAZYACCESS(blocked_languages, source)) + if(LAZYACCESS(blocked_understanding, source)) continue if(!best_mutual_languages[language] || best_mutual_languages[language] < mutual_understanding[language][source]) best_mutual_languages[language] = mutual_understanding[language][source] @@ -190,37 +191,43 @@ Key procs 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) +/datum/language_holder/proc/add_blocked_language(languages, language_flags = ALL, source = LANGUAGE_MIND) if(!islist(languages)) languages = list(languages) for(var/language in languages) - LAZYORASSOCLIST(blocked_languages, language, source) + if(language_flags & SPOKEN_LANGUAGE) + LAZYORASSOCLIST(blocked_speaking, language, source) + if(language_flags & UNDERSTOOD_LANGUAGE) + LAZYORASSOCLIST(blocked_understanding, language, source) calculate_best_mutual_language() 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) +/datum/language_holder/proc/remove_blocked_language(languages, language_flags = ALL, source = LANGUAGE_MIND) if(!islist(languages)) languages = list(languages) for(var/language in languages) if(source == LANGUAGE_ALL) - LAZYREMOVE(blocked_languages, language) + if(language_flags & SPOKEN_LANGUAGE) + LAZYREMOVE(blocked_speaking, language) + if(language_flags & UNDERSTOOD_LANGUAGE) + LAZYREMOVE(blocked_understanding, language) else - LAZYREMOVEASSOC(blocked_languages, language, source) + if(language_flags & SPOKEN_LANGUAGE) + LAZYREMOVEASSOC(blocked_speaking, language, source) + if(language_flags & UNDERSTOOD_LANGUAGE) + LAZYREMOVEASSOC(blocked_understanding, language, source) calculate_best_mutual_language() return TRUE /// Checks if you have the language passed. /datum/language_holder/proc/has_language(language, flag_to_check = UNDERSTOOD_LANGUAGE) - if(language in blocked_languages) - return FALSE - var/list/langs_to_check = list() - if(flag_to_check & SPOKEN_LANGUAGE) + if(flag_to_check & SPOKEN_LANGUAGE && !LAZYACCESS(blocked_speaking, language)) langs_to_check |= spoken_languages - if(flag_to_check & UNDERSTOOD_LANGUAGE) + if(flag_to_check & UNDERSTOOD_LANGUAGE && !LAZYACCESS(blocked_understanding, language)) langs_to_check |= understood_languages return language in langs_to_check @@ -239,7 +246,7 @@ Key procs 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((!highest_priority || (priority > highest_priority)) && !(language in blocked_speaking)) if(can_speak_language(language)) selected_language = language highest_priority = priority @@ -284,8 +291,10 @@ Key procs grant_language(language, UNDERSTOOD_LANGUAGE, from_holder.understood_languages[language]) for(var/language in from_holder.spoken_languages) grant_language(language, SPOKEN_LANGUAGE, from_holder.spoken_languages[language]) - for(var/language in from_holder.blocked_languages) - add_blocked_language(language, from_holder.blocked_languages[language]) + for(var/language in from_holder.blocked_speaking) + add_blocked_language(language, SPOKEN_LANGUAGE, from_holder.blocked_speaking[language]) + for(var/language in from_holder.blocked_understanding) + add_blocked_language(language, UNDERSTOOD_LANGUAGE, from_holder.blocked_understanding[language]) return TRUE /// Transfers all mind languages to the supplied language holder. @@ -298,10 +307,14 @@ Key procs if(LANGUAGE_MIND in spoken_languages[language]) remove_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) to_holder.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) - for(var/language in blocked_languages) - if(LANGUAGE_MIND in blocked_languages[language]) - remove_blocked_language(language, LANGUAGE_MIND) - to_holder.add_blocked_language(language, LANGUAGE_MIND) + for(var/language in blocked_speaking) + if(LANGUAGE_MIND in blocked_speaking[language]) + remove_blocked_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) + to_holder.add_blocked_language(language, SPOKEN_LANGUAGE, LANGUAGE_MIND) + for(var/language in blocked_understanding) + if(LANGUAGE_MIND in blocked_understanding[language]) + remove_blocked_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND) + to_holder.add_blocked_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND) for(var/language in mutual_understanding) var/mind_understanding = mutual_understanding[language][LANGUAGE_MIND] if(mind_understanding > 0) @@ -335,7 +348,8 @@ GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) /datum/language_holder/alien understood_languages = list(/datum/language/xenocommon = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/xenocommon = list(LANGUAGE_ATOM)) - blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_speaking = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_understanding = list(/datum/language/common = list(LANGUAGE_ATOM)) /datum/language_holder/construct understood_languages = list( @@ -350,10 +364,12 @@ GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) /datum/language_holder/drone understood_languages = list(/datum/language/drone = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/drone = list(LANGUAGE_ATOM)) - blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_speaking = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_understanding = list(/datum/language/common = list(LANGUAGE_ATOM)) /datum/language_holder/drone/syndicate - blocked_languages = null + blocked_speaking = null + blocked_understanding = null /datum/language_holder/human_basic understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) @@ -372,7 +388,8 @@ GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) /datum/language_holder/lightbringer understood_languages = list(/datum/language/slime = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/slime = list(LANGUAGE_ATOM)) - blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_speaking = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_understanding = list(/datum/language/common = list(LANGUAGE_ATOM)) /datum/language_holder/lizard understood_languages = list( @@ -438,12 +455,14 @@ GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes()) /datum/language_holder/venus understood_languages = list(/datum/language/sylvan = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/sylvan = list(LANGUAGE_ATOM)) - blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_speaking = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_understanding = list(/datum/language/common = list(LANGUAGE_ATOM)) /datum/language_holder/spider understood_languages = list(/datum/language/buzzwords = list(LANGUAGE_ATOM)) spoken_languages = list(/datum/language/buzzwords = list(LANGUAGE_ATOM)) - blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_speaking = list(/datum/language/common = list(LANGUAGE_ATOM)) + blocked_understanding = list(/datum/language/common = list(LANGUAGE_ATOM)) /datum/language_holder/synthetic understood_languages = list( diff --git a/code/modules/language/_language_menu.dm b/code/modules/language/_language_menu.dm index b9ffa4fab58..039afb2e1c3 100644 --- a/code/modules/language/_language_menu.dm +++ b/code/modules/language/_language_menu.dm @@ -83,10 +83,16 @@ if("Both") adding_flags |= ALL - if(LAZYACCESS(language_holder.blocked_languages, language_datum)) - choice = tgui_alert(user, "Do you want to lift the blockage that's also preventing the language to be spoken or understood?", "[language_datum]", list("Yes", "No")) + var/ask_to_remove_block + var/list/block_being_removed_on = list() + if(adding_flags & SPOKEN_LANGUAGE && LAZYACCESS(language_holder.blocked_speaking, language_datum)) + ask_to_remove_block = TRUE + block_being_removed_on += "spoken" + + if(ask_to_remove_block) + choice = tgui_alert(user, "Do you want to lift the blockage that's also preventing the language to be [block_being_removed_on.Join(" or ")]?", "[language_datum]", list("Yes", "No")) if(choice == "Yes") - language_holder.remove_blocked_language(language_datum, LANGUAGE_ALL) + language_holder.remove_blocked_language(language_datum, adding_flags, LANGUAGE_ALL) language_holder.grant_language(language_datum, adding_flags) if(is_admin) message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(speaker)].") diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 384439899ac..1811616359d 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -418,8 +418,10 @@ GLOBAL_LIST_EMPTY(features_by_species) human_who_gained_species.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) for(var/language in gaining_holder.spoken_languages) human_who_gained_species.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) - for(var/language in gaining_holder.blocked_languages) - human_who_gained_species.add_blocked_language(language, LANGUAGE_SPECIES) + for(var/language in gaining_holder.blocked_speaking) + human_who_gained_species.add_blocked_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) + for(var/language in gaining_holder.blocked_understanding) + human_who_gained_species.add_blocked_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) if(regenerate_icons) human_who_gained_species.regenerate_icons() @@ -474,8 +476,10 @@ GLOBAL_LIST_EMPTY(features_by_species) human.remove_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) for(var/language in losing_holder.spoken_languages) human.remove_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) - for(var/language in losing_holder.blocked_languages) - human.remove_blocked_language(language, LANGUAGE_SPECIES) + for(var/language in losing_holder.blocked_speaking) + human.remove_blocked_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) + for(var/language in losing_holder.blocked_understanding) + human.remove_blocked_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) SEND_SIGNAL(human, COMSIG_SPECIES_LOSS, src) diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm index 5bdccb8fcfa..d617603cdfc 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm @@ -353,12 +353,12 @@ /datum/reagent/consumable/ethanol/rum/aged/on_mob_metabolize(mob/living/drinker) . = ..() - drinker.add_blocked_language(subtypesof(/datum/language) - /datum/language/piratespeak, LANGUAGE_DRINK) + drinker.add_blocked_language(subtypesof(/datum/language) - /datum/language/piratespeak, source = LANGUAGE_DRINK) drinker.grant_language(/datum/language/piratespeak, source = LANGUAGE_DRINK) /datum/reagent/consumable/ethanol/rum/aged/on_mob_end_metabolize(mob/living/drinker) if(!QDELING(drinker)) - drinker.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_DRINK) + drinker.remove_blocked_language(subtypesof(/datum/language), source = LANGUAGE_DRINK) drinker.remove_language(/datum/language/piratespeak, source = LANGUAGE_DRINK) return ..() diff --git a/code/modules/unit_tests/say.dm b/code/modules/unit_tests/say.dm index a845b6ccf98..6d09fe08715 100644 --- a/code/modules/unit_tests/say.dm +++ b/code/modules/unit_tests/say.dm @@ -90,7 +90,7 @@ var/surfer_quote = "surfing in the USA" host_mob.grant_language(/datum/language/beachbum, SPOKEN_LANGUAGE) // can speak but can't understand - host_mob.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER) + host_mob.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, source = LANGUAGE_STONER) TEST_ASSERT_NOTEQUAL(surfer_quote, host_mob.translate_language(host_mob, /datum/language/beachbum, surfer_quote), "Language test failed. Mob was supposed to understand: [surfer_quote]") host_mob.grant_language(/datum/language/beachbum, ALL) // can now understand