Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit742
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -73,18 +73,26 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
dog_fashion = /datum/dog_fashion/head/clown
|
||||
var/list/clownmask_designs = list()
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat/Initialize(mapload)
|
||||
.=..()
|
||||
clownmask_designs = list(
|
||||
"True Form" = image(icon = src.icon, icon_state = "clown"),
|
||||
"The Feminist" = image(icon = src.icon, icon_state = "sexyclown"),
|
||||
"The Jester" = image(icon = src.icon, icon_state = "chaos"),
|
||||
"The Madman" = image(icon = src.icon, icon_state = "joker"),
|
||||
"The Rainbow Color" = image(icon = src.icon, icon_state = "rainbow")
|
||||
)
|
||||
|
||||
/obj/item/clothing/mask/gas/clown_hat/ui_action_click(mob/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
var/list/options = list()
|
||||
options["True Form"] = "clown"
|
||||
options["The Feminist"] = "sexyclown"
|
||||
options["The Madman"] = "joker"
|
||||
options["The Rainbow Color"] ="rainbow"
|
||||
var/static/list/options = list("True Form" = "clown", "The Feminist" = "sexyclown", "The Madman" = "joker",
|
||||
"The Rainbow Color" ="rainbow", "The Jester" = "chaos")
|
||||
|
||||
var/choice = input(user,"To what form do you wish to Morph this mask?","Morph Mask") in options
|
||||
var/choice = show_radial_menu(user,src, clownmask_designs, custom_check = FALSE, radius = 36, require_near = TRUE)
|
||||
|
||||
if(src && choice && !user.incapacitated() && in_range(user,src))
|
||||
icon_state = options[choice]
|
||||
@@ -93,7 +101,7 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
to_chat(user, "<span class='notice'>Your Clown Mask has now morphed into [choice], all praise the Honkmother!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/gas/sexyclown
|
||||
name = "sexy-clown wig and mask"
|
||||
@@ -113,19 +121,26 @@
|
||||
flags_cover = MASKCOVERSEYES
|
||||
resistance_flags = FLAMMABLE
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
var/list/mimemask_designs = list()
|
||||
|
||||
|
||||
/obj/item/clothing/mask/gas/mime/Initialize(mapload)
|
||||
.=..()
|
||||
mimemask_designs = list(
|
||||
"Blanc" = image(icon = src.icon, icon_state = "mime"),
|
||||
"Excité" = image(icon = src.icon, icon_state = "sexymime"),
|
||||
"Triste" = image(icon = src.icon, icon_state = "sadmime"),
|
||||
"Effrayé" = image(icon = src.icon, icon_state = "scaredmime")
|
||||
)
|
||||
|
||||
|
||||
/obj/item/clothing/mask/gas/mime/ui_action_click(mob/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
var/list/options = list()
|
||||
options["Blanc"] = "mime"
|
||||
options["Triste"] = "sadmime"
|
||||
options["Effrayé"] = "scaredmime"
|
||||
options["Excité"] ="sexymime"
|
||||
var/static/list/options = list("Blanc" = "mime", "Triste" = "sadmime", "Effrayé" = "scaredmime", "Excité" ="sexymime")
|
||||
|
||||
var/choice = input(user,"To what form do you wish to Morph this mask?","Morph Mask") in options
|
||||
var/choice = show_radial_menu(user,src, mimemask_designs, custom_check = FALSE, radius = 36, require_near = TRUE)
|
||||
|
||||
if(src && choice && !user.incapacitated() && in_range(user,src))
|
||||
icon_state = options[choice]
|
||||
@@ -134,7 +149,7 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
to_chat(user, "<span class='notice'>Your Mime Mask has now morphed into [choice]!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/gas/monkeymask
|
||||
name = "monkey mask"
|
||||
@@ -187,18 +202,25 @@
|
||||
max_integrity = 100
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
dog_fashion = null
|
||||
var/list/tikimask_designs = list()
|
||||
|
||||
|
||||
/obj/item/clothing/mask/gas/tiki_mask/Initialize(mapload)
|
||||
.=..()
|
||||
tikimask_designs = list(
|
||||
"Original Tiki" = image(icon = src.icon, icon_state = "tiki_eyebrow"),
|
||||
"Happy Tiki" = image(icon = src.icon, icon_state = "tiki_happy"),
|
||||
"Confused Tiki" = image(icon = src.icon, icon_state = "tiki_confused"),
|
||||
"Angry Tiki" = image(icon = src.icon, icon_state = "tiki_angry")
|
||||
)
|
||||
|
||||
/obj/item/clothing/mask/gas/tiki_mask/ui_action_click(mob/user)
|
||||
|
||||
var/mob/M = usr
|
||||
var/list/options = list()
|
||||
options["Original Tiki"] = "tiki_eyebrow"
|
||||
options["Happy Tiki"] = "tiki_happy"
|
||||
options["Confused Tiki"] = "tiki_confused"
|
||||
options["Angry Tiki"] ="tiki_angry"
|
||||
var/static/list/options = list("Original Tiki" = "tiki_eyebrow", "Happy Tiki" = "tiki_happy", "Confused Tiki" = "tiki_confused",
|
||||
"Angry Tiki" = "tiki_angry")
|
||||
|
||||
var/choice = input(M,"To what form do you wish to change this mask?","Morph Mask") in options
|
||||
var/choice = show_radial_menu(user,src, tikimask_designs, custom_check = FALSE, radius = 36, require_near = TRUE)
|
||||
|
||||
if(src && choice && !M.stat && in_range(M,src))
|
||||
icon_state = options[choice]
|
||||
@@ -207,4 +229,4 @@
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
to_chat(M, "The Tiki Mask has now changed into the [choice] Mask!")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
@@ -351,30 +351,40 @@
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
actions_types = list(/datum/action/item_action/adjust)
|
||||
var/list/papermask_designs = list()
|
||||
|
||||
|
||||
/obj/item/clothing/mask/paper/Initialize(mapload)
|
||||
.=..()
|
||||
papermask_designs = list(
|
||||
"Blank" = image(icon = src.icon, icon_state = "plainmask"),
|
||||
"Neutral" = image(icon = src.icon, icon_state = "neutralmask"),
|
||||
"Eyes" = image(icon = src.icon, icon_state = "eyemask"),
|
||||
"Sleeping" = image(icon = src.icon, icon_state = "sleepingmask"),
|
||||
"Heart" = image(icon = src.icon, icon_state = "heartmask"),
|
||||
"Core" = image(icon = src.icon, icon_state = "coremask"),
|
||||
"Plus" = image(icon = src.icon, icon_state = "plusmask"),
|
||||
"Square" = image(icon = src.icon, icon_state = "squaremask"),
|
||||
"Bullseye" = image(icon = src.icon, icon_state = "bullseyemask"),
|
||||
"Vertical" = image(icon = src.icon, icon_state = "verticalmask"),
|
||||
"Horizontal" = image(icon = src.icon, icon_state = "horizontalmask"),
|
||||
"X" = image(icon = src.icon, icon_state = "xmask"),
|
||||
"Bugeyes" = image(icon = src.icon, icon_state = "bugmask"),
|
||||
"Double" = image(icon = src.icon, icon_state = "doublemask"),
|
||||
"Mark" = image(icon = src.icon, icon_state = "markmask")
|
||||
)
|
||||
|
||||
/obj/item/clothing/mask/paper/ui_action_click(mob/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
return
|
||||
|
||||
var/list/options = list()
|
||||
options["Blank"] = "plainmask"
|
||||
options["Neutral"] = "neutralmask"
|
||||
options["Eyes"] = "eyemask"
|
||||
options["Sleeping"] ="sleepingmask"
|
||||
options["Heart"] = "heartmask"
|
||||
options["Core"] = "coremask"
|
||||
options["Plus"] = "plusmask"
|
||||
options["Square"] ="squaremask"
|
||||
options["Bullseye"] = "bullseyemask"
|
||||
options["Vertical"] = "verticalmask"
|
||||
options["Horizontal"] = "horizontalmask"
|
||||
options["X"] ="xmask"
|
||||
options["Bugeyes"] = "bugmask"
|
||||
options["Double"] = "doublemask"
|
||||
options["Mark"] = "markmask"
|
||||
var/static/list/options = list("Blank" = "plainmask", "Neutral" = "neutralmask", "Eyes" = "eyemask",
|
||||
"Sleeping" ="sleepingmask", "Heart" = "heartmask", "Core" = "coremask",
|
||||
"Plus" = "plusmask", "Square" ="squaremask", "Bullseye" = "bullseyemask",
|
||||
"Vertical" = "verticalmask", "Horizontal" = "horizontalmask", "X" ="xmask",
|
||||
"Bugeyes" = "bugmask", "Double" = "doublemask", "Mark" = "markmask")
|
||||
|
||||
var/choice = input(user,"What symbol would you want on this mask?","Morph Mask") in options
|
||||
var/choice = show_radial_menu(user,src, papermask_designs, custom_check = FALSE, radius = 36, require_near = TRUE)
|
||||
|
||||
if(src && choice && !user.incapacitated() && in_range(user,src))
|
||||
icon_state = options[choice]
|
||||
|
||||
@@ -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)].")
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// 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_state = "plant"
|
||||
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
|
||||
. = ..()
|
||||
|
||||
@@ -1059,6 +1059,9 @@
|
||||
if(health_deficiency >= 40)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25)
|
||||
else
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
else
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -276,6 +276,19 @@
|
||||
R.hud_used.update_robot_modules_display()
|
||||
SSblackbox.record_feedback("tally", "cyborg_modules", 1, R.module)
|
||||
|
||||
/**
|
||||
* check_menu: Checks if we are allowed to interact with a radial menu
|
||||
*
|
||||
* Arguments:
|
||||
* * user The mob interacting with a menu
|
||||
*/
|
||||
/obj/item/robot_module/proc/check_menu(mob/user)
|
||||
if(!istype(user))
|
||||
return FALSE
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/robot_module/standard
|
||||
name = "Standard"
|
||||
basic_modules = list(
|
||||
@@ -337,13 +350,28 @@
|
||||
|
||||
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/medmodels = list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale")
|
||||
if(R.client && (R.client.ckey in list("nezuli")))
|
||||
medmodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medmodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/med_icons
|
||||
if(!med_icons)
|
||||
med_icons = list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "medical"),
|
||||
"Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "medical"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmed"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamed"),
|
||||
"Eyebot" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "eyebotmed"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymed")
|
||||
)
|
||||
var/list/L = list("Medihound" = "medihound", "Medihound Dark" = "medihounddark", "Vale" = "valemed")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
med_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-med")
|
||||
bad_snowflake.pixel_x = -16
|
||||
med_icons["Alina"] = bad_snowflake
|
||||
med_icons = sortList(med_icons)
|
||||
var/med_borg_icon = show_radial_menu(R, R , med_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(med_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "medical"
|
||||
if("Droid")
|
||||
@@ -391,6 +419,8 @@
|
||||
moduleselect_icon = "medihound"
|
||||
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/engineering
|
||||
@@ -434,13 +464,31 @@
|
||||
|
||||
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
|
||||
if(R.client && (R.client.ckey in list("nezuli")))
|
||||
engymodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/engi_icons
|
||||
if(!engi_icons)
|
||||
engi_icons = list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "engineer"),
|
||||
"Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "engi-tread"),
|
||||
"Loader" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "loaderborg"),
|
||||
"Handy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "handyeng"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekeng"),
|
||||
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "caneng"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinaeng"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidereng"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyeng")
|
||||
)
|
||||
var/list/L = list("Pup Dozer" = "pupdozer", "Vale" = "valeeng")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
engi_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-eng")
|
||||
bad_snowflake.pixel_x = -16
|
||||
engi_icons["Alina"] = bad_snowflake
|
||||
engi_icons = sortList(engi_icons)
|
||||
var/engi_borg_icon = show_radial_menu(R, R , engi_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(engi_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "engineer"
|
||||
if("Default - Treads")
|
||||
@@ -485,6 +533,8 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "alinasleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security
|
||||
@@ -512,13 +562,29 @@
|
||||
|
||||
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/secmodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider", "K9", "K9 Dark", "Vale")
|
||||
if(R.client && (R.client.ckey in list("nezuli")))
|
||||
secmodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in secmodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/sec_icons
|
||||
if(!sec_icons)
|
||||
sec_icons = list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "sec"),
|
||||
"Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sec-tread"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleeksec"),
|
||||
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "cansec"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinasec"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidersec"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavysec")
|
||||
)
|
||||
var/list/L = list("K9" = "k9", "Vale" = "valesec", "K9 Dark" = "k9dark")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
sec_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
|
||||
bad_snowflake.pixel_x = -16
|
||||
sec_icons["Alina"] = bad_snowflake
|
||||
sec_icons = sortList(sec_icons)
|
||||
var/sec_borg_icon = show_radial_menu(R, R , sec_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(sec_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "sec"
|
||||
if("Default - Treads")
|
||||
@@ -561,6 +627,8 @@
|
||||
sleeper_overlay = "valesecsleeper"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security/Initialize()
|
||||
@@ -599,10 +667,13 @@
|
||||
|
||||
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "Borgi")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/peace_icons = sortList(list(
|
||||
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "peace"),
|
||||
"Borgi" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "borgi"),
|
||||
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "whitespider")
|
||||
))
|
||||
var/peace_borg_icon = show_radial_menu(R, R , peace_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(peace_borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "peace"
|
||||
if("Spider")
|
||||
@@ -615,6 +686,8 @@
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
//Janitor module combined with Service module
|
||||
@@ -738,10 +811,35 @@
|
||||
|
||||
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("(Service) Waitress", "(Service) Heavy", "(Service) Sleek", "(Service) Butler", "(Service) Tophat", "(Service) Can", "(Service) Bro", "(Service) DarkK9", "(Service) Vale", "(Service) ValeDark", "(Janitor) Default", "(Janitor) Sleek", "(Janitor) Marina", "(Janitor) Can", "(Janitor) Heavy", "(Janitor) Scrubpuppy")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/service_icons
|
||||
if(!service_icons)
|
||||
service_icons = list(
|
||||
"(Service) Waitress" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_f"),
|
||||
"(Service) Butler" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_m"),
|
||||
"(Service) Bro" = image(icon = 'icons/mob/robots.dmi', icon_state = "brobot"),
|
||||
"(Service) Can" = image(icon = 'icons/mob/robots.dmi', icon_state = "kent"),
|
||||
"(Service) Tophat" = image(icon = 'icons/mob/robots.dmi', icon_state = "tophat"),
|
||||
"(Service) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekserv"),
|
||||
"(Service) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyserv"),
|
||||
"(Janitor) Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "janitor"),
|
||||
"(Janitor) Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinajan"),
|
||||
"(Janitor) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekjan"),
|
||||
"(Janitor) Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canjan"),
|
||||
"(Janitor) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyjan"),
|
||||
)
|
||||
var/list/L = list("(Service) DarkK9" = "k50", "(Service) Vale" = "valeserv", "(Service) ValeDark" = "valeservdark",
|
||||
"(Janitor) Scrubpuppy" = "scrubpup")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
service_icons[a] = wide
|
||||
if(R.client && R.client.ckey == "nezuli")
|
||||
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
|
||||
bad_snowflake.pixel_x = -16
|
||||
service_icons["Alina"] = bad_snowflake
|
||||
service_icons = sortList(service_icons)
|
||||
var/service_robot_icon = show_radial_menu(R, R , service_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(service_robot_icon)
|
||||
if("(Service) Waitress")
|
||||
cyborg_base_icon = "service_f"
|
||||
special_light_key = "service"
|
||||
@@ -799,6 +897,8 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "jsleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/miner
|
||||
@@ -833,10 +933,25 @@
|
||||
|
||||
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "Blade", "Vale")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
var/static/list/mining_icons
|
||||
if(!mining_icons)
|
||||
mining_icons = list(
|
||||
"Lavaland" = image(icon = 'icons/mob/robots.dmi', icon_state = "miner"),
|
||||
"Asteroid" = image(icon = 'icons/mob/robots.dmi', icon_state = "minerOLD"),
|
||||
"Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "miner"),
|
||||
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmin"),
|
||||
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamin"),
|
||||
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canmin"),
|
||||
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymin"),
|
||||
)
|
||||
var/list/L = list("Blade" = "blade", "Vale" = "valemine")
|
||||
for(var/a in L)
|
||||
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
|
||||
wide.pixel_x = -16
|
||||
mining_icons[a] = wide
|
||||
mining_icons = sortList(mining_icons)
|
||||
var/mining_borg_icon = show_radial_menu(R, R , mining_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
|
||||
switch(mining_borg_icon)
|
||||
if("Lavaland")
|
||||
cyborg_base_icon = "miner"
|
||||
if("Asteroid")
|
||||
@@ -871,6 +986,8 @@
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
sleeper_overlay = "valeminesleeper"
|
||||
dogborg = TRUE
|
||||
else
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/syndicate
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user