mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 00:29:02 +01:00
Refactors mind language holders into non-existent, fixes new languages being deleted on species swap + tests (#76612)
## About The Pull Request This PR refactors mind language holders into non-existence As a result, `update_atom_languages` is no longer necessary Mind-bound languages are transferred via `/mind/proc/transfer_to` Species changing no longer deletes and re-creates the mob's language holder, allowing them to keep any languages they have. Species languages are sourced from `LANGUAGE_SPECIES` now, meaning they are removed when they change species. If the mob is not a human with a species datum, these are effectively just atom level languages. Makes a bunch of unit tests to ensure language transfer over certain events works as intended ## Why It's Good For The Game Mobs with minds having two independent language holders results in a good few bugs, and simply doesn't make sense when we have sources (`LANGUAGE_MIND`). Instead of tracking two language holders, we can simply use sources better and only track one. This means that the language holder you start with is your language holder, period. It doesn't get deleted or re-instantiated or whatever. ## Changelog 🆑 Melbert refactor: Refactored language holders, making species changes not delete all of your known languages /🆑
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/*!Language holders will either exist in an atom/movable or a mind. Creation of language holders happens
|
||||
/*!Language holders will either exist in an atom/movable. Creation of language holders happens
|
||||
automatically when they are needed, for example when something tries to speak.
|
||||
Where a mind is available, the mind language holder will be the one "in charge". The mind holder
|
||||
will update its languages based on the atom holder, and will get updated as part of
|
||||
@@ -33,34 +33,35 @@ Key procs
|
||||
* [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.
|
||||
/// Lazyassoclist of all understood languages
|
||||
var/list/understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||
/// Lazyassoclist 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.
|
||||
/// Lazyassoclist of blocked languages.
|
||||
/// Used to prevent understanding and speaking certain languages, ie for certain mobs, mutations etc.
|
||||
var/list/blocked_languages
|
||||
/// If true, overrides tongue aforementioned limitations.
|
||||
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/atom/owner
|
||||
var/atom/movable/owner
|
||||
|
||||
/// Initializes, and copies in the languages from the current atom if available.
|
||||
/datum/language_holder/New(atom/_owner)
|
||||
if(_owner && QDELETED(_owner))
|
||||
CRASH("Langauge holder added to a qdeleting thing, what the fuck [text_ref(_owner)]")
|
||||
owner = _owner
|
||||
if(istype(owner, /datum/mind))
|
||||
var/datum/mind/M = owner
|
||||
if(M.current)
|
||||
update_atom_languages(M.current)
|
||||
/datum/language_holder/New(atom/new_owner)
|
||||
if(new_owner)
|
||||
if(QDELETED(new_owner))
|
||||
CRASH("Langauge holder added to a qdeleting thing, what the fuck [text_ref(new_owner)]")
|
||||
if(!ismovable(new_owner))
|
||||
CRASH("Language holder being added to a non-movable thing, this is invalid (was: [new_owner] / [new_owner.type])")
|
||||
|
||||
owner = new_owner
|
||||
|
||||
// If we have an owner, we'll set a default selected language
|
||||
if(owner)
|
||||
@@ -72,50 +73,46 @@ Key procs
|
||||
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
|
||||
/datum/language_holder/proc/grant_language(language, language_flags = ALL, source = LANGUAGE_MIND)
|
||||
if(language_flags & UNDERSTOOD_LANGUAGE)
|
||||
LAZYORASSOCLIST(understood_languages, language, source)
|
||||
. = TRUE
|
||||
if(spoken)
|
||||
if(!spoken_languages[language])
|
||||
spoken_languages[language] = list()
|
||||
spoken_languages[language] |= source
|
||||
if(language_flags & SPOKEN_LANGUAGE)
|
||||
LAZYORASSOCLIST(spoken_languages, language, source)
|
||||
. = TRUE
|
||||
|
||||
return .
|
||||
|
||||
/// 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)
|
||||
/datum/language_holder/proc/grant_all_languages(language_flags = ALL, grant_omnitongue = TRUE, source = LANGUAGE_MIND)
|
||||
for(var/language in GLOB.all_languages)
|
||||
grant_language(language, understood, spoken, source)
|
||||
grant_language(language, language_flags, 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])
|
||||
/datum/language_holder/proc/remove_language(language, language_flags = ALL, source = LANGUAGE_ALL)
|
||||
if(language_flags & UNDERSTOOD_LANGUAGE)
|
||||
if(source == LANGUAGE_ALL)
|
||||
understood_languages -= language
|
||||
LAZYREMOVE(understood_languages, language)
|
||||
else
|
||||
understood_languages[language] -= source
|
||||
if(!length(understood_languages[language]))
|
||||
understood_languages -= language
|
||||
LAZYREMOVEASSOC(understood_languages, language, source)
|
||||
. = TRUE
|
||||
|
||||
if(spoken && spoken_languages[language])
|
||||
if(language_flags & SPOKEN_LANGUAGE)
|
||||
if(source == LANGUAGE_ALL)
|
||||
spoken_languages -= language
|
||||
LAZYREMOVE(spoken_languages, language)
|
||||
else
|
||||
spoken_languages[language] -= source
|
||||
if(!length(spoken_languages[language]))
|
||||
spoken_languages -= language
|
||||
LAZYREMOVEASSOC(spoken_languages, language, source)
|
||||
. = TRUE
|
||||
|
||||
return .
|
||||
|
||||
/// 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)
|
||||
remove_language(language, ALL, source)
|
||||
if(remove_omnitongue)
|
||||
omnitongue = FALSE
|
||||
return TRUE
|
||||
@@ -124,39 +121,41 @@ Key procs
|
||||
/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
|
||||
LAZYORASSOCLIST(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
|
||||
if(source == LANGUAGE_ALL)
|
||||
LAZYREMOVE(blocked_languages, language)
|
||||
else
|
||||
LAZYREMOVEASSOC(blocked_languages, language, source)
|
||||
|
||||
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)
|
||||
/// 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
|
||||
if(spoken)
|
||||
return language in spoken_languages
|
||||
return language in understood_languages
|
||||
|
||||
var/list/langs_to_check = list()
|
||||
if(flag_to_check & SPOKEN_LANGUAGE)
|
||||
langs_to_check |= spoken_languages
|
||||
if(flag_to_check & UNDERSTOOD_LANGUAGE)
|
||||
langs_to_check |= understood_languages
|
||||
|
||||
return language in langs_to_check
|
||||
|
||||
/// 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/can_speak_language_path = omnitongue || ouratom.could_speak_language(language)
|
||||
return (can_speak_language_path && has_language(language, TRUE))
|
||||
var/can_speak_language_path = omnitongue || owner.could_speak_language(language)
|
||||
return (can_speak_language_path && has_language(language, SPOKEN_LANGUAGE))
|
||||
|
||||
/// 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()
|
||||
@@ -199,54 +198,61 @@ Key procs
|
||||
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(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)
|
||||
grant_language(language, UNDERSTOOD_LANGUAGE, source_override)
|
||||
for(var/language in from_holder.spoken_languages)
|
||||
grant_language(language, FALSE, TRUE, source_override)
|
||||
grant_language(language, SPOKEN_LANGUAGE, source_override)
|
||||
else
|
||||
for(var/language in from_holder.understood_languages)
|
||||
grant_language(language, TRUE, FALSE, from_holder.understood_languages[language])
|
||||
grant_language(language, UNDERSTOOD_LANGUAGE, from_holder.understood_languages[language])
|
||||
for(var/language in from_holder.spoken_languages)
|
||||
grant_language(language, FALSE, TRUE, from_holder.spoken_languages[language])
|
||||
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])
|
||||
return TRUE
|
||||
|
||||
/// Transfers all mind languages to the supplied language holder.
|
||||
/datum/language_holder/proc/transfer_mind_languages(datum/language_holder/to_holder)
|
||||
for(var/language in understood_languages)
|
||||
if(LANGUAGE_MIND in understood_languages[language])
|
||||
remove_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND)
|
||||
to_holder.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_MIND)
|
||||
for(var/language in spoken_languages)
|
||||
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)
|
||||
|
||||
//************************************************
|
||||
//* Specific language holders *
|
||||
//* Use atom language sources only. *
|
||||
//************************************************/
|
||||
if(owner)
|
||||
get_selected_language()
|
||||
if(to_holder.owner)
|
||||
to_holder.get_selected_language()
|
||||
|
||||
/// A global assoc list containing prototypes of all language holders
|
||||
/// [Language holder typepath] to [language holder instance]
|
||||
/// Used for easy reference of what can speak what without needing to constantly recreate language holders.
|
||||
GLOBAL_LIST_INIT(prototype_language_holders, init_language_holder_prototypes())
|
||||
|
||||
/// Inits the global list of language holder prototypes.
|
||||
/proc/init_language_holder_prototypes()
|
||||
var/list/prototypes = list()
|
||||
for(var/holdertype in typesof(/datum/language_holder))
|
||||
prototypes[holdertype] = new holdertype()
|
||||
|
||||
return prototypes
|
||||
|
||||
/*
|
||||
* Specific language holders presets
|
||||
*
|
||||
* Prefer to use [LANGUGAE_ATOM]. Atom languages will stick through species changes but not mindswaps.
|
||||
*/
|
||||
|
||||
/datum/language_holder/alien
|
||||
understood_languages = list(/datum/language/xenocommon = list(LANGUAGE_ATOM))
|
||||
@@ -254,10 +260,14 @@ Key procs
|
||||
blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/construct
|
||||
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))
|
||||
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
|
||||
understood_languages = list(/datum/language/drone = list(LANGUAGE_ATOM))
|
||||
@@ -265,13 +275,21 @@ Key procs
|
||||
blocked_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/drone/syndicate
|
||||
blocked_languages = list()
|
||||
blocked_languages = null
|
||||
|
||||
/datum/language_holder/human_basic
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/jelly
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/slime = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/slime = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/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
|
||||
understood_languages = list(/datum/language/slime = list(LANGUAGE_ATOM))
|
||||
@@ -279,10 +297,14 @@ Key procs
|
||||
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))
|
||||
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
|
||||
@@ -300,19 +322,29 @@ Key procs
|
||||
selected_language = /datum/language/uncommon
|
||||
|
||||
/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))
|
||||
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))
|
||||
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))
|
||||
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/venus
|
||||
@@ -338,92 +370,124 @@ Key procs
|
||||
)
|
||||
|
||||
/datum/language_holder/moth
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/moffic = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/moffic = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/moffic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/moffic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/skeleton
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/calcic = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/calcic = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/calcic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/calcic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/ethereal
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/voltaic = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/voltaic = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/voltaic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/voltaic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/golem
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/golem/bone
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM),
|
||||
/datum/language/calcic = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM),
|
||||
/datum/language/calcic = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/golem/runic
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM),
|
||||
/datum/language/narsie = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM),
|
||||
/datum/language/narsie = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/terrum = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/fly
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/buzzwords = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/buzzwords = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/buzzwords = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/buzzwords = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/plant
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/sylvan = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/sylvan = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/sylvan = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/sylvan = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/felinid
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/nekomimetic = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/nekomimetic = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/nekomimetic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/nekomimetic = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/shadowpeople
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/shadowtongue = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/shadowtongue = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/shadowtongue = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/shadowtongue = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/clown
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/monkey = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/monkey = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/monkey = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/monkey = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/syndicate
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/codespeak = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/codespeak = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/codespeak = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/codespeak = list(LANGUAGE_ATOM),
|
||||
)
|
||||
|
||||
/datum/language_holder/beachbum
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/beachbum = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/beachbum = list(LANGUAGE_ATOM))
|
||||
understood_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/beachbum = list(LANGUAGE_ATOM),
|
||||
)
|
||||
spoken_languages = list(
|
||||
/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/beachbum = list(LANGUAGE_ATOM),
|
||||
)
|
||||
selected_language = /datum/language/beachbum
|
||||
|
||||
/datum/language_holder/empty
|
||||
understood_languages = list()
|
||||
spoken_languages = list()
|
||||
understood_languages = null
|
||||
spoken_languages = null
|
||||
|
||||
/datum/language_holder/universal
|
||||
understood_languages = null
|
||||
spoken_languages = null
|
||||
|
||||
/datum/language_holder/universal/New()
|
||||
..()
|
||||
. = ..()
|
||||
grant_all_languages()
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
M.visible_message(span_danger("[user] beats [M] over the head with [src]!"), span_userdanger("[user] beats you over the head with [src]!"), span_hear("You hear smacking."))
|
||||
else
|
||||
M.visible_message(span_notice("[user] teaches [M] by beating [M.p_them()] over the head with [src]!"), span_boldnotice("As [user] hits you with [src], [flavour_text]."), span_hear("You hear smacking."))
|
||||
M.grant_language(language, TRUE, TRUE, LANGUAGE_MIND)
|
||||
M.grant_language(language, source = LANGUAGE_MIND)
|
||||
use_charge(user)
|
||||
|
||||
/obj/item/language_manual/proc/use_charge(mob/user)
|
||||
|
||||
@@ -20,46 +20,40 @@
|
||||
/datum/language_menu/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/atom/movable/AM = language_holder.get_atom()
|
||||
if(isliving(AM))
|
||||
data["is_living"] = TRUE
|
||||
else
|
||||
data["is_living"] = FALSE
|
||||
|
||||
var/atom/movable/speaker = language_holder.owner
|
||||
data["is_living"] = isliving(speaker)
|
||||
data["languages"] = list()
|
||||
for(var/lang in GLOB.all_languages)
|
||||
var/result = language_holder.has_language(lang) || language_holder.has_language(lang, TRUE)
|
||||
for(var/datum/language/language as anything in GLOB.all_languages)
|
||||
var/result = language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE)
|
||||
if(!result)
|
||||
continue
|
||||
var/datum/language/language = lang
|
||||
var/list/L = list()
|
||||
var/list/lang_data = list()
|
||||
|
||||
L["name"] = initial(language.name)
|
||||
L["desc"] = initial(language.desc)
|
||||
L["key"] = initial(language.key)
|
||||
L["is_default"] = (language == language_holder.selected_language)
|
||||
if(AM)
|
||||
L["can_speak"] = AM.can_speak_language(language)
|
||||
L["can_understand"] = AM.has_language(language)
|
||||
lang_data["name"] = initial(language.name)
|
||||
lang_data["desc"] = initial(language.desc)
|
||||
lang_data["key"] = initial(language.key)
|
||||
lang_data["is_default"] = (language == language_holder.selected_language)
|
||||
if(speaker)
|
||||
lang_data["can_speak"] = speaker.can_speak_language(language)
|
||||
lang_data["can_understand"] = speaker.has_language(language)
|
||||
|
||||
data["languages"] += list(L)
|
||||
UNTYPED_LIST_ADD(data["languages"], lang_data)
|
||||
|
||||
if(check_rights_for(user.client, R_ADMIN) || isobserver(AM))
|
||||
if(check_rights_for(user.client, R_ADMIN) || isobserver(speaker))
|
||||
data["admin_mode"] = TRUE
|
||||
data["omnitongue"] = language_holder.omnitongue
|
||||
|
||||
data["unknown_languages"] = list()
|
||||
for(var/lang in GLOB.all_languages)
|
||||
if(language_holder.has_language(lang) || language_holder.has_language(lang, TRUE))
|
||||
for(var/datum/language/language as anything in GLOB.all_languages)
|
||||
if(language_holder.has_language(language) || language_holder.has_language(language, SPOKEN_LANGUAGE))
|
||||
continue
|
||||
var/datum/language/language = lang
|
||||
var/list/L = list()
|
||||
var/list/lang_data = list()
|
||||
|
||||
L["name"] = initial(language.name)
|
||||
L["desc"] = initial(language.desc)
|
||||
L["key"] = initial(language.key)
|
||||
lang_data["name"] = initial(language.name)
|
||||
lang_data["desc"] = initial(language.desc)
|
||||
lang_data["key"] = initial(language.key)
|
||||
|
||||
UNTYPED_LIST_ADD(data["unknown_languages"], lang_data)
|
||||
|
||||
data["unknown_languages"] += list(L)
|
||||
return data
|
||||
|
||||
/datum/language_menu/ui_act(action, params)
|
||||
@@ -67,71 +61,67 @@
|
||||
if(.)
|
||||
return
|
||||
var/mob/user = usr
|
||||
var/atom/movable/AM = language_holder.get_atom()
|
||||
|
||||
var/atom/movable/speaker = language_holder.owner
|
||||
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
||||
var/language_name = params["language_name"]
|
||||
var/datum/language/language_datum
|
||||
for(var/lang in GLOB.all_languages)
|
||||
var/datum/language/language = lang
|
||||
for(var/datum/language/language as anything in GLOB.all_languages)
|
||||
if(language_name == initial(language.name))
|
||||
language_datum = language
|
||||
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
||||
|
||||
switch(action)
|
||||
if("select_default")
|
||||
if(language_datum && AM.can_speak_language(language_datum))
|
||||
if(language_datum && speaker.can_speak_language(language_datum))
|
||||
language_holder.selected_language = language_datum
|
||||
. = TRUE
|
||||
if("grant_language")
|
||||
if((is_admin || isobserver(AM)) && language_datum)
|
||||
if((is_admin || isobserver(speaker)) && language_datum)
|
||||
var/list/choices = list("Only Spoken", "Only Understood", "Both")
|
||||
var/choice = tgui_input_list(user, "How do you want to add this language?", "[language_datum]", choices)
|
||||
if(isnull(choice))
|
||||
return
|
||||
var/spoken = FALSE
|
||||
var/understood = FALSE
|
||||
var/adding_flags = NONE
|
||||
switch(choice)
|
||||
if("Only Spoken")
|
||||
spoken = TRUE
|
||||
adding_flags |= SPOKEN_LANGUAGE
|
||||
if("Only Understood")
|
||||
understood = TRUE
|
||||
adding_flags |= UNDERSTOOD_LANGUAGE
|
||||
if("Both")
|
||||
spoken = TRUE
|
||||
understood = TRUE
|
||||
if(language_holder.blocked_languages && language_holder.blocked_languages[language_datum])
|
||||
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"))
|
||||
if(choice == "Yes")
|
||||
language_holder.remove_blocked_language(language_datum, LANGUAGE_ALL)
|
||||
language_holder.grant_language(language_datum, understood, spoken)
|
||||
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(AM)].")
|
||||
log_admin("[key_name(user)] granted the language [language_name] to [key_name(AM)].")
|
||||
message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(speaker)].")
|
||||
log_admin("[key_name(user)] granted the language [language_name] to [key_name(speaker)].")
|
||||
. = TRUE
|
||||
if("remove_language")
|
||||
if((is_admin || isobserver(AM)) && language_datum)
|
||||
if((is_admin || isobserver(speaker)) && language_datum)
|
||||
var/list/choices = list("Only Spoken", "Only Understood", "Both")
|
||||
var/choice = tgui_input_list(user, "Which part do you wish to remove?", "[language_datum]", choices)
|
||||
if(isnull(choice))
|
||||
return
|
||||
var/spoken = FALSE
|
||||
var/understood = FALSE
|
||||
var/removing_flags = NONE
|
||||
switch(choice)
|
||||
if("Only Spoken")
|
||||
spoken = TRUE
|
||||
removing_flags |= SPOKEN_LANGUAGE
|
||||
if("Only Understood")
|
||||
understood = TRUE
|
||||
removing_flags |= UNDERSTOOD_LANGUAGE
|
||||
if("Both")
|
||||
spoken = TRUE
|
||||
understood = TRUE
|
||||
language_holder.remove_language(language_datum, understood, spoken)
|
||||
removing_flags |= ALL
|
||||
|
||||
language_holder.remove_language(language_datum, removing_flags)
|
||||
if(is_admin)
|
||||
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)].")
|
||||
message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(speaker)].")
|
||||
log_admin("[key_name(user)] removed the language [language_name] to [key_name(speaker)].")
|
||||
. = TRUE
|
||||
if("toggle_omnitongue")
|
||||
if(is_admin || isobserver(AM))
|
||||
if(is_admin || isobserver(speaker))
|
||||
language_holder.omnitongue = !language_holder.omnitongue
|
||||
if(is_admin)
|
||||
message_admins("[key_name_admin(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(AM)].")
|
||||
log_admin("[key_name(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(AM)].")
|
||||
message_admins("[key_name_admin(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(speaker)].")
|
||||
log_admin("[key_name(user)] [language_holder.omnitongue ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(speaker)].")
|
||||
. = TRUE
|
||||
|
||||
Reference in New Issue
Block a user