Porting "Refactors language holder"
This commit is contained in:
@@ -3,5 +3,24 @@
|
||||
#define LANGUAGE_HIDE_ICON_IF_UNDERSTOOD 4
|
||||
#define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8
|
||||
|
||||
#define LANGUAGE_KNOWN "language_known"
|
||||
#define LANGUAGE_SHADOWED "language_shadowed"
|
||||
// LANGUAGE SOURCE DEFINES
|
||||
#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_BLOODSUCKER "bloodsucker"
|
||||
#define LANGUAGE_CLOCKIE "clockie"
|
||||
#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_VASSAL "vassal"
|
||||
#define LANGUAGE_VOICECHANGE "voicechange"
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
|
||||
trauma = _trauma
|
||||
owner = trauma.owner
|
||||
copy_known_languages_from(owner, TRUE)
|
||||
|
||||
setup_friend()
|
||||
|
||||
|
||||
@@ -26,21 +26,15 @@
|
||||
scan_desc = "extensive damage to the brain's language center"
|
||||
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>"
|
||||
var/datum/language_holder/prev_language
|
||||
var/datum/language_holder/mob_language
|
||||
|
||||
/datum/brain_trauma/severe/aphasia/on_gain()
|
||||
mob_language = owner.get_language_holder()
|
||||
prev_language = mob_language.copy()
|
||||
mob_language.remove_all_languages()
|
||||
mob_language.grant_language(/datum/language/aphasia)
|
||||
owner.add_blocked_language(subtypesof(/datum/language/) - /datum/language/aphasia, LANGUAGE_APHASIA)
|
||||
owner.grant_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/aphasia/on_lose()
|
||||
mob_language.remove_language(/datum/language/aphasia)
|
||||
mob_language.copy_known_languages_from(prev_language) //this will also preserve languages learned during the trauma
|
||||
QDEL_NULL(prev_language)
|
||||
mob_language = null
|
||||
owner.remove_blocked_language(subtypesof(/datum/language/), LANGUAGE_APHASIA)
|
||||
owner.remove_language(/datum/language/aphasia, TRUE, TRUE, LANGUAGE_APHASIA)
|
||||
..()
|
||||
|
||||
/datum/brain_trauma/severe/blindness
|
||||
|
||||
@@ -30,7 +30,6 @@ Bonus
|
||||
symptom_delay_max = 120
|
||||
var/scramble_language = FALSE
|
||||
var/datum/language/current_language
|
||||
var/datum/language_holder/original_language
|
||||
threshold_desc = list(
|
||||
"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.",
|
||||
@@ -48,9 +47,6 @@ Bonus
|
||||
symptom_delay_max = 85
|
||||
if(A.properties["transmittable"] >= 14) //random language
|
||||
scramble_language = TRUE
|
||||
var/mob/living/M = A.affected_mob
|
||||
var/datum/language_holder/mob_language = M.get_language_holder()
|
||||
original_language = mob_language.copy()
|
||||
|
||||
/datum/symptom/voice_change/Activate(datum/disease/advance/A)
|
||||
if(!..())
|
||||
@@ -64,12 +60,10 @@ Bonus
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.SetSpecialVoice(H.dna.species.random_name(H.gender))
|
||||
if(scramble_language)
|
||||
H.remove_language(current_language)
|
||||
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.grant_language(current_language)
|
||||
var/datum/language_holder/mob_language = H.get_language_holder()
|
||||
mob_language.only_speaks_language = current_language
|
||||
H.add_blocked_language(subtypesof(/datum/language) - current_language, LANGUAGE_VOICECHANGE)
|
||||
H.grant_language(current_language, TRUE, TRUE, LANGUAGE_VOICECHANGE)
|
||||
|
||||
/datum/symptom/voice_change/End(datum/disease/advance/A)
|
||||
..()
|
||||
@@ -77,7 +71,5 @@ Bonus
|
||||
var/mob/living/carbon/human/H = A.affected_mob
|
||||
H.UnsetSpecialVoice()
|
||||
if(scramble_language)
|
||||
var/mob/living/M = A.affected_mob
|
||||
M.copy_known_languages_from(original_language, TRUE)
|
||||
current_language = null
|
||||
QDEL_NULL(original_language)
|
||||
A.affected_mob.remove_blocked_language(subtypesof(/datum/language), LANGUAGE_VOICECHANGE)
|
||||
A.affected_mob.remove_all_languages(LANGUAGE_VOICECHANGE) // In case someone managed to get more than one anyway.
|
||||
|
||||
@@ -355,6 +355,11 @@
|
||||
var/datum/species/old_species = dna.species
|
||||
dna.species = new_race
|
||||
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)
|
||||
..()
|
||||
|
||||
@@ -85,8 +85,7 @@
|
||||
|
||||
/datum/mind/proc/get_language_holder()
|
||||
if(!language_holder)
|
||||
var/datum/language_holder/L = current.get_language_holder(shadow=FALSE)
|
||||
language_holder = L.copy(src)
|
||||
language_holder = new (src)
|
||||
|
||||
return language_holder
|
||||
|
||||
@@ -101,9 +100,6 @@
|
||||
if(iscarbon(current))
|
||||
var/mob/living/carbon/C = current
|
||||
C.disable_intentional_combat_mode(TRUE)
|
||||
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(new_character.key != key) //if we're transferring into a body with a key associated which is not ours
|
||||
@@ -131,6 +127,7 @@
|
||||
transfer_martial_arts(new_character)
|
||||
if(active || force_key_move)
|
||||
new_character.key = key //now transfer the key to link the client to our new body
|
||||
current.update_atom_languages()
|
||||
|
||||
//CIT CHANGE - makes arousal update when transfering bodies
|
||||
if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs.
|
||||
|
||||
@@ -277,10 +277,10 @@
|
||||
|
||||
/datum/mutation/human/stoner/on_acquiring(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/beachbum)
|
||||
owner.remove_language(/datum/language/common)
|
||||
owner.grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER)
|
||||
owner.add_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER)
|
||||
|
||||
/datum/mutation/human/stoner/on_losing(mob/living/carbon/human/owner)
|
||||
..()
|
||||
owner.grant_language(/datum/language/common)
|
||||
owner.remove_language(/datum/language/beachbum)
|
||||
owner.remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_STONER)
|
||||
owner.remove_blocked_language(subtypesof(/datum/language) - /datum/language/beachbum, LANGUAGE_STONER)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/throw_range = 7
|
||||
var/mob/pulledby = null
|
||||
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_ask = "asks"
|
||||
var/verb_exclaim = "exclaims"
|
||||
@@ -502,88 +502,94 @@
|
||||
animate(src, pixel_y = initial(pixel_y), time = 10)
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
|
||||
/* Language procs */
|
||||
/atom/movable/proc/get_language_holder(shadow=TRUE)
|
||||
if(language_holder)
|
||||
return language_holder
|
||||
else
|
||||
|
||||
/* Language procs
|
||||
* Unless you are doing something very specific, these are the ones you want to use.
|
||||
*/
|
||||
|
||||
/// 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)
|
||||
return language_holder
|
||||
return language_holder
|
||||
|
||||
/atom/movable/proc/grant_language(datum/language/dt, body = FALSE)
|
||||
var/datum/language_holder/H = get_language_holder(!body)
|
||||
H.grant_language(dt, body)
|
||||
/// Grants the supplied language and sets omnitongue true.
|
||||
/atom/movable/proc/grant_language(language, understood = TRUE, spoken = TRUE, source = LANGUAGE_ATOM)
|
||||
var/datum/language_holder/LH = get_language_holder()
|
||||
return LH.grant_language(language, understood, spoken, source)
|
||||
|
||||
/atom/movable/proc/grant_all_languages(omnitongue=FALSE)
|
||||
var/datum/language_holder/H = get_language_holder()
|
||||
H.grant_all_languages(omnitongue)
|
||||
/// Grants every language.
|
||||
/atom/movable/proc/grant_all_languages(understood = TRUE, spoken = TRUE, grant_omnitongue = TRUE, source = LANGUAGE_MIND)
|
||||
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()
|
||||
var/datum/language_holder/H = get_language_holder()
|
||||
. = H.get_random_understood_language()
|
||||
var/datum/language_holder/LH = get_language_holder()
|
||||
return LH.get_random_understood_language()
|
||||
|
||||
/atom/movable/proc/remove_language(datum/language/dt, body = FALSE)
|
||||
var/datum/language_holder/H = get_language_holder(!body)
|
||||
H.remove_language(dt, body)
|
||||
/// Gets a random spoken language, useful for forced speech and such.
|
||||
/atom/movable/proc/get_random_spoken_language()
|
||||
var/datum/language_holder/LH = get_language_holder()
|
||||
return LH.get_random_spoken_language()
|
||||
|
||||
/atom/movable/proc/remove_all_languages()
|
||||
var/datum/language_holder/H = get_language_holder()
|
||||
H.remove_all_languages()
|
||||
/// Copies all languages into 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.
|
||||
/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)
|
||||
var/datum/language_holder/H = get_language_holder()
|
||||
. = H.has_language(dt)
|
||||
|
||||
/atom/movable/proc/copy_known_languages_from(thing, replace=FALSE)
|
||||
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
|
||||
/// Empties out the atom specific languages and updates them according to the current atoms language holder.
|
||||
/// As a side effect, it also creates missing language holders in the process.
|
||||
/atom/movable/proc/update_atom_languages()
|
||||
var/datum/language_holder/LH = get_language_holder()
|
||||
return LH.update_atom_languages(src)
|
||||
|
||||
/* End language procs */
|
||||
|
||||
|
||||
/atom/movable/proc/ConveyorMove(movedir)
|
||||
set waitfor = FALSE
|
||||
if(!anchored && has_gravity())
|
||||
|
||||
@@ -396,7 +396,6 @@ GLOBAL_LIST_EMPTY(network_holopads)
|
||||
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
||||
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.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||
Hologram.setAnchored(TRUE)//So space wind cannot drag it.
|
||||
@@ -555,9 +554,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
Hologram.alpha = 170
|
||||
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
|
||||
Hologram.dir = SOUTH //for now
|
||||
Hologram.grant_all_languages(omnitongue=TRUE)
|
||||
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.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
|
||||
Hologram.setAnchored(TRUE)//So space wind cannot drag it.
|
||||
@@ -649,7 +647,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
return
|
||||
if(HOLORECORD_LANGUAGE)
|
||||
var/datum/language_holder/holder = replay_holo.get_language_holder()
|
||||
holder.selected_default_language = entry[2]
|
||||
holder.selected_language = entry[2]
|
||||
if(HOLORECORD_PRESET)
|
||||
var/preset_type = entry[2]
|
||||
var/datum/preset_holoimage/H = new preset_type
|
||||
@@ -672,6 +670,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
updateDialog()
|
||||
|
||||
/obj/effect/overlay/holo_pad_hologram
|
||||
initial_language_holder = /datum/language_holder/universal
|
||||
var/mob/living/Impersonation
|
||||
var/datum/holocall/HC
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
obj/source, // the originating radio
|
||||
frequency, // the frequency the signal is taking place on
|
||||
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
|
||||
spans // the list of spans applied to the message
|
||||
)
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
if(!spans)
|
||||
spans = list(M.speech_span)
|
||||
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)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
|
||||
@@ -519,7 +519,9 @@
|
||||
S.name = name
|
||||
S.ckey = C.ckey
|
||||
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
|
||||
S.AddElement(/datum/element/ghost_role_eligibility,penalize_on_ghost = TRUE)
|
||||
START_PROCESSING(SSprocessing,src)
|
||||
var/input = stripped_input(S,"What are you named?", ,"", MAX_NAME_LEN)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere?
|
||||
new_spawn.socks = "Nude"
|
||||
new_spawn.update_body(TRUE)
|
||||
new_spawn.language_holder.selected_language = /datum/language/sylvan
|
||||
|
||||
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
|
||||
|
||||
@@ -63,10 +64,6 @@
|
||||
else
|
||||
to_chat(new_spawn, "<span class='userdanger'>You have been born outside of your natural home! Whether you decide to return home, or make due with your new home is your own decision.</span>")
|
||||
|
||||
new_spawn.grant_language(/datum/language/draconic)
|
||||
var/datum/language_holder/holder = new_spawn.get_language_holder()
|
||||
holder.selected_default_language = /datum/language/draconic
|
||||
|
||||
//Ash walkers on birth understand how to make bone bows, bone arrows and ashen arrows
|
||||
|
||||
new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_arrow)
|
||||
|
||||
@@ -25,7 +25,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
|
||||
return
|
||||
spans |= speech_span
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
language = get_selected_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/source)
|
||||
|
||||
@@ -10,7 +10,12 @@
|
||||
/obj/item/organ/heart/gland/slime/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
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()
|
||||
to_chat(owner, "<span class='warning'>You feel nauseated!</span>")
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/poweron_feed = FALSE // Am I feeding?
|
||||
var/poweron_masquerade = FALSE
|
||||
// STATS
|
||||
var/bloodsucker_level
|
||||
var/bloodsucker_level
|
||||
var/bloodsucker_level_unspent = 1
|
||||
var/regen_rate = 0.3 // How fast do I regenerate?
|
||||
var/additional_regen // How much additional blood regen we gain from bonuses such as high blood.
|
||||
@@ -209,7 +209,7 @@
|
||||
// Physiology
|
||||
CheckVampOrgans() // Heart, Eyes
|
||||
// Language
|
||||
owner.current.grant_language(/datum/language/vampiric)
|
||||
owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
|
||||
owner.hasSoul = FALSE // If false, renders the character unable to sell their soul.
|
||||
owner.isholy = FALSE // is this person a chaplain or admin role allowed to use bibles
|
||||
// Disabilities
|
||||
@@ -246,7 +246,7 @@
|
||||
// Update Health
|
||||
owner.current.setMaxHealth(100)
|
||||
// Language
|
||||
owner.current.remove_language(/datum/language/vampiric)
|
||||
owner.current.remove_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_BLOODSUCKER)
|
||||
// Soul
|
||||
if (owner.soulOwner == owner) // Return soul, if *I* own it.
|
||||
owner.hasSoul = TRUE
|
||||
@@ -649,10 +649,10 @@
|
||||
return TRUE
|
||||
// Check 3) If I am a BLOODSUCKER, then are they my Vassal?
|
||||
if (mob_B && atom_V && (atom_V in mob_B.vassals))
|
||||
return TRUE
|
||||
return TRUE
|
||||
// Check 4) If we are both VASSAL, then do we have the same master?
|
||||
if (atom_V && mob_V && atom_V.master == mob_V.master)
|
||||
return TRUE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -710,7 +710,7 @@
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
|
||||
/obj/screen/bloodsucker/proc/update_counter(value, valuecolor)
|
||||
invisibility = 0
|
||||
invisibility = 0
|
||||
|
||||
/obj/screen/bloodsucker/blood_counter
|
||||
icon = 'icons/mob/actions/bloodsucker.dmi'
|
||||
@@ -758,7 +758,7 @@
|
||||
|
||||
/obj/screen/bloodsucker/sunlight_counter/update_counter(value, valuecolor)
|
||||
..()
|
||||
maptext = "<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>"
|
||||
maptext = "<div align='center' valign='bottom' style='position:relative; top:0px; left:6px'><font color='[valuecolor]'>[value]</font></div>"
|
||||
|
||||
/datum/antagonist/bloodsucker/proc/count_vassals(datum/mind/master)
|
||||
var/datum/antagonist/bloodsucker/B = master.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
objectives += vassal_objective
|
||||
objectives_given += vassal_objective
|
||||
give_thrall_eyes()
|
||||
owner.current.grant_language(/datum/language/vampiric)
|
||||
owner.current.grant_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_VASSAL)
|
||||
// Add Antag HUD
|
||||
update_vassal_icons_added(owner.current, "vassal")
|
||||
. = ..()
|
||||
@@ -81,7 +81,7 @@
|
||||
qdel(O)
|
||||
objectives_given = list()
|
||||
remove_thrall_eyes()
|
||||
owner.current.remove_language(/datum/language/vampiric)
|
||||
owner.current.remove_language(/datum/language/vampiric, TRUE, TRUE, LANGUAGE_VASSAL)
|
||||
// Clear Antag HUD
|
||||
update_vassal_icons_removed(owner.current)
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
create_initial_profile()
|
||||
if(give_objectives)
|
||||
forge_objectives()
|
||||
owner.current.grant_all_languages(FALSE, FALSE, TRUE) //Grants omnitongue. We are able to transform our body after all.
|
||||
remove_clownmut()
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@
|
||||
if(user.nutrition < NUTRITION_LEVEL_WELL_FED)
|
||||
user.nutrition = min((user.nutrition + target.nutrition), NUTRITION_LEVEL_WELL_FED)
|
||||
|
||||
if(target.mind)//if the victim has got a mind
|
||||
// Absorb a lizard, speak Draconic.
|
||||
user.copy_known_languages_from(target)
|
||||
// Absorb a lizard, speak Draconic.
|
||||
user.copy_languages(target, LANGUAGE_ABSORB)
|
||||
|
||||
if(target.mind && user.mind)//if the victim and user have minds
|
||||
target.mind.show_memory(user, 0) //I can read your mind, kekeke. Output all their notes.
|
||||
|
||||
//Some of target's recent speech, so the changeling can attempt to imitate them better.
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
laws = new /datum/ai_laws/ratvar()
|
||||
braintype = picked_name
|
||||
GLOB.all_clockwork_objects += src
|
||||
brainmob.add_blocked_language(subtypesof(/datum/language) - /datum/language/ratvar, LANGUAGE_CLOCKIE)
|
||||
|
||||
/obj/item/mmi/posibrain/soul_vessel/Destroy()
|
||||
GLOB.all_clockwork_objects -= src
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
current = mob_override
|
||||
GLOB.all_clockwork_mobs += current
|
||||
current.faction |= "ratvar"
|
||||
current.grant_language(/datum/language/ratvar)
|
||||
current.grant_language(/datum/language/ratvar, TRUE, TRUE, LANGUAGE_CLOCKIE)
|
||||
current.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
|
||||
if(issilicon(current))
|
||||
var/mob/living/silicon/S = current
|
||||
@@ -102,6 +102,7 @@
|
||||
R.module.rebuild_modules()
|
||||
else if(isAI(S))
|
||||
var/mob/living/silicon/ai/A = S
|
||||
A.add_blocked_language(subtypesof(/datum/language) - /datum/language/ratvar, LANGUAGE_CLOCKIE)
|
||||
A.can_be_carded = FALSE
|
||||
A.requires_power = POWER_REQ_CLOCKCULT
|
||||
var/list/AI_frame = list(mutable_appearance('icons/mob/clockwork_mobs.dmi', "aiframe")) //make the AI's cool frame
|
||||
@@ -142,7 +143,7 @@
|
||||
current = mob_override
|
||||
GLOB.all_clockwork_mobs -= current
|
||||
current.faction -= "ratvar"
|
||||
current.remove_language(/datum/language/ratvar)
|
||||
current.remove_language(/datum/language/ratvar, TRUE, TRUE, LANGUAGE_CLOCKIE)
|
||||
current.clear_alert("clockinfo")
|
||||
for(var/datum/action/innate/clockwork_armaments/C in owner.current.actions) //Removes any bound clockwork armor
|
||||
qdel(C)
|
||||
@@ -152,6 +153,7 @@
|
||||
var/mob/living/silicon/S = current
|
||||
if(isAI(S))
|
||||
var/mob/living/silicon/ai/A = S
|
||||
A.remove_blocked_language(subtypesof(/datum/language) - /datum/language/ratvar, LANGUAGE_CLOCKIE)
|
||||
A.can_be_carded = initial(A.can_be_carded)
|
||||
A.requires_power = initial(A.requires_power)
|
||||
A.cut_overlays()
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
if(mob_override)
|
||||
current = mob_override
|
||||
current.faction |= "cult"
|
||||
current.grant_language(/datum/language/narsie)
|
||||
current.grant_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST)
|
||||
if(!cult_team?.cult_master)
|
||||
vote.Grant(current)
|
||||
communion.Grant(current)
|
||||
@@ -134,7 +134,7 @@
|
||||
if(mob_override)
|
||||
current = mob_override
|
||||
current.faction -= "cult"
|
||||
current.remove_language(/datum/language/narsie)
|
||||
current.remove_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST)
|
||||
vote.Remove(current)
|
||||
communion.Remove(current)
|
||||
magic.Remove(current)
|
||||
|
||||
@@ -527,7 +527,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
|
||||
/datum/antagonist/devil/apply_innate_effects(mob/living/mob_override)
|
||||
give_appropriate_spells()
|
||||
owner.current.grant_all_languages(TRUE)
|
||||
owner.current.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_DEVIL)
|
||||
update_hud()
|
||||
.=..()
|
||||
|
||||
@@ -536,6 +536,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
var/obj/effect/proc_holder/spell/S = X
|
||||
if(is_type_in_typecache(S, devil_spells))
|
||||
owner.RemoveSpell(S)
|
||||
owner.current.remove_all_languages(LANGUAGE_DEVIL)
|
||||
.=..()
|
||||
|
||||
/datum/antagonist/devil/proc/printdevilinfo()
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
/mob/living/carbon/true_devil/Initialize()
|
||||
create_bodyparts() //initialize bodyparts
|
||||
create_internal_organs()
|
||||
grant_all_languages(omnitongue=TRUE)
|
||||
grant_all_languages()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/true_devil/create_internal_organs()
|
||||
|
||||
@@ -65,5 +65,5 @@
|
||||
/datum/traitor_class/ai/finalize_traitor(datum/antagonist/traitor/T)
|
||||
T.add_law_zero()
|
||||
T.owner.current.playsound_local(get_turf(T.owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
T.owner.current.grant_language(/datum/language/codespeak)
|
||||
T.owner.current.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MALF)
|
||||
return FALSE
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
newstruct.cancel_camera()
|
||||
|
||||
|
||||
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/U, vic = 0)
|
||||
/obj/item/soulstone/proc/init_shade(mob/living/carbon/human/T, mob/user, vic = 0)
|
||||
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
|
||||
T.stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
T.invisibility = INVISIBILITY_ABSTRACT
|
||||
@@ -245,20 +245,23 @@
|
||||
S.name = "Shade of [T.real_name]"
|
||||
S.real_name = "Shade of [T.real_name]"
|
||||
T.transfer_ckey(S)
|
||||
S.language_holder = U.language_holder.copy(S)
|
||||
if(U)
|
||||
S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation
|
||||
if(U && iscultist(U))
|
||||
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)
|
||||
S.faction |= "[REF(user)]" //Add the master as a faction, allowing inter-mob cooperation
|
||||
if(user && iscultist(user))
|
||||
SSticker.mode.add_cultist(S.mind, 0)
|
||||
S.cancel_camera()
|
||||
name = "soulstone: Shade of [T.real_name]"
|
||||
icon_state = "soulstone2"
|
||||
if(U && (iswizard(U) || usability))
|
||||
to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in [U.p_their()] goals at all costs.")
|
||||
else if(U && iscultist(U))
|
||||
if(user && (iswizard(user) || usability))
|
||||
to_chat(S, "Your soul has been captured! You are now bound to [user.real_name]'s will. Help [user.p_them()] succeed in [user.p_their()] goals at all costs.")
|
||||
else if(user && iscultist(user))
|
||||
to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.")
|
||||
if(vic && U)
|
||||
to_chat(U, "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been ripped from [T.p_their()] body and stored within the soul stone.")
|
||||
if(vic && user)
|
||||
to_chat(user, "<span class='info'><b>Capture successful!</b>:</span> [T.real_name]'s soul has been ripped from [T.p_their()] body and stored within the soul stone.")
|
||||
|
||||
|
||||
/obj/item/soulstone/proc/getCultGhost(mob/living/carbon/human/T, mob/U)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
role_name = "random animal"
|
||||
var/animals = 1
|
||||
var/one = "one"
|
||||
/// Blacklisted mob_biotypes - Hey can we like, not have player controlled megafauna?
|
||||
/// Blacklisted mob_biotypes - Hey can we like, not have player controlled megafauna?
|
||||
var/blacklisted_biotypes = MOB_EPIC
|
||||
fakeable = TRUE
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
SG.transfer_ckey(SA, FALSE)
|
||||
|
||||
SA.grant_all_languages(TRUE)
|
||||
SA.grant_all_languages(TRUE, FALSE, FALSE)
|
||||
|
||||
SA.sentience_act()
|
||||
|
||||
|
||||
@@ -865,7 +865,7 @@
|
||||
var/translated = FALSE
|
||||
if(speaker && message)
|
||||
if(raw_message)
|
||||
if(message_langs != get_default_language())
|
||||
if(message_langs != get_selected_language())
|
||||
translated = TRUE
|
||||
set_pin_data(IC_OUTPUT, 1, speaker.GetVoice())
|
||||
set_pin_data(IC_OUTPUT, 2, raw_message)
|
||||
|
||||
@@ -41,4 +41,4 @@
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
H.grant_all_languages(omnitongue=TRUE)
|
||||
H.grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_CURATOR)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
return
|
||||
|
||||
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)
|
||||
|
||||
@@ -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='italics'>You hear smacking.</span>")
|
||||
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='italics'>You hear smacking.</span>")
|
||||
M.grant_language(/datum/language/codespeak)
|
||||
M.grant_language(/datum/language/codespeak, TRUE, TRUE, LANGUAGE_MIND)
|
||||
use_charge(user)
|
||||
|
||||
/obj/item/codespeak_manual/proc/use_charge(mob/user)
|
||||
|
||||
@@ -1,149 +1,332 @@
|
||||
/datum/language_holder
|
||||
var/list/languages = list(/datum/language/common)
|
||||
var/list/shadow_languages = list()
|
||||
var/only_speaks_language = null
|
||||
var/selected_default_language = null
|
||||
var/datum/language_menu/language_menu
|
||||
/*!Language holders will either exist in an atom/movable or a mind. 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
|
||||
transformations and other events that cause new languages to become available.
|
||||
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
|
||||
/// 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
|
||||
|
||||
/datum/language_holder/New(owner)
|
||||
src.owner = owner
|
||||
|
||||
languages = typecacheof(languages)
|
||||
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(ismovable(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(ismovable(owner))
|
||||
. = owner
|
||||
else if(istype(owner, /datum/mind))
|
||||
/// Initializes, and copies in the languages from the current atom if available.
|
||||
/datum/language_holder/New(_owner)
|
||||
owner = _owner
|
||||
if(istype(owner, /datum/mind))
|
||||
var/datum/mind/M = owner
|
||||
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
|
||||
languages = list(/datum/language/xenocommon)
|
||||
|
||||
/datum/language_holder/monkey
|
||||
languages = list(/datum/language/monkey)
|
||||
|
||||
/datum/language_holder/swarmer
|
||||
languages = list(/datum/language/swarmer)
|
||||
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))
|
||||
|
||||
/datum/language_holder/clockmob
|
||||
languages = list(/datum/language/common, /datum/language/ratvar)
|
||||
only_speaks_language = /datum/language/ratvar
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/ratvar = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/ratvar = list(LANGUAGE_ATOM))
|
||||
|
||||
/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
|
||||
languages = list(/datum/language/common, /datum/language/drone, /datum/language/machine)
|
||||
only_speaks_language = /datum/language/drone
|
||||
understood_languages = list(/datum/language/drone = list(LANGUAGE_ATOM),
|
||||
/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
|
||||
only_speaks_language = null
|
||||
blocked_languages = null
|
||||
|
||||
/datum/language_holder/dwarf
|
||||
languages = list(/datum/language/common, /datum/language/dwarf)
|
||||
only_speaks_language = /datum/language/dwarf
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/dwarf = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/dwarf = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/slime
|
||||
languages = list(/datum/language/common, /datum/language/slime)
|
||||
only_speaks_language = /datum/language/slime
|
||||
/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))
|
||||
|
||||
/datum/language_holder/lightbringer
|
||||
// TODO change to a lightbringer specific sign language
|
||||
languages = list(/datum/language/slime)
|
||||
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))
|
||||
|
||||
/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/sylvan
|
||||
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/synthetic
|
||||
languages = list(/datum/language/common)
|
||||
shadow_languages = list(/datum/language/common, /datum/language/machine, /datum/language/draconic, /datum/language/slime, /datum/language/dwarf)
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/machine = list(LANGUAGE_ATOM),
|
||||
/datum/language/draconic = list(LANGUAGE_ATOM),
|
||||
/datum/language/slime = list(LANGUAGE_ATOM),
|
||||
/datum/language/dwarf = 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/slime = list(LANGUAGE_ATOM),
|
||||
/datum/language/dwarf = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/venus
|
||||
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
|
||||
/datum/language/sylvan = list(LANGUAGE_ATOM))
|
||||
spoken_languages = list(/datum/language/sylvan = list(LANGUAGE_ATOM))
|
||||
|
||||
/datum/language_holder/empty
|
||||
languages = list()
|
||||
shadow_languages = list()
|
||||
understood_languages = list()
|
||||
spoken_languages = list()
|
||||
|
||||
/datum/language_holder/universal/New()
|
||||
..()
|
||||
grant_all_languages(omnitongue=TRUE)
|
||||
grant_all_languages()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/datum/language_menu
|
||||
var/datum/language_holder/language_holder
|
||||
|
||||
/datum/language_menu/New(language_holder)
|
||||
src.language_holder = language_holder
|
||||
/datum/language_menu/New(_language_holder)
|
||||
language_holder = _language_holder
|
||||
|
||||
/datum/language_menu/Destroy()
|
||||
language_holder = null
|
||||
@@ -24,21 +24,20 @@
|
||||
data["is_living"] = FALSE
|
||||
|
||||
data["languages"] = list()
|
||||
for(var/ld in GLOB.all_languages)
|
||||
var/result = language_holder.has_language(ld)
|
||||
for(var/lang in GLOB.all_languages)
|
||||
var/result = language_holder.has_language(lang) || language_holder.has_language(lang, TRUE)
|
||||
if(!result)
|
||||
continue
|
||||
var/shadow = result == LANGUAGE_SHADOWED
|
||||
var/datum/language/LD = ld
|
||||
var/datum/language/language = lang
|
||||
var/list/L = list()
|
||||
|
||||
L["name"] = initial(LD.name)
|
||||
L["desc"] = initial(LD.desc)
|
||||
L["key"] = initial(LD.key)
|
||||
L["is_default"] = (LD == language_holder.selected_default_language)
|
||||
L["shadow"] = shadow
|
||||
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_in_language(LD)
|
||||
L["can_speak"] = AM.can_speak_language(language)
|
||||
L["can_understand"] = AM.has_language(language)
|
||||
|
||||
data["languages"] += list(L)
|
||||
|
||||
@@ -47,15 +46,15 @@
|
||||
data["omnitongue"] = language_holder.omnitongue
|
||||
|
||||
data["unknown_languages"] = list()
|
||||
for(var/ld in GLOB.all_languages)
|
||||
if(language_holder.has_language(ld))
|
||||
for(var/lang in GLOB.all_languages)
|
||||
if(language_holder.has_language(lang) || language_holder.has_language(lang, TRUE))
|
||||
continue
|
||||
var/datum/language/LD = ld
|
||||
var/datum/language/language = lang
|
||||
var/list/L = list()
|
||||
|
||||
L["name"] = initial(LD.name)
|
||||
L["desc"] = initial(LD.desc)
|
||||
L["key"] = initial(LD.key)
|
||||
L["name"] = initial(language.name)
|
||||
L["desc"] = initial(language.desc)
|
||||
L["key"] = initial(language.key)
|
||||
|
||||
data["unknown_languages"] += list(L)
|
||||
return data
|
||||
@@ -68,27 +67,51 @@
|
||||
|
||||
var/language_name = params["language_name"]
|
||||
var/datum/language/language_datum
|
||||
for(var/ld in GLOB.all_languages)
|
||||
var/datum/language/LD = ld
|
||||
if(language_name == initial(LD.name))
|
||||
language_datum = LD
|
||||
for(var/lang in GLOB.all_languages)
|
||||
var/datum/language/language = lang
|
||||
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_in_language(language_datum))
|
||||
language_holder.selected_default_language = language_datum
|
||||
if(language_datum && AM.can_speak_language(language_datum))
|
||||
language_holder.selected_language = language_datum
|
||||
. = TRUE
|
||||
if("grant_language")
|
||||
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)
|
||||
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)].")
|
||||
. = TRUE
|
||||
if("remove_language")
|
||||
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)
|
||||
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)].")
|
||||
|
||||
19
code/modules/language/sylvan.dm
Normal file
19
code/modules/language/sylvan.dm
Normal file
@@ -0,0 +1,19 @@
|
||||
// The language of the vinebings. Yes, it's a shameless ripoff of elvish.
|
||||
/datum/language/sylvan
|
||||
name = "Sylvan"
|
||||
desc = "A complicated, ancient language spoken by vine like beings."
|
||||
speech_verb = "expresses"
|
||||
ask_verb = "inquires"
|
||||
exclaim_verb = "declares"
|
||||
key = "h"
|
||||
space_chance = 20
|
||||
syllables = list(
|
||||
"fii", "sii", "rii", "rel", "maa", "ala", "san", "tol", "tok", "dia", "eres",
|
||||
"fal", "tis", "bis", "qel", "aras", "losk", "rasa", "eob", "hil", "tanl", "aere",
|
||||
"fer", "bal", "pii", "dala", "ban", "foe", "doa", "cii", "uis", "mel", "wex",
|
||||
"incas", "int", "elc", "ent", "aws", "qip", "nas", "vil", "jens", "dila", "fa",
|
||||
"la", "re", "do", "ji", "ae", "so", "qe", "ce", "na", "mo", "ha", "yu"
|
||||
)
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "lily"
|
||||
default_priority = 90
|
||||
@@ -564,7 +564,7 @@
|
||||
|
||||
/obj/item/book_of_babel/attack_self(mob/user)
|
||||
to_chat(user, "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.")
|
||||
user.grant_all_languages(omnitongue=TRUE)
|
||||
user.grant_all_languages()
|
||||
new /obj/effect/decal/cleanable/ash(get_turf(user))
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -25,10 +25,3 @@
|
||||
/mob/living/brain/treat_message(message)
|
||||
message = capitalize(message)
|
||||
return message
|
||||
|
||||
/mob/living/brain/could_speak_in_language(datum/language/dt)
|
||||
if(istype(container, /obj/item/mmi/posibrain/soul_vessel))
|
||||
// soul vessels can only speak ratvarian.
|
||||
. = ispath(dt, /datum/language/ratvar)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -49,6 +49,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/blacklisted = 0 //Flag to exclude from green slime core species.
|
||||
var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!"
|
||||
var/say_mod = "says" // affects the speech message
|
||||
var/species_language_holder = /datum/language_holder
|
||||
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. 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/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
gib_types = /obj/effect/gibspawner/robot
|
||||
damage_overlay_type = "synth"
|
||||
mutanttongue = /obj/item/organ/tongue/robot
|
||||
species_language_holder = /datum/language_holder/synthetic
|
||||
limbs_id = "synth"
|
||||
|
||||
/datum/species/android/on_species_gain(mob/living/carbon/C)
|
||||
|
||||
@@ -17,6 +17,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
|
||||
mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
|
||||
mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
|
||||
species_language_holder = /datum/language_holder/dwarf
|
||||
|
||||
/mob/living/carbon/human/species/dwarf //species admin spawn path
|
||||
race = /datum/species/dwarf //and the race the path is set to.
|
||||
@@ -30,7 +31,6 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
. = ..()
|
||||
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.grant_language(/datum/language/dwarf)
|
||||
H.facial_hair_style = dwarf_hair
|
||||
H.update_hair()
|
||||
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
|
||||
@@ -40,7 +40,6 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
. = ..()
|
||||
H.transform = H.transform.Scale(1, 1.25) //And we undo it.
|
||||
UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
|
||||
H.remove_language(/datum/language/dwarf)
|
||||
|
||||
//Dwarf Name stuff
|
||||
/proc/dwarf_name() //hello caller: my name is urist mcuristurister
|
||||
|
||||
@@ -21,20 +21,19 @@
|
||||
coldmod = 6 // = 3x cold damage
|
||||
heatmod = 0.5 // = 1/4x heat damage
|
||||
burnmod = 0.5 // = 1/2x generic burn damage
|
||||
species_language_holder = /datum/language_holder/jelly
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
if(regenerate_limbs)
|
||||
regenerate_limbs.Remove(C)
|
||||
if(slime_change) //CIT CHANGE
|
||||
slime_change.Remove(C) //CIT CHANGE
|
||||
C.remove_language(/datum/language/slime)
|
||||
C.faction -= "slime"
|
||||
..()
|
||||
C.faction -= "slime"
|
||||
|
||||
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
C.grant_language(/datum/language/slime)
|
||||
if(ishuman(C))
|
||||
regenerate_limbs = new
|
||||
regenerate_limbs.Grant(C)
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
disliked_food = GRAIN | DAIRY
|
||||
liked_food = GROSS | MEAT
|
||||
inert_mutation = FIREBREATH
|
||||
|
||||
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
||||
H.grant_language(/datum/language/draconic)
|
||||
species_language_holder = /datum/language_holder/lizard
|
||||
|
||||
/datum/species/lizard/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
@@ -86,6 +84,7 @@
|
||||
mutantlungs = /obj/item/organ/lungs/ashwalker
|
||||
burnmod = 0.9
|
||||
brutemod = 0.9
|
||||
species_language_holder = /datum/language_holder/lizard/ash
|
||||
|
||||
/datum/species/lizard/ashwalker/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
|
||||
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision/mushroom
|
||||
var/datum/martial_art/mushpunch/mush
|
||||
|
||||
/datum/species/mush/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
||||
H.grant_language(/datum/language/mushroom) //pomf pomf
|
||||
species_language_holder = /datum/language_holder/mushroom
|
||||
|
||||
/datum/species/mush/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant
|
||||
disliked_food = MEAT | DAIRY
|
||||
liked_food = VEGETABLES | FRUIT | GRAIN
|
||||
species_language_holder = /datum/language_holder/sylvan
|
||||
var/light_nutrition_gain_factor = 10
|
||||
var/light_toxheal = 1
|
||||
var/light_oxyheal = 1
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
|
||||
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
|
||||
species_language_holder = /datum/language_holder/synthetic
|
||||
|
||||
/datum/species/synth/military
|
||||
name = "Military Synth"
|
||||
|
||||
@@ -34,12 +34,11 @@
|
||||
/mob/living/carbon/human/set_drugginess(amount)
|
||||
..()
|
||||
if(!amount)
|
||||
remove_language(/datum/language/beachbum)
|
||||
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||
|
||||
/mob/living/carbon/human/adjust_drugginess(amount)
|
||||
..()
|
||||
if(!dna.check_mutation(STONER))
|
||||
if(druggy)
|
||||
grant_language(/datum/language/beachbum)
|
||||
else
|
||||
remove_language(/datum/language/beachbum)
|
||||
if(druggy)
|
||||
grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||
else
|
||||
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
return 0
|
||||
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)
|
||||
if(T)
|
||||
. = T.could_speak_in_language(dt)
|
||||
return T.could_speak_language(language)
|
||||
else
|
||||
. = initial(dt.flags) & TONGUELESS_SPEECH
|
||||
return initial(language.flags) & TONGUELESS_SPEECH
|
||||
@@ -98,8 +98,6 @@
|
||||
|
||||
var/datum/riding/riding_datum
|
||||
|
||||
var/datum/language/selected_default_language
|
||||
|
||||
var/last_words //used for database logging
|
||||
|
||||
var/list/obj/effect/proc_holder/abilities = list()
|
||||
|
||||
@@ -133,7 +133,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
var/datum/language/message_language = get_message_language(message)
|
||||
if(message_language)
|
||||
// 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
|
||||
message = copytext_char(message, 3)
|
||||
|
||||
@@ -141,7 +141,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
message = trim_left(message)
|
||||
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
language = get_selected_language()
|
||||
|
||||
// Detection of language needs to be before inherent channels, because
|
||||
// AIs use inherent channels for the holopad. Most inherent channels
|
||||
@@ -415,11 +415,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)
|
||||
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
|
||||
|
||||
/mob/living/get_language_holder(shadow=TRUE)
|
||||
if(mind && shadow)
|
||||
// Mind language holders shadow mob holders.
|
||||
. = mind.get_language_holder()
|
||||
if(.)
|
||||
return .
|
||||
|
||||
/mob/living/get_language_holder(get_minds = TRUE)
|
||||
if(get_minds && mind)
|
||||
return mind.get_language_holder()
|
||||
. = ..()
|
||||
|
||||
@@ -171,10 +171,3 @@
|
||||
|
||||
#undef VOX_DELAY
|
||||
#endif
|
||||
|
||||
/mob/living/silicon/ai/could_speak_in_language(datum/language/dt)
|
||||
if(is_servant_of_ratvar(src))
|
||||
// Ratvarian AIs can only speak Ratvarian
|
||||
. = ispath(dt, /datum/language/ratvar)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -267,9 +267,8 @@
|
||||
if(href_list["toggle"])
|
||||
encryptmod = TRUE
|
||||
if("translator")
|
||||
if(href_list["toggle"])
|
||||
grant_all_languages(TRUE)
|
||||
// this is PERMAMENT.
|
||||
if(href_list["toggle"]) //This is permanent.
|
||||
grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE)
|
||||
if("doorjack")
|
||||
if(href_list["jack"])
|
||||
if(cable && cable.machine)
|
||||
|
||||
@@ -911,7 +911,6 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
bot_name = name
|
||||
name = paicard.pai.name
|
||||
faction = user.faction.Copy()
|
||||
language_holder = paicard.pai.language_holder.copy(src)
|
||||
log_combat(user, paicard.pai, "uploaded to [bot_name],")
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -425,6 +425,7 @@
|
||||
mind.transfer_to(new_xeno)
|
||||
else
|
||||
transfer_ckey(new_xeno)
|
||||
update_atom_languages()
|
||||
|
||||
to_chat(new_xeno, "<B>You are now an alien.</B>")
|
||||
. = new_xeno
|
||||
|
||||
@@ -249,7 +249,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
add_overlay(causality_field, TRUE)
|
||||
|
||||
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)
|
||||
if(damage < explosion_point) // Cutting it a bit close there engineers
|
||||
radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel)
|
||||
|
||||
@@ -228,7 +228,6 @@
|
||||
|
||||
if(!new_mob)
|
||||
return
|
||||
new_mob.grant_language(/datum/language/common)
|
||||
|
||||
// Some forms can still wear some items
|
||||
for(var/obj/item/W in contents)
|
||||
|
||||
@@ -959,9 +959,10 @@ datum/status_effect/stabilized/blue/on_remove()
|
||||
familiar = new linked.mob_type(get_turf(owner.loc))
|
||||
familiar.name = linked.mob_name
|
||||
familiar.del_on_death = TRUE
|
||||
familiar.copy_known_languages_from(owner, FALSE)
|
||||
familiar.copy_languages(owner, LANGUAGE_MASTER)
|
||||
if(linked.saved_mind)
|
||||
linked.saved_mind.transfer_to(familiar)
|
||||
familiar.update_atom_languages()
|
||||
familiar.ckey = linked.saved_mind.key
|
||||
else
|
||||
if(familiar.mind)
|
||||
|
||||
@@ -684,7 +684,7 @@
|
||||
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(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)
|
||||
qdel(src)
|
||||
else
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
assignedrole = "Lavaland Syndicate"
|
||||
|
||||
/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
|
||||
name = "Lavaland Syndicate Agent"
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
owner.RegisterSignal(owner, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/tongue/could_speak_in_language(datum/language/dt)
|
||||
return is_type_in_typecache(dt, languages_possible)
|
||||
/obj/item/organ/tongue/could_speak_language(language)
|
||||
return is_type_in_typecache(language, languages_possible)
|
||||
|
||||
/obj/item/organ/tongue/lizard
|
||||
name = "forked tongue"
|
||||
@@ -141,7 +141,7 @@
|
||||
/obj/item/organ/tongue/abductor/handle_speech(datum/source, list/speech_args)
|
||||
//Hacks
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
var/mob/living/carbon/human/user = usr
|
||||
var/mob/living/carbon/human/user = source
|
||||
var/rendered = "<span class='abductor'><b>[user.name]:</b> [message]</span>"
|
||||
user.log_talk(message, LOG_SAY, tag="abductor")
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
@@ -260,7 +260,7 @@
|
||||
maxHealth = 100 //RoboTongue!
|
||||
var/electronics_magic = TRUE
|
||||
|
||||
/obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt)
|
||||
/obj/item/organ/tongue/robot/could_speak_language(language)
|
||||
return ..() || electronics_magic
|
||||
|
||||
/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// The language of the vinebings. Yes, it's a shameless ripoff of elvish.
|
||||
/datum/language/sylvan
|
||||
name = "Sylvan"
|
||||
desc = "A complicated, ancient language spoken by vine like beings."
|
||||
speech_verb = "expresses"
|
||||
ask_verb = "inquires"
|
||||
exclaim_verb = "declares"
|
||||
key = "h"
|
||||
space_chance = 20
|
||||
syllables = list(
|
||||
"fii", "sii", "rii", "rel", "maa", "ala", "san", "tol", "tok", "dia", "eres",
|
||||
"fal", "tis", "bis", "qel", "aras", "losk", "rasa", "eob", "hil", "tanl", "aere",
|
||||
"fer", "bal", "pii", "dala", "ban", "foe", "doa", "cii", "uis", "mel", "wex",
|
||||
"incas", "int", "elc", "ent", "aws", "qip", "nas", "vil", "jens", "dila", "fa",
|
||||
"la", "re", "do", "ji", "ae", "so", "qe", "ce", "na", "mo", "ha", "yu"
|
||||
)
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "lily"
|
||||
default_priority = 90
|
||||
|
||||
/datum/language_holder/venus
|
||||
languages = list(/datum/language/common, /datum/language/sylvan, /datum/language/machine)
|
||||
only_speaks_language = /datum/language/sylvan
|
||||
|
||||
@@ -110,7 +110,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
|
||||
|
||||
to_chat(M, "<span class='warning'>You feel a strange sensation building in your mind as you realise there's two of you, before you get a chance to think about it, you suddenly split from your old body, and find yourself face to face with yourself.</span>")
|
||||
M.visible_message("[M] suddenly shudders, and splits into two identical twins!")
|
||||
SM.copy_known_languages_from(M, FALSE)
|
||||
SM.copy_languages(M, LANGUAGE_MIND)
|
||||
playerClone = TRUE
|
||||
M.next_move_modifier = 1
|
||||
M.nutrition -= 500
|
||||
|
||||
@@ -2143,6 +2143,7 @@
|
||||
#include "code\modules\language\ratvarian.dm"
|
||||
#include "code\modules\language\slime.dm"
|
||||
#include "code\modules\language\swarmer.dm"
|
||||
#include "code\modules\language\sylvan.dm"
|
||||
#include "code\modules\language\vampiric.dm"
|
||||
#include "code\modules\language\xenocommon.dm"
|
||||
#include "code\modules\library\lib_codex_gigas.dm"
|
||||
@@ -3342,7 +3343,6 @@
|
||||
#include "modular_citadel\code\modules\custom_loadout\custom_items.dm"
|
||||
#include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm"
|
||||
#include "modular_citadel\code\modules\custom_loadout\read_from_file.dm"
|
||||
#include "modular_citadel\code\modules\language\sylvan.dm"
|
||||
#include "modular_citadel\code\modules\mentor\dementor.dm"
|
||||
#include "modular_citadel\code\modules\mentor\follow.dm"
|
||||
#include "modular_citadel\code\modules\mentor\mentor.dm"
|
||||
|
||||
@@ -86,7 +86,9 @@ export const LanguageMenu = props => {
|
||||
{' '}
|
||||
Key: ,{language.key}
|
||||
{' '}
|
||||
{!!language.shadow && '(gained from mob)'}
|
||||
{language.can_understand
|
||||
? 'Can understand.'
|
||||
: 'Cannot understand.'}
|
||||
{' '}
|
||||
{language.can_speak ? 'Can speak.' : 'Cannot speak.' }
|
||||
</LabeledList.Item>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user