mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
Merge upstream
This commit is contained in:
@@ -83,7 +83,8 @@ var/global/BSACooldown = 0
|
||||
body += "<A href='?_src_=holder;traitor=\ref[M]'>Traitor panel</A> | "
|
||||
body += "<A href='?_src_=holder;narrateto=\ref[M]'>Narrate to</A> | "
|
||||
body += "<A href='?_src_=holder;subtlemessage=\ref[M]'>Subtle message</A> | "
|
||||
body += "<A href='?_src_=holder;individuallog=\ref[M]'>Individual Round Logs</A>"
|
||||
body += "<A href='?_src_=holder;individuallog=\ref[M]'>Individual Round Logs</A> | "
|
||||
body += "<A href='?_src_=holder;languagemenu=\ref[M]'>Language Menu</A>"
|
||||
|
||||
if (M.client)
|
||||
if(!isnewplayer(M))
|
||||
@@ -823,4 +824,4 @@ var/global/BSACooldown = 0
|
||||
string = pick(
|
||||
"Admin login: [key_name(src)]")
|
||||
if(string)
|
||||
message_admins("[string]")
|
||||
message_admins("[string]")
|
||||
|
||||
@@ -622,10 +622,7 @@ var/list/admin_verbs_hideable = list(
|
||||
var/message = input(usr, "What do you want the message to be?", "Make Sound") as text | null
|
||||
if(!message)
|
||||
return
|
||||
var/templanguages = O.languages_spoken
|
||||
O.languages_spoken |= ALL
|
||||
O.say(message)
|
||||
O.languages_spoken = templanguages
|
||||
log_admin("[key_name(usr)] made [O] at [O.x], [O.y], [O.z] say \"[message]\"")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z]. say \"[message]\"</span>")
|
||||
feedback_add_details("admin_verb","OS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -1814,6 +1814,16 @@
|
||||
return
|
||||
|
||||
show_individual_logging_panel(M, href_list["log_type"])
|
||||
else if(href_list["languagemenu"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/mob/living/L = locate(href_list["languagemenu"]) in mob_list
|
||||
if(!isliving(L))
|
||||
to_chat(usr, "This can only be used on instances of type /mob/living.")
|
||||
return
|
||||
|
||||
L.open_language_menu(usr)
|
||||
|
||||
else if(href_list["traitor"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
var/listening = 0
|
||||
var/recorded = "" //the activation message
|
||||
var/mode = 1
|
||||
var/global/list/modes = list("inclusive",
|
||||
var/static/list/modes = list("inclusive",
|
||||
"exclusive",
|
||||
"recognizer",
|
||||
"voice sensor")
|
||||
@@ -21,35 +21,33 @@
|
||||
..()
|
||||
to_chat(user, "<span class='notice'>Use a multitool to swap between \"inclusive\", \"exclusive\", \"recognizer\", and \"voice sensor\" mode.</span>")
|
||||
|
||||
/obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans)
|
||||
if(speaker == src)
|
||||
return
|
||||
|
||||
if(listening && !radio_freq)
|
||||
record_speech(speaker, raw_message)
|
||||
record_speech(speaker, raw_message, message_language)
|
||||
else
|
||||
if(check_activation(speaker, raw_message))
|
||||
spawn(10)
|
||||
pulse(0)
|
||||
addtimer(CALLBACK(src, .proc/pulse, 0), 10)
|
||||
|
||||
/obj/item/device/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message)
|
||||
/obj/item/device/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language)
|
||||
switch(mode)
|
||||
if(1)
|
||||
recorded = raw_message
|
||||
listening = 0
|
||||
say("Activation message is '[recorded]'.")
|
||||
say("Activation message is '[recorded]'.", message_language)
|
||||
if(2)
|
||||
recorded = raw_message
|
||||
listening = 0
|
||||
say("Activation message is '[recorded]'.")
|
||||
say("Activation message is '[recorded]'.", message_language)
|
||||
if(3)
|
||||
recorded = speaker.GetVoice()
|
||||
listening = 0
|
||||
say("Your voice pattern is saved.")
|
||||
say("Your voice pattern is saved.", message_language)
|
||||
if(4)
|
||||
if(length(raw_message))
|
||||
spawn(10)
|
||||
pulse(0)
|
||||
addtimer(CALLBACK(src, .proc/pulse, 0), 10)
|
||||
|
||||
/obj/item/device/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message)
|
||||
. = 0
|
||||
|
||||
@@ -35,7 +35,6 @@ var/list/gaslist_cache = init_gaslist_cache()
|
||||
var/datum/holder
|
||||
|
||||
/datum/gas_mixture/New(volume = CELL_VOLUME)
|
||||
..()
|
||||
gases = new
|
||||
temperature = 0
|
||||
temperature_archived = 0
|
||||
|
||||
@@ -115,9 +115,9 @@
|
||||
on = FALSE
|
||||
update_icon()
|
||||
playsound(T, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
|
||||
radio.talk_into(src, "Patient fully restored", radio_channel)
|
||||
radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language())
|
||||
if(autoeject) // Eject if configured.
|
||||
radio.talk_into(src, "Auto ejecting patient now", radio_channel)
|
||||
radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language())
|
||||
open_machine()
|
||||
return
|
||||
else if(occupant.stat == DEAD) // We don't bother with dead people.
|
||||
|
||||
@@ -209,6 +209,12 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
active = 1
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/carbon/C)
|
||||
for(var/obj/item/weapon/implant/exile/E in C.implants)//Checking that there is an exile implant
|
||||
to_chat(C, "\black The station gate has detected your exile implant and is blocking your entry.")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/gateway/centeraway/Bumped(atom/movable/AM)
|
||||
if(!detect())
|
||||
return
|
||||
@@ -217,10 +223,18 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
if(!stationgate || QDELETED(stationgate))
|
||||
return
|
||||
if(istype(AM, /mob/living/carbon))
|
||||
var/mob/living/carbon/C = AM
|
||||
for(var/obj/item/weapon/implant/exile/E in C.implants)//Checking that there is an exile implant
|
||||
to_chat(AM, "\black The station gate has detected your exile implant and is blocking your entry.")
|
||||
if(check_exile_implant(AM))
|
||||
return
|
||||
else
|
||||
for(var/mob/living/carbon/C in AM.contents)
|
||||
if(check_exile_implant(C))
|
||||
say("Rejecting [AM]: Exile implant detected in contained lifeform.")
|
||||
return
|
||||
if(AM.buckled_mobs.len)
|
||||
for(var/mob/living/carbon/C in AM.buckled_mobs)
|
||||
if(check_exile_implant(C))
|
||||
say("Rejecting [AM]: Exile implant detected in close proximity lifeform.")
|
||||
return
|
||||
AM.forceMove(get_step(stationgate.loc, SOUTH))
|
||||
AM.setDir(SOUTH)
|
||||
if (ismob(AM))
|
||||
|
||||
@@ -578,9 +578,12 @@
|
||||
spawn()
|
||||
A.open()
|
||||
wearer.visible_message("<span class='warning'>[wearer] rolls sideways and slips past [A]</span>")
|
||||
wearer.forceMove(get_turf(A))
|
||||
var/turf/target = get_turf(A)
|
||||
if(istype(A, /obj/machinery/door/window) && (get_turf(wearer) == get_turf(A)))
|
||||
target = get_step(A, A.dir)
|
||||
wearer.forceMove(target)
|
||||
if(dragging_through)
|
||||
dragging_through.forceMove(get_turf(A))
|
||||
dragging_through.forceMove(target)
|
||||
wearer.pulling = dragging_through
|
||||
return pass
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
weight = 20
|
||||
max_occurrences = 5
|
||||
|
||||
/datum/round_event_control/canSpawnEvent(players_amt, gamemode)
|
||||
/datum/round_event_control/falsealarm/canSpawnEvent(players_amt, gamemode)
|
||||
return ..() && length(gather_false_events())
|
||||
|
||||
/datum/round_event/falsealarm
|
||||
@@ -26,6 +26,8 @@
|
||||
/proc/gather_false_events(players_amt, gamemode)
|
||||
. = list()
|
||||
for(var/datum/round_event_control/E in SSevents.control)
|
||||
if(istype(E,/datum/round_event_control/falsealarm))
|
||||
continue
|
||||
if(!E.canSpawnEvent(players_amt, gamemode))
|
||||
continue
|
||||
|
||||
|
||||
@@ -49,8 +49,10 @@
|
||||
spawned_animals++
|
||||
|
||||
SA.key = SG.key
|
||||
SA.languages_spoken |= HUMAN
|
||||
SA.languages_understood |= HUMAN
|
||||
|
||||
SA.grant_language(/datum/language/common)
|
||||
SET_SECONDARY_FLAG(SA, OMNITONGUE)
|
||||
|
||||
SA.sentience_act()
|
||||
|
||||
SA.maxHealth = max(SA.maxHealth, 200)
|
||||
|
||||
@@ -707,6 +707,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/ballistic, /obj/item
|
||||
|
||||
var/list/mob/living/carbon/people = list()
|
||||
var/list/mob/living/carbon/person = null
|
||||
var/datum/language/understood_language = target.get_random_understood_language()
|
||||
for(var/mob/living/carbon/H in view(target))
|
||||
if(H == target)
|
||||
continue
|
||||
@@ -718,7 +719,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/ballistic, /obj/item
|
||||
people += H
|
||||
if(person) //Basic talk
|
||||
var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER)
|
||||
to_chat(target, target.compose_message(person,person.languages_understood,pick(speak_messages),null,person.get_spans()))
|
||||
to_chat(target, target.compose_message(person,understood_language,pick(speak_messages),null,person.get_spans()))
|
||||
if(target.client)
|
||||
target.client.images |= speech_overlay
|
||||
sleep(30)
|
||||
@@ -728,7 +729,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/ballistic, /obj/item
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
humans += H
|
||||
person = pick(humans)
|
||||
to_chat(target, target.compose_message(person,person.languages_understood,pick(radio_messages),"1459",person.get_spans()))
|
||||
to_chat(target, target.compose_message(person,understood_language,pick(radio_messages),"1459",person.get_spans()))
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/hallucination/message
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// 'basic' language; spoken by default.
|
||||
/datum/language/common
|
||||
name = "Galactic Common"
|
||||
desc = "The common galactic tongue."
|
||||
speech_verb = "says"
|
||||
whisper_verb = "whispers"
|
||||
key = "0"
|
||||
flags = TONGUELESS_SPEECH
|
||||
default_priority = 100
|
||||
|
||||
//Syllable Lists
|
||||
/*
|
||||
This list really long, mainly because I can't make up my mind about which mandarin syllables should be removed,
|
||||
and the english syllables had to be duplicated so that there is roughly a 50-50 weighting.
|
||||
|
||||
Sources:
|
||||
http://www.sttmedia.com/syllablefrequency-english
|
||||
http://www.chinahighlights.com/travelguide/learning-chinese/pinyin-syllables.htm
|
||||
*/
|
||||
/datum/language/common/syllables = list(
|
||||
"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao",
|
||||
"bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "cei", "cen", "ceng", "cha", "chai",
|
||||
"chan", "chang", "chao", "che", "chen", "cheng", "chi", "chong", "chou", "chu", "chua", "chuai", "chuan", "chuang", "chui", "chun",
|
||||
"chuo", "ci", "cong", "cou", "cu", "cuan", "cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "dei",
|
||||
"den", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du", "duan", "dui", "dun", "duo", "e",
|
||||
"ei", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang",
|
||||
"gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha",
|
||||
"hai", "han", "hang", "hao", "he", "hei", "hen", "heng", "hm", "hng", "hong", "hou", "hu", "hua", "huai", "huan",
|
||||
"huang", "hui", "hun", "huo", "ji", "jia", "jian", "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan",
|
||||
"jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "kei", "ken", "keng", "kong", "kou", "ku", "kua", "kuai",
|
||||
"kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng", "li", "lia", "lian",
|
||||
"liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "luan", "lun", "luo", "ma", "mai", "man", "mang",
|
||||
"mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na",
|
||||
"nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ng", "ni", "nian", "niang", "niao", "nie", "nin", "ning",
|
||||
"niu", "nong", "nou", "nu", "nuan", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng",
|
||||
"pi", "pian", "piao", "pie", "pin", "ping", "po", "pou", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin",
|
||||
"qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou",
|
||||
"ru", "rua", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sei", "sen", "seng", "sha",
|
||||
"shai", "shan", "shang", "shao", "she", "shei", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui",
|
||||
"shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te",
|
||||
"teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan",
|
||||
"wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu",
|
||||
"xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yong", "you", "yu", "yuan",
|
||||
"yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", "zhan", "zhang", "zhao",
|
||||
"zhe", "zhei", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", "zhun", "zhuo", "zi",
|
||||
"zong", "zou", "zuan", "zui", "zun", "zuo", "zu",
|
||||
"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it",
|
||||
"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to",
|
||||
"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin",
|
||||
"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi",
|
||||
"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it",
|
||||
"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to",
|
||||
"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin",
|
||||
"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi",
|
||||
"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it",
|
||||
"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to",
|
||||
"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin",
|
||||
"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi",
|
||||
"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it",
|
||||
"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to",
|
||||
"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin",
|
||||
"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi",
|
||||
"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it",
|
||||
"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to",
|
||||
"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin",
|
||||
"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi",
|
||||
"al", "an", "ar", "as", "at", "ea", "ed", "en", "er", "es", "ha", "he", "hi", "in", "is", "it",
|
||||
"le", "me", "nd", "ne", "ng", "nt", "on", "or", "ou", "re", "se", "st", "te", "th", "ti", "to",
|
||||
"ve", "wa", "all", "and", "are", "but", "ent", "era", "ere", "eve", "for", "had", "hat", "hen", "her", "hin",
|
||||
"his", "ing", "ion", "ith", "not", "ome", "oul", "our", "sho", "ted", "ter", "tha", "the", "thi")
|
||||
@@ -0,0 +1,14 @@
|
||||
/datum/language/drone
|
||||
name = "Drone"
|
||||
desc = "A heavily encoded damage control coordination stream, with special flags for hats."
|
||||
speech_verb = "chitters"
|
||||
ask_verb = "chitters inquisitively"
|
||||
exclaim_verb = "chitters loudly"
|
||||
spans = list(SPAN_ROBOT)
|
||||
key = "d"
|
||||
flags = NO_STUTTER
|
||||
syllables = list(".", "|")
|
||||
// ...|..||.||||.|.||.|.|.|||.|||
|
||||
space_chance = 0
|
||||
sentence_chance = 0
|
||||
default_priority = 20
|
||||
@@ -0,0 +1,95 @@
|
||||
#define SCRAMBLE_CACHE_LEN 20
|
||||
|
||||
/*
|
||||
Datum based languages. Easily editable and modular.
|
||||
*/
|
||||
|
||||
/datum/language
|
||||
var/name = "an unknown language" // Fluff name of language if any.
|
||||
var/desc = "A language." // Short description for 'Check Languages'.
|
||||
var/speech_verb = "says" // 'says', 'hisses', 'farts'.
|
||||
var/ask_verb = "asks" // Used when sentence ends in a ?
|
||||
var/exclaim_verb = "exclaims" // Used when sentence ends in a !
|
||||
var/whisper_verb = "whispers" // Optional. When not specified speech_verb + quietly/softly is used instead.
|
||||
var/list/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
|
||||
var/key = "x" // Character used to speak in language
|
||||
var/flags // Various language flags.
|
||||
var/list/syllables // Used when scrambling text for a non-speaker.
|
||||
var/list/sentence_chance = 5 // Likelihood of making a new sentence after each syllable.
|
||||
var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string
|
||||
var/list/spans = list()
|
||||
var/static/list/scramble_cache = list()
|
||||
var/default_priority = 0 // the language that an atom knows with the highest "default_priority" is selected by default.
|
||||
|
||||
/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4, syllable_divisor=2)
|
||||
if(!syllables || !syllables.len)
|
||||
if(gender==FEMALE)
|
||||
return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
|
||||
else
|
||||
return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
|
||||
|
||||
var/full_name = ""
|
||||
var/new_name = ""
|
||||
|
||||
for(var/i in 0 to name_count)
|
||||
new_name = ""
|
||||
var/Y = rand(Floor(syllable_count/syllable_divisor), syllable_count)
|
||||
for(var/x in Y to 0)
|
||||
new_name += pick(syllables)
|
||||
full_name += " [capitalize(lowertext(new_name))]"
|
||||
|
||||
return "[trim(full_name)]"
|
||||
|
||||
/datum/language/proc/scramble(input)
|
||||
|
||||
if(!syllables || !syllables.len)
|
||||
return stars(input)
|
||||
|
||||
// If the input is cached already, move it to the end of the cache and return it
|
||||
var/lookup = scramble_cache[input]
|
||||
if(lookup)
|
||||
scramble_cache -= input
|
||||
scramble_cache[input] = lookup
|
||||
return lookup
|
||||
|
||||
var/input_size = length(input)
|
||||
var/scrambled_text = ""
|
||||
var/capitalize = TRUE
|
||||
|
||||
while(length(scrambled_text) < input_size)
|
||||
var/next = pick(syllables)
|
||||
if(capitalize)
|
||||
next = capitalize(next)
|
||||
capitalize = FALSE
|
||||
scrambled_text += next
|
||||
var/chance = rand(100)
|
||||
if(chance <= sentence_chance)
|
||||
scrambled_text += ". "
|
||||
capitalize = TRUE
|
||||
else if(chance > sentence_chance && chance <= space_chance)
|
||||
scrambled_text += " "
|
||||
|
||||
scrambled_text = trim(scrambled_text)
|
||||
var/ending = copytext(scrambled_text, length(scrambled_text))
|
||||
if(ending == ".")
|
||||
scrambled_text = copytext(scrambled_text,1,length(scrambled_text)-1)
|
||||
var/input_ending = copytext(input, input_size)
|
||||
if(input_ending in list("!","?","."))
|
||||
scrambled_text += input_ending
|
||||
|
||||
// Add it to cache, cutting old entries if the list is too long
|
||||
scramble_cache[input] = scrambled_text
|
||||
if(scramble_cache.len > SCRAMBLE_CACHE_LEN)
|
||||
scramble_cache.Cut(1, scramble_cache.len-SCRAMBLE_CACHE_LEN-1)
|
||||
|
||||
return scrambled_text
|
||||
|
||||
/datum/language/proc/get_spoken_verb(msg_end)
|
||||
switch(msg_end)
|
||||
if("!")
|
||||
return exclaim_verb
|
||||
if("?")
|
||||
return ask_verb
|
||||
return speech_verb
|
||||
|
||||
#undef SCRAMBLE_CACHE_LEN
|
||||
@@ -0,0 +1,88 @@
|
||||
/datum/language_menu
|
||||
var/mob/living/owner
|
||||
|
||||
/datum/language_menu/New(new_owner)
|
||||
owner = new_owner
|
||||
|
||||
/datum/language_menu/Destroy()
|
||||
owner = null
|
||||
. = ..()
|
||||
|
||||
/datum/language_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = language_menu_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "language_menu", "Language Menu", 700, 800, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/datum/language_menu/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/datum/language/mob_default_language = owner.get_default_language()
|
||||
|
||||
data["languages"] = list()
|
||||
for(var/ld in owner.languages)
|
||||
var/datum/language/LD = ld
|
||||
var/list/L = list()
|
||||
|
||||
L["name"] = initial(LD.name)
|
||||
L["desc"] = initial(LD.desc)
|
||||
L["key"] = initial(LD.key)
|
||||
L["is_default"] = (LD == mob_default_language)
|
||||
L["can_speak"] = owner.can_speak_in_language(LD)
|
||||
|
||||
data["languages"] += list(L)
|
||||
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
data["admin_mode"] = TRUE
|
||||
data["omnitongue"] = HAS_SECONDARY_FLAG(owner, OMNITONGUE)
|
||||
|
||||
data["unknown_languages"] = list()
|
||||
for(var/ld in subtypesof(/datum/language))
|
||||
if(owner.has_language(ld))
|
||||
continue
|
||||
var/datum/language/LD = ld
|
||||
var/list/L = list()
|
||||
|
||||
L["name"] = initial(LD.name)
|
||||
L["desc"] = initial(LD.desc)
|
||||
L["key"] = initial(LD.key)
|
||||
|
||||
data["unknown_languages"] += list(L)
|
||||
return data
|
||||
|
||||
/datum/language_menu/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
var/mob/user = usr
|
||||
|
||||
var/language_name = params["language_name"]
|
||||
var/datum/language/language_datum
|
||||
for(var/ld in subtypesof(/datum/language))
|
||||
var/datum/language/LD = ld
|
||||
if(language_name == initial(LD.name))
|
||||
language_datum = LD
|
||||
var/is_admin = check_rights_for(user.client, R_ADMIN)
|
||||
|
||||
switch(action)
|
||||
if("select_default")
|
||||
if(language_datum)
|
||||
owner.selected_default_language = language_datum
|
||||
. = TRUE
|
||||
if("grant_language")
|
||||
if(is_admin && language_datum)
|
||||
owner.grant_language(language_datum)
|
||||
message_admins("[key_name_admin(user)] granted the [language_name] language to [key_name_admin(owner)].")
|
||||
log_admin("[key_name(user)] granted the language [language_name] to [key_name(owner)].")
|
||||
. = TRUE
|
||||
if("remove_language")
|
||||
if(is_admin && language_datum)
|
||||
owner.remove_language(language_datum)
|
||||
message_admins("[key_name_admin(user)] removed the [language_name] language to [key_name_admin(owner)].")
|
||||
log_admin("[key_name(user)] removed the language [language_name] to [key_name(owner)].")
|
||||
. = TRUE
|
||||
if("toggle_omnitongue")
|
||||
if(is_admin)
|
||||
TOGGLE_SECONDARY_FLAG(owner, OMNITONGUE)
|
||||
message_admins("[key_name_admin(user)] [HAS_SECONDARY_FLAG(owner, OMNITONGUE) ? "enabled" : "disabled"] the ability to speak all languages (that they know) of [key_name_admin(owner)].")
|
||||
log_admin("[key_name(user)] [HAS_SECONDARY_FLAG(owner, OMNITONGUE) ? "enabled" : "disabled"] the ability to speak all languages (that_they know) of [key_name(owner)].")
|
||||
. = TRUE
|
||||
@@ -0,0 +1,17 @@
|
||||
/datum/language/machine
|
||||
name = "Encoded Audio Language"
|
||||
desc = "An efficient language of encoded tones developed by synthetics and cyborgs."
|
||||
speech_verb = "whistles"
|
||||
ask_verb = "chirps"
|
||||
exclaim_verb = "whistles loudly"
|
||||
spans = list(SPAN_ROBOT, "changeling")
|
||||
key = "6"
|
||||
flags = NO_STUTTER
|
||||
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz")
|
||||
space_chance = 10
|
||||
default_priority = 90
|
||||
|
||||
/datum/language/machine/get_random_name()
|
||||
if(prob(70))
|
||||
return "[pick(posibrain_names)]-[rand(100, 999)]"
|
||||
return pick(ai_names)
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/language/monkey
|
||||
name = "Chimpanzee"
|
||||
desc = "Ook ook ook."
|
||||
speech_verb = "chimpers"
|
||||
ask_verb = "chimpers"
|
||||
exclaim_verb = "screeches"
|
||||
key = "1"
|
||||
space_chance = 100
|
||||
syllables = list("oop", "aak", "chee", "eek")
|
||||
default_priority = 80
|
||||
@@ -0,0 +1,12 @@
|
||||
/datum/language/ratvar
|
||||
name = "Ratvarian"
|
||||
desc = "A timeless language full of power and incomprehensible to the unenlightened."
|
||||
speech_verb = "clinks"
|
||||
ask_verb = "clunks"
|
||||
exclaim_verb = "clanks"
|
||||
key = "r"
|
||||
default_priority = 10
|
||||
spans = list(SPAN_ROBOT, "brass")
|
||||
|
||||
/datum/language/ratvar/scramble(var/input)
|
||||
. = text2ratvar(input)
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/language/slime
|
||||
name = "Slime"
|
||||
desc = "A melodic and complex language spoken by slimes. Some of the notes are inaudible to humans."
|
||||
speech_verb = "warbles"
|
||||
ask_verb = "warbles"
|
||||
exclaim_verb = "warbles"
|
||||
spans = list("slime")
|
||||
key = "k"
|
||||
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!")
|
||||
default_priority = 70
|
||||
@@ -0,0 +1,42 @@
|
||||
/datum/language/swarmer
|
||||
name = "Swarmer"
|
||||
desc = "A language only consisting of musical notes."
|
||||
speech_verb = "tones"
|
||||
ask_verb = "tones inquisitively"
|
||||
exclaim_verb = "tones loudly"
|
||||
spans = list(SPAN_ROBOT)
|
||||
key = "s"
|
||||
flags = NO_STUTTER
|
||||
space_chance = 100
|
||||
sentence_chance = 0
|
||||
default_priority = 60
|
||||
// since various flats and sharps are the same,
|
||||
// all non-accidental notes are doubled in the list
|
||||
/* The list with unicode symbols for the accents.
|
||||
syllables = list(
|
||||
"C", "C",
|
||||
"C♯", "D♭",
|
||||
"D", "D",
|
||||
"D♯", "E♭",
|
||||
"E", "E",
|
||||
"F", "F",
|
||||
"F♯", "G♭",
|
||||
"G", "G",
|
||||
"G♯", "A♭",
|
||||
"A", "A",
|
||||
"A♯", "B♭",
|
||||
"B", "B")
|
||||
*/
|
||||
syllables = list(
|
||||
"C", "C",
|
||||
"C#", "Db",
|
||||
"D", "D",
|
||||
"D#", "Eb",
|
||||
"E", "E",
|
||||
"F", "F",
|
||||
"F#", "Gb",
|
||||
"G", "G",
|
||||
"G#", "Ab",
|
||||
"A", "A",
|
||||
"A#", "Bb",
|
||||
"B", "B")
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/language/xenocommon
|
||||
name = "Xenomorph"
|
||||
desc = "The common tongue of the xenomorphs."
|
||||
speech_verb = "hisses"
|
||||
ask_verb = "hisses"
|
||||
exclaim_verb = "hisses"
|
||||
spans = list("alien")
|
||||
key = "4"
|
||||
syllables = list("sss","sSs","SSS")
|
||||
default_priority = 50
|
||||
@@ -21,3 +21,10 @@
|
||||
T.lighting_clear_overlay()
|
||||
|
||||
return TRUE
|
||||
|
||||
/area/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("dynamic_lighting")
|
||||
set_dynamic_lighting(var_value)
|
||||
return TRUE
|
||||
return ..()
|
||||
@@ -102,6 +102,9 @@
|
||||
|
||||
/datum/lighting_corner/proc/update_objects()
|
||||
// Cache these values a head of time so 4 individual lighting objects don't all calculate them individually.
|
||||
var/lum_r = src.lum_r
|
||||
var/lum_g = src.lum_g
|
||||
var/lum_b = src.lum_b
|
||||
var/mx = max(lum_r, lum_g, lum_b) // Scale it so one of them is the strongest lum, if it is above 1.
|
||||
. = 1 // factor
|
||||
if (mx > 1)
|
||||
@@ -139,4 +142,4 @@
|
||||
|
||||
stack_trace("Ok, Look, TG, I need you to find whatever fucker decided to call qdel on a fucking lighting corner, then tell him very nicely and politely that he is 100% retarded and needs his head checked. Thanks. Send them my regards by the way.")
|
||||
// Yeah fuck you anyways.
|
||||
return QDEL_HINT_LETMELIVE
|
||||
return QDEL_HINT_LETMELIVE
|
||||
@@ -75,21 +75,49 @@
|
||||
|
||||
var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx)
|
||||
|
||||
color = list(
|
||||
cr.cache_r, cr.cache_g, cr.cache_b, 0,
|
||||
cg.cache_r, cg.cache_g, cg.cache_b, 0,
|
||||
cb.cache_r, cb.cache_g, cb.cache_b, 0,
|
||||
ca.cache_r, ca.cache_g, ca.cache_b, 0,
|
||||
0, 0, 0, 1
|
||||
)
|
||||
var/rr = cr.cache_r
|
||||
var/rg = cr.cache_g
|
||||
var/rb = cr.cache_b
|
||||
|
||||
var/gr = cg.cache_r
|
||||
var/gg = cg.cache_g
|
||||
var/gb = cg.cache_b
|
||||
|
||||
var/br = cb.cache_r
|
||||
var/bg = cb.cache_g
|
||||
var/bb = cb.cache_b
|
||||
|
||||
var/ar = ca.cache_r
|
||||
var/ag = ca.cache_g
|
||||
var/ab = ca.cache_b
|
||||
|
||||
#if LIGHTING_SOFT_THRESHOLD != 0
|
||||
luminosity = max > LIGHTING_SOFT_THRESHOLD
|
||||
var/set_luminosity = max > LIGHTING_SOFT_THRESHOLD
|
||||
#else
|
||||
// Because of floating points™️, it won't even be a flat 0.
|
||||
// Because of floating points™?, it won't even be a flat 0.
|
||||
// This number is mostly arbitrary.
|
||||
luminosity = max > 1e-6
|
||||
var/set_luminosity = max > 1e-6
|
||||
#endif
|
||||
|
||||
if((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8))
|
||||
//anything that passes the first case is very likely to pass the second, and addition is a little faster in this case
|
||||
icon_state = "transparent"
|
||||
color = null
|
||||
else if(!set_luminosity)
|
||||
icon_state = "dark"
|
||||
color = null
|
||||
else
|
||||
icon_state = null
|
||||
color = list(
|
||||
rr, rg, rb, 00,
|
||||
gr, gg, gb, 00,
|
||||
br, bg, bb, 00,
|
||||
ar, ag, ab, 00,
|
||||
00, 00, 00, 01
|
||||
)
|
||||
|
||||
luminosity = set_luminosity
|
||||
|
||||
// Variety of overrides so the overlays don't get affected by weird things.
|
||||
|
||||
/atom/movable/lighting_object/ex_act(severity)
|
||||
@@ -111,4 +139,4 @@
|
||||
// Override here to prevent things accidentally moving around overlays.
|
||||
/atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE)
|
||||
if(harderforce)
|
||||
. = ..()
|
||||
. = ..()
|
||||
@@ -32,8 +32,8 @@
|
||||
|
||||
while(sanity > 0)
|
||||
sanity--
|
||||
var/width_border = TRANSITIONEDGE + round(ruin.width / 2)
|
||||
var/height_border = TRANSITIONEDGE + round(ruin.height / 2)
|
||||
var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(ruin.width / 2)
|
||||
var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(ruin.height / 2)
|
||||
var/z_level = pick(z_levels)
|
||||
var/turf/T = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z_level)
|
||||
var/valid = TRUE
|
||||
|
||||
@@ -573,9 +573,9 @@
|
||||
L.underlays -= marked_image
|
||||
qdel(marked_image)
|
||||
marked_image = null
|
||||
var/backstab = check_target_facings(user, L)
|
||||
var/backstab_dir = get_dir(user, L)
|
||||
var/def_check = L.getarmor(type = "bomb")
|
||||
if(backstab == FACING_INIT_FACING_TARGET_TARGET_FACING_PERPENDICULAR || backstab == FACING_SAME_DIR)
|
||||
if((user.dir & backstab_dir) && (L.dir & backstab_dir))
|
||||
L.apply_damage(80, BRUTE, blocked = def_check)
|
||||
playsound(user, 'sound/weapons/Kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong
|
||||
else
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
else
|
||||
if(!emagged)
|
||||
Radio.set_frequency(SEC_FREQ)
|
||||
Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", SEC_FREQ)
|
||||
Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", SEC_FREQ, get_spans(), get_default_language())
|
||||
to_chat(usr, "<span class='notice'>Shuttle received message and will be sent shortly.</span>")
|
||||
|
||||
/obj/machinery/mineral/labor_claim_console/proc/check_auth()
|
||||
|
||||
@@ -359,7 +359,7 @@
|
||||
name = "oar"
|
||||
icon = 'icons/obj/vehicles.dmi'
|
||||
icon_state = "oar"
|
||||
item_state = "rods"
|
||||
item_state = "oar"
|
||||
desc = "Not to be confused with the kind Research hassles you for."
|
||||
force = 12
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
|
||||
@@ -19,8 +19,6 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
see_in_dark = 100
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
languages_spoken = ALL
|
||||
languages_understood = ALL
|
||||
var/can_reenter_corpse
|
||||
var/datum/hud/living/carbon/hud = null // hud
|
||||
var/bootime = 0
|
||||
@@ -123,6 +121,8 @@ var/global/static/observer_default_invisibility = INVISIBILITY_OBSERVER
|
||||
verbs -= /mob/dead/observer/verb/possess
|
||||
|
||||
animate(src, pixel_y = 2, time = 10, loop = -1)
|
||||
|
||||
grant_all_languages()
|
||||
..()
|
||||
|
||||
/mob/dead/observer/narsie_act()
|
||||
|
||||
@@ -8,15 +8,18 @@
|
||||
|
||||
. = src.say_dead(message)
|
||||
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans)
|
||||
var/atom/movable/to_follow = speaker
|
||||
if(radio_freq)
|
||||
var/atom/movable/virtualspeaker/V = speaker
|
||||
|
||||
if(isAI(V.source))
|
||||
var/mob/living/silicon/ai/S = V.source
|
||||
speaker = S.eyeobj
|
||||
to_follow = S.eyeobj
|
||||
else
|
||||
speaker = V.source
|
||||
var/link = FOLLOW_LINK(src, speaker)
|
||||
to_follow = V.source
|
||||
var/link = FOLLOW_LINK(src, to_follow)
|
||||
// Recompose the message, because it's scrambled by default
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans)
|
||||
to_chat(src, "[link] [message]")
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/obj/item/device/mmi
|
||||
name = "Man-Machine Interface"
|
||||
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations."
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
|
||||
|
||||
/mob/living/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
@@ -64,4 +62,4 @@
|
||||
/mob/living/brain/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(stored_dna)
|
||||
stored_dna.real_name = real_name
|
||||
stored_dna.real_name = real_name
|
||||
|
||||
@@ -25,7 +25,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>"
|
||||
var/new_mob_message = "<span class='notice'>The positronic brain chimes quietly.</span>"
|
||||
var/dead_message = "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>"
|
||||
var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
|
||||
var/list/fluff_names
|
||||
var/picked_fluff_name //which fluff name we picked
|
||||
|
||||
|
||||
@@ -135,7 +135,10 @@ var/global/posibrain_notif_cooldown = 0
|
||||
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
brainmob = new(src)
|
||||
picked_fluff_name = pick(fluff_names)
|
||||
if(!fluff_names || !fluff_names.len)
|
||||
picked_fluff_name = pick(posibrain_names)
|
||||
else
|
||||
picked_fluff_name = pick(fluff_names)
|
||||
brainmob.name = "[picked_fluff_name]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.loc = src
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/brain/say(message)
|
||||
/mob/living/brain/say(message, language)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
@@ -7,16 +7,17 @@
|
||||
return
|
||||
else
|
||||
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/brain/get_spans()
|
||||
return ..() | SPAN_ROBOT
|
||||
|
||||
/mob/living/brain/radio(message, message_mode, list/spans)
|
||||
/mob/living/brain/radio(message, message_mode, list/spans, language)
|
||||
if(message_mode && istype(container, /obj/item/device/mmi))
|
||||
var/obj/item/device/mmi/R = container
|
||||
if(R.radio)
|
||||
R.radio.talk_into(src, message, , spans)
|
||||
R.radio.talk_into(src, message, , get_spans(), language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/mob/living/brain/lingcheck()
|
||||
@@ -24,4 +25,12 @@
|
||||
|
||||
/mob/living/brain/treat_message(message)
|
||||
message = capitalize(message)
|
||||
return message
|
||||
return message
|
||||
|
||||
/mob/living/brain/can_speak_in_language(datum/language/dt)
|
||||
if(HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
. = has_language(dt)
|
||||
else if(istype(container, /obj/item/device/mmi/posibrain/soul_vessel))
|
||||
. = has_language(dt) && ispath(dt, /datum/language/ratvar)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -11,11 +11,10 @@
|
||||
dna = null
|
||||
faction = list("alien")
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
languages_spoken = ALIEN
|
||||
languages_understood = ALIEN
|
||||
sight = SEE_MOBS
|
||||
see_in_dark = 4
|
||||
verb_say = "hisses"
|
||||
initial_languages = list(/datum/language/xenocommon)
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
|
||||
handcrafting = new()
|
||||
|
||||
grant_language(/datum/language/common) // ME TARZAN, YOU JANEBOT
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/create_internal_organs()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
var/global/default_martial_art = new/datum/martial_art
|
||||
/mob/living/carbon/human
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
initial_languages = list(/datum/language/common)
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
pressure_resistance = 25
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
if(!istype(dongle)) return 0
|
||||
if(dongle.translate_binary) return 1
|
||||
|
||||
/mob/living/carbon/human/radio(message, message_mode, list/spans)
|
||||
/mob/living/carbon/human/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
@@ -83,17 +83,17 @@
|
||||
switch(message_mode)
|
||||
if(MODE_HEADSET)
|
||||
if (ears)
|
||||
ears.talk_into(src, message, , spans)
|
||||
ears.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_DEPARTMENT)
|
||||
if (ears)
|
||||
ears.talk_into(src, message, message_mode, spans)
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(message_mode in radiochannels)
|
||||
if(ears)
|
||||
ears.talk_into(src, message, message_mode, spans)
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
/mob/living/carbon/human/whisper(message as text)
|
||||
/mob/living/carbon/human/whisper_verb(message as text)
|
||||
whisper(message)
|
||||
|
||||
/mob/living/carbon/human/whisper(message, datum/language/language=null)
|
||||
if(!IsVocal())
|
||||
return
|
||||
if(!message)
|
||||
return
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
@@ -73,14 +78,14 @@
|
||||
for(var/atom/movable/AM in listening)
|
||||
if(istype(AM,/obj/item/device/radio))
|
||||
continue
|
||||
AM.Hear(rendered, src, languages_spoken, message, , spans)
|
||||
AM.Hear(rendered, src, language, message, , spans)
|
||||
|
||||
message = stars(message)
|
||||
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] [whispers], <span class='message'>\"[attach_spans(message, spans)]\"</span></span>"
|
||||
for(var/atom/movable/AM in eavesdropping)
|
||||
if(istype(AM,/obj/item/device/radio))
|
||||
continue
|
||||
AM.Hear(rendered, src, languages_spoken, message, , spans)
|
||||
AM.Hear(rendered, src, language, message, , spans)
|
||||
|
||||
if(critical) //Dying words.
|
||||
succumb(1)
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
if(prob(20))
|
||||
emote("gasp")
|
||||
if(O2_partialpressure > 0)
|
||||
var/ratio = safe_oxy_min/O2_partialpressure
|
||||
var/ratio = 1 - O2_partialpressure/safe_oxy_min
|
||||
adjustOxyLoss(min(5*ratio, 3))
|
||||
failed_last_breath = 1
|
||||
oxygen_used = breath_gases["o2"][MOLES]*ratio
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
name = "monkey"
|
||||
voice_name = "monkey"
|
||||
verb_say = "chimpers"
|
||||
initial_languages = list(/datum/language/monkey)
|
||||
icon = 'icons/mob/monkey.dmi'
|
||||
icon_state = ""
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
languages_spoken = MONKEY
|
||||
languages_understood = MONKEY
|
||||
ventcrawler = VENTCRAWLER_NUDE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey
|
||||
@@ -159,4 +158,4 @@
|
||||
if(prob(10))
|
||||
var/obj/item/clothing/head/helmet/justice/escape/helmet = new(src)
|
||||
equip_to_slot_or_del(helmet,slot_head)
|
||||
helmet.attack_self(src) // todo encapsulate toggle
|
||||
helmet.attack_self(src) // todo encapsulate toggle
|
||||
|
||||
@@ -28,3 +28,15 @@
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(I)
|
||||
. |= I.get_held_item_speechspans(src)
|
||||
|
||||
/mob/living/carbon/can_speak_in_language(datum/language/dt)
|
||||
if(HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
. = has_language(dt)
|
||||
else if(has_language(dt))
|
||||
var/obj/item/organ/tongue/T = getorganslot("tongue")
|
||||
if(T)
|
||||
. = T.can_speak_in_language(dt)
|
||||
else
|
||||
. = initial(dt.flags) & TONGUELESS_SPEECH
|
||||
else
|
||||
. = FALSE
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
medhud.add_to_hud(src)
|
||||
faction += "\ref[src]"
|
||||
|
||||
language_menu = new(src)
|
||||
|
||||
|
||||
/mob/living/prepare_huds()
|
||||
..()
|
||||
@@ -41,6 +43,8 @@
|
||||
staticOverlays.len = 0
|
||||
remove_from_all_data_huds()
|
||||
|
||||
QDEL_NULL(language_menu)
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/ghostize(can_reenter_corpse = 1)
|
||||
@@ -665,7 +669,8 @@
|
||||
if(what && Adjacent(who) && what.mob_can_equip(who, src, final_where, TRUE))
|
||||
if(temporarilyRemoveItemFromInventory(what))
|
||||
if(where_list)
|
||||
who.put_in_hand(what, where_list[2])
|
||||
if(!who.put_in_hand(what, where_list[2]))
|
||||
what.forceMove(get_turf(who))
|
||||
else
|
||||
who.equip_to_slot(what, where, TRUE)
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/mob/living
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
sight = 0
|
||||
see_in_dark = 2
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD)
|
||||
@@ -74,4 +72,7 @@
|
||||
var/list/implants = null
|
||||
var/tesla_ignore = FALSE
|
||||
|
||||
var/datum/riding/riding_datum
|
||||
var/datum/riding/riding_datum
|
||||
|
||||
var/datum/language/selected_default_language
|
||||
var/datum/language_menu/language_menu
|
||||
|
||||
@@ -64,7 +64,7 @@ var/list/department_radio_keys = list(
|
||||
|
||||
var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
/mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE)
|
||||
/mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null)
|
||||
if(sanitize)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
if(!message || message == "")
|
||||
@@ -103,7 +103,26 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if(stat && !(message_mode in crit_allowed_modes))
|
||||
return
|
||||
|
||||
if(handle_inherent_channels(message, message_mode)) //Hiveminds, binary chat & holopad.
|
||||
// language comma detection.
|
||||
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))
|
||||
language = message_language
|
||||
message = copytext(message, 3)
|
||||
|
||||
// Trim the space if they said ",0 I LOVE LANGUAGES"
|
||||
if(findtext(message, " ", 1, 2))
|
||||
message = copytext(message, 2)
|
||||
|
||||
if(!language)
|
||||
language = get_default_language()
|
||||
|
||||
// Detection of language needs to be before inherent channels, because
|
||||
// AIs use inherent channels for the holopad. Most inherent channels
|
||||
// ignore the language argument however.
|
||||
|
||||
if(handle_inherent_channels(message, message_mode, language)) //Hiveminds, binary chat & holopad.
|
||||
return
|
||||
|
||||
if(!can_speak_vocal(message))
|
||||
@@ -117,11 +136,19 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
spans += get_spans()
|
||||
|
||||
if(language)
|
||||
var/datum/language/L = language_datums[language]
|
||||
if(!istype(L))
|
||||
L = new language
|
||||
language_datums[language] = L
|
||||
|
||||
spans |= L.spans
|
||||
|
||||
//Log what we've said with an associated timestamp, using the list's len for safety/to prevent overwriting messages
|
||||
log_message(message, INDIVIDUAL_SAY_LOG)
|
||||
|
||||
var/message_range = 7
|
||||
var/radio_return = radio(message, message_mode, spans)
|
||||
var/radio_return = radio(message, message_mode, spans, language)
|
||||
if(radio_return & NOPASS) //There's a whisper() message_mode, no need to continue the proc if that is called
|
||||
return
|
||||
if(radio_return & ITALICS)
|
||||
@@ -139,12 +166,12 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if(pressure < ONE_ATMOSPHERE*0.4) //Thin air, let's italicise the message
|
||||
spans |= SPAN_ITALICS
|
||||
|
||||
send_speech(message, message_range, src, bubble_type, spans)
|
||||
send_speech(message, message_range, src, bubble_type, spans, message_language=language)
|
||||
|
||||
log_say("[name]/[key] : [message]")
|
||||
return 1
|
||||
|
||||
/mob/living/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans)
|
||||
if(!client)
|
||||
return
|
||||
var/deaf_message
|
||||
@@ -156,20 +183,21 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
else
|
||||
deaf_message = "<span class='notice'>You can't hear yourself!</span>"
|
||||
deaf_type = 2 // Since you should be able to hear yourself without looking
|
||||
if(!(message_langs & languages_understood) || force_compose) //force_compose is so AIs don't end up without their hrefs.
|
||||
message = compose_message(speaker, message_langs, raw_message, radio_freq, spans)
|
||||
|
||||
// Recompose message for AI hrefs, language incomprehension.
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans)
|
||||
show_message(message, 2, deaf_message, deaf_type)
|
||||
return message
|
||||
|
||||
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans)
|
||||
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null)
|
||||
var/list/listening = get_hearers_in_view(message_range, source)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7 && M.z == z)) && client) // client is so that ghosts don't have to listen to mice
|
||||
listening |= M
|
||||
|
||||
var/rendered = compose_message(src, languages_spoken, message, , spans)
|
||||
var/rendered = compose_message(src, message_language, message, , spans)
|
||||
for(var/atom/movable/AM in listening)
|
||||
AM.Hear(rendered, src, languages_spoken, message, , spans)
|
||||
AM.Hear(rendered, src, message_language, message, , spans, message_language)
|
||||
|
||||
//speech bubble
|
||||
var/list/speech_bubble_recipients = list()
|
||||
@@ -178,8 +206,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
var/image/I = image('icons/mob/talk.dmi', src, "[bubble_type][say_test(message)]", FLY_LAYER)
|
||||
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
spawn(0)
|
||||
flick_overlay(I, speech_bubble_recipients, 30)
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /.proc/flick_overlay, I, speech_bubble_recipients, 30)
|
||||
|
||||
/mob/proc/binarycheck()
|
||||
return 0
|
||||
@@ -221,6 +248,19 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
else if(length(message) > 2)
|
||||
return department_radio_keys[copytext(message, 1, 3)]
|
||||
|
||||
/mob/living/proc/get_message_language(message)
|
||||
var/static/list/langlist
|
||||
if(!langlist)
|
||||
langlist = subtypesof(/datum/language)
|
||||
|
||||
if(copytext(message, 1, 2) == ",")
|
||||
var/key = copytext(message, 2, 3)
|
||||
for(var/ld in langlist)
|
||||
var/datum/language/LD = ld
|
||||
if(initial(LD.key) == key)
|
||||
return LD
|
||||
return null
|
||||
|
||||
/mob/living/proc/handle_inherent_channels(message, message_mode)
|
||||
if(message_mode == MODE_CHANGELING)
|
||||
switch(lingcheck())
|
||||
@@ -289,22 +329,22 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
|
||||
return message
|
||||
|
||||
/mob/living/proc/radio(message, message_mode, list/spans)
|
||||
/mob/living/proc/radio(message, message_mode, list/spans, language)
|
||||
switch(message_mode)
|
||||
if(MODE_R_HAND)
|
||||
for(var/obj/item/r_hand in get_held_items_for_side("r", all = TRUE))
|
||||
if (r_hand)
|
||||
return r_hand.talk_into(src, message, , spans)
|
||||
return r_hand.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
if(MODE_L_HAND)
|
||||
for(var/obj/item/l_hand in get_held_items_for_side("l", all = TRUE))
|
||||
if (l_hand)
|
||||
return l_hand.talk_into(src, message, , spans)
|
||||
return l_hand.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_INTERCOM)
|
||||
for (var/obj/item/device/radio/intercom/I in view(1, null))
|
||||
I.talk_into(src, message, , spans)
|
||||
I.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_BINARY)
|
||||
@@ -333,3 +373,15 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
if (getBrainLoss() >= 60)
|
||||
return "gibbers, \"[tempinput]\""
|
||||
return ..()
|
||||
|
||||
/mob/living/get_default_language()
|
||||
if(selected_default_language)
|
||||
if(has_language(selected_default_language))
|
||||
return selected_default_language
|
||||
else
|
||||
selected_default_language = null
|
||||
|
||||
. = ..()
|
||||
|
||||
/mob/living/proc/open_language_menu(mob/user)
|
||||
language_menu.ui_interact(user)
|
||||
|
||||
@@ -22,7 +22,6 @@ var/list/ai_list = list()
|
||||
canmove = 0
|
||||
status_flags = CANSTUN|CANPUSH
|
||||
a_intent = INTENT_HARM //so we always get pushed instead of trying to swap
|
||||
force_compose = 1 //This ensures that the AI always composes it's own hear message. Needed for hrefs and job display.
|
||||
sight = SEE_TURFS | SEE_MOBS | SEE_OBJS
|
||||
see_in_dark = 8
|
||||
med_hud = DATA_HUD_MEDICAL_BASIC
|
||||
@@ -831,8 +830,8 @@ var/list/ai_list = list()
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
raw_message = lang_treat(speaker, message_langs, raw_message, spans)
|
||||
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans)
|
||||
raw_message = lang_treat(speaker, message_language, raw_message, spans)
|
||||
var/name_used = speaker.GetVoice()
|
||||
var/rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> <span class='message'>[raw_message]</span></span></i>"
|
||||
show_message(rendered, 2)
|
||||
@@ -985,4 +984,4 @@ var/list/ai_list = list()
|
||||
/mob/living/silicon/ai/spawned/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
|
||||
if(!target_ai)
|
||||
target_ai = src //cheat! just give... ourselves as the spawned AI, because that's technically correct
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -104,6 +104,6 @@
|
||||
acceleration = !acceleration
|
||||
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
|
||||
|
||||
/mob/camera/aiEye/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
|
||||
/mob/camera/aiEye/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans)
|
||||
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
|
||||
ai.relay_speech(message, speaker, message_langs, raw_message, radio_freq, spans)
|
||||
ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/mob/living/silicon/ai/say(message)
|
||||
/mob/living/silicon/ai/say(message, language)
|
||||
if(parent && istype(parent) && parent.stat != 2) //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
|
||||
parent.say(message)
|
||||
parent.say(message, language)
|
||||
return
|
||||
..(message)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/mob/living/silicon/ai/IsVocal()
|
||||
return !config.silent_ai
|
||||
|
||||
/mob/living/silicon/ai/radio(message, message_mode, list/spans)
|
||||
/mob/living/silicon/ai/radio(message, message_mode, list/spans, language)
|
||||
if(!radio_enabled || aiRestorePowerRoutine || stat) //AI cannot speak if radio is disabled (via intellicard) or depowered.
|
||||
to_chat(src, "<span class='danger'>Your radio transmitter is offline!</span>")
|
||||
return 0
|
||||
@@ -29,17 +29,17 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/handle_inherent_channels(message, message_mode)
|
||||
/mob/living/silicon/ai/handle_inherent_channels(message, message_mode, language)
|
||||
. = ..()
|
||||
if(.)
|
||||
return .
|
||||
|
||||
if(message_mode == MODE_HOLOPAD)
|
||||
holopad_talk(message)
|
||||
holopad_talk(message, language)
|
||||
return 1
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/silicon/ai/proc/holopad_talk(message)
|
||||
/mob/living/silicon/ai/proc/holopad_talk(message, language)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
|
||||
message = trim(message)
|
||||
@@ -49,11 +49,10 @@
|
||||
|
||||
var/obj/machinery/holopad/T = current
|
||||
if(istype(T) && T.masters[src])//If there is a hologram and its master is the user.
|
||||
send_speech(message, 7, T, "robot", get_spans())
|
||||
send_speech(message, 7, T, "robot", get_spans(), message_language=language)
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
return
|
||||
|
||||
|
||||
// Make sure that the code compiles with AI_VOX undefined
|
||||
@@ -167,3 +166,12 @@ var/const/VOX_DELAY = 600
|
||||
return 0
|
||||
|
||||
#endif
|
||||
|
||||
/mob/living/silicon/ai/can_speak_in_language(datum/language/dt)
|
||||
if(HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
. = has_language(dt)
|
||||
else if(is_servant_of_ratvar(src))
|
||||
// Ratvarian AIs can only speak Ratvarian
|
||||
. = ispath(dt, /datum/language/ratvar) && has_language(dt)
|
||||
else
|
||||
. = ..()
|
||||
|
||||
@@ -110,10 +110,13 @@
|
||||
var/datum/action/innate/pai/chassis/AC = new /datum/action/innate/pai/chassis
|
||||
var/datum/action/innate/pai/rest/AR = new /datum/action/innate/pai/rest
|
||||
var/datum/action/innate/pai/light/AL = new /datum/action/innate/pai/light
|
||||
|
||||
var/datum/action/language_menu/ALM = new
|
||||
AS.Grant(src)
|
||||
AC.Grant(src)
|
||||
AR.Grant(src)
|
||||
AL.Grant(src)
|
||||
ALM.Grant(src)
|
||||
emittersemicd = TRUE
|
||||
addtimer(CALLBACK(src, .proc/emittercool), 600)
|
||||
|
||||
|
||||
@@ -102,4 +102,4 @@
|
||||
|
||||
/mob/living/silicon/pai/movement_delay()
|
||||
. = ..()
|
||||
. += 1 //A bit slower than humans, so they're easier to smash
|
||||
. += 1 //A bit slower than humans, so they're easier to smash
|
||||
|
||||
@@ -253,9 +253,9 @@
|
||||
med.remove_hud_from(src)
|
||||
if("translator")
|
||||
if(href_list["toggle"])
|
||||
var/on_already = ((languages_understood == ALL) && (languages_spoken == ALL))
|
||||
languages_spoken = on_already ? (HUMAN | ROBOT) : ALL
|
||||
languages_understood = on_already ? (HUMAN | ROBOT) : ALL
|
||||
if(!HAS_SECONDARY_FLAG(src, OMNITONGUE))
|
||||
grant_all_languages(TRUE)
|
||||
// this is PERMAMENT.
|
||||
if("doorjack")
|
||||
if(href_list["jack"])
|
||||
if(src.cable && src.cable.machine)
|
||||
@@ -313,7 +313,8 @@
|
||||
if(s == "medical HUD")
|
||||
dat += "<a href='byond://?src=\ref[src];software=medicalhud;sub=0'>Medical Analysis Suite</a>[(src.medHUD) ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
if(s == "universal translator")
|
||||
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a>[((languages_spoken == ALL) && (languages_understood == ALL)) ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
var/translator_on = HAS_SECONDARY_FLAG(src, OMNITONGUE)
|
||||
dat += "<a href='byond://?src=\ref[src];software=translator;sub=0'>Universal Translator</a>[translator_on ? "<font color=#55FF55> On</font>" : "<font color=#FF5555> Off</font>"] <br>"
|
||||
if(s == "projection array")
|
||||
dat += "<a href='byond://?src=\ref[src];software=projectionarray;sub=0'>Projection Array</a> <br>"
|
||||
if(s == "camera jack")
|
||||
@@ -464,11 +465,10 @@
|
||||
|
||||
// Universal Translator
|
||||
/mob/living/silicon/pai/proc/softwareTranslator()
|
||||
var/translator_on = HAS_SECONDARY_FLAG(src, OMNITONGUE)
|
||||
. = {"<h3>Universal Translator</h3><br>
|
||||
When enabled, this device will automatically convert all spoken and written language into a format that any known recipient can understand.<br><br>
|
||||
The device is currently [ ((languages_spoken == ALL) && (languages_understood == ALL)) ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>
|
||||
<a href='byond://?src=\ref[src];software=translator;sub=0;toggle=1'>Toggle Device</a><br>
|
||||
"}
|
||||
When enabled, this device will permamently be able to speak and understand all known forms of communication.<br><br>
|
||||
The device is currently [translator_on ? "<font color=#55FF55>en" : "<font color=#FF5555>dis" ]abled.</font><br>[translator_on ? "" : "<a href='byond://?src=\ref[src];software=translator;sub=0;toggle=1'>Activate Translation Module</a><br>"]"}
|
||||
return .
|
||||
|
||||
// Security HUD
|
||||
|
||||
@@ -33,19 +33,19 @@
|
||||
/mob/living/silicon/lingcheck()
|
||||
return 0 //Borged or AI'd lings can't speak on the ling channel.
|
||||
|
||||
/mob/living/silicon/radio(message, message_mode, list/spans)
|
||||
/mob/living/silicon/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
|
||||
if(message_mode == "robot")
|
||||
if (radio)
|
||||
radio.talk_into(src, message, , spans)
|
||||
radio.talk_into(src, message, , spans, language)
|
||||
return REDUCE_RANGE
|
||||
|
||||
else if(message_mode in radiochannels)
|
||||
if(radio)
|
||||
radio.talk_into(src, message, message_mode, spans)
|
||||
radio.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
/mob/living/silicon
|
||||
gender = NEUTER
|
||||
voice_name = "synthesized voice"
|
||||
languages_spoken = ROBOT | HUMAN
|
||||
languages_understood = ROBOT | HUMAN
|
||||
has_unlimited_silicon_privilege = 1
|
||||
verb_say = "states"
|
||||
verb_ask = "queries"
|
||||
verb_exclaim = "declares"
|
||||
verb_yell = "alarms"
|
||||
initial_languages = list(/datum/language/common, /datum/language/machine)
|
||||
see_in_dark = 8
|
||||
bubble_icon = "machine"
|
||||
weather_immunities = list("ash")
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
verb_ask = "queries"
|
||||
verb_exclaim = "declares"
|
||||
verb_yell = "alarms"
|
||||
initial_languages = list(/datum/language/common, /datum/language/machine)
|
||||
bubble_icon = "machine"
|
||||
|
||||
faction = list("neutral", "silicon" , "turret")
|
||||
@@ -140,6 +141,9 @@
|
||||
//Gives a HUD view to player bots that use a HUD.
|
||||
activate_data_hud()
|
||||
|
||||
grant_language(/datum/language/common)
|
||||
grant_language(/datum/language/machine)
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/update_canmove()
|
||||
. = ..()
|
||||
@@ -323,30 +327,29 @@
|
||||
if((!on) || (!message))
|
||||
return
|
||||
if(channel && Radio.channels[channel])// Use radio if we have channel key
|
||||
Radio.talk_into(src, message, channel, get_spans())
|
||||
Radio.talk_into(src, message, channel, get_spans(), get_default_language())
|
||||
else
|
||||
say(message)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/get_spans()
|
||||
return ..() | SPAN_ROBOT
|
||||
|
||||
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans)
|
||||
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language)
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
|
||||
switch(message_mode)
|
||||
if(MODE_HEADSET)
|
||||
Radio.talk_into(src, message, , spans)
|
||||
Radio.talk_into(src, message, , spans, language)
|
||||
return REDUCE_RANGE
|
||||
|
||||
if(MODE_DEPARTMENT)
|
||||
Radio.talk_into(src, message, message_mode, spans)
|
||||
Radio.talk_into(src, message, message_mode, spans, language)
|
||||
return REDUCE_RANGE
|
||||
|
||||
if(message_mode in radiochannels)
|
||||
Radio.talk_into(src, message, message_mode, spans)
|
||||
Radio.talk_into(src, message, message_mode, spans, language)
|
||||
return REDUCE_RANGE
|
||||
return 0
|
||||
|
||||
|
||||
@@ -39,6 +39,16 @@
|
||||
weaponscheck = 0
|
||||
auto_patrol = 1
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/jr
|
||||
name = "Officer Pipsqueak"
|
||||
desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize()
|
||||
..()
|
||||
resize = 0.8
|
||||
update_transform()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/beepsky/explode()
|
||||
var/turf/Tsec = get_turf(src)
|
||||
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
voice_name = "synthesized chirp"
|
||||
speak_emote = list("chirps")
|
||||
bubble_icon = "machine"
|
||||
languages_spoken = DRONE
|
||||
languages_understood = DRONE|HUMAN
|
||||
initial_languages = list(/datum/language/common, /datum/language/machine, /datum/language/drone)
|
||||
only_speaks_language = /datum/language/drone
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
has_unlimited_silicon_privilege = 1
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
|
||||
@@ -97,8 +97,6 @@
|
||||
icon_living = "drone_clock"
|
||||
icon_dead = "drone_clock_dead"
|
||||
picked = TRUE
|
||||
languages_spoken = RATVAR
|
||||
languages_understood = HUMAN|RATVAR
|
||||
pass_flags = PASSTABLE
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
@@ -112,6 +110,8 @@
|
||||
verb_exclaim = "proclaims"
|
||||
verb_yell = "harangues"
|
||||
bubble_icon = "clock"
|
||||
initial_languages = list(/datum/language/common, /datum/language/ratvar)
|
||||
only_speaks_language = /datum/language/ratvar
|
||||
light_color = "#E42742"
|
||||
heavy_emp_damage = 0
|
||||
laws = "0. Purge all untruths and honor Ratvar."
|
||||
@@ -139,6 +139,8 @@
|
||||
verbs -= /mob/living/simple_animal/drone/verb/toggle_light
|
||||
verbs -= /mob/living/simple_animal/drone/verb/drone_ping
|
||||
|
||||
grant_language(/datum/language/ratvar)
|
||||
|
||||
/mob/living/simple_animal/drone/cogscarab/Login()
|
||||
..()
|
||||
add_servant_of_ratvar(src, TRUE)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
else
|
||||
to_chat(M, msg)
|
||||
if(dead_can_hear && (M in dead_mob_list))
|
||||
var/link = FOLLOW_LINK(M, src)
|
||||
var/link = FOLLOW_LINK(M, faction_checked_mob)
|
||||
to_chat(M, "[link] [msg]")
|
||||
|
||||
|
||||
|
||||
@@ -369,8 +369,6 @@ Difficulty: Very Hard
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
use_power = 0
|
||||
density = 1
|
||||
languages_spoken = ALL
|
||||
languages_understood = ALL
|
||||
flags = HEAR
|
||||
var/activation_method = "touch"
|
||||
var/activation_damage_type = null
|
||||
@@ -618,8 +616,6 @@ Difficulty: Very Hard
|
||||
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
|
||||
light_range = 4
|
||||
faction = list("neutral")
|
||||
languages_spoken = SLIME
|
||||
languages_understood = ALL
|
||||
del_on_death = 1
|
||||
unsuitable_atmos_damage = 0
|
||||
movement_type = FLYING
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
mouse_opacity = 2 // Easier to click on in melee, they're giant targets anyway
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/Destroy()
|
||||
qdel(internal)
|
||||
QDEL_NULL(internal)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
|
||||
@@ -86,10 +86,7 @@
|
||||
if(!.)
|
||||
return
|
||||
var/turf/newloc = loc
|
||||
message_admins("Megafauna [src] \
|
||||
(<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) \
|
||||
moved via shuttle from ([oldloc.x],[oldloc.y],[oldloc.z]) to \
|
||||
([newloc.x],[newloc.y],[newloc.z])")
|
||||
message_admins("Megafauna [src] [ADMIN_FLW(src)] moved via shuttle from [ADMIN_COORDJMP(oldloc)] to [ADMIN_COORDJMP(newloc)]")
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L)
|
||||
if(!L)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "frog"
|
||||
icon_living = "frog"
|
||||
icon_dead = "frog_dead"
|
||||
speak = list("ribbits","croaks")
|
||||
speak = list("ribbit","croak")
|
||||
emote_see = list("hops in a circle.", "shakes.")
|
||||
speak_chance = 1
|
||||
turns_per_move = 5
|
||||
@@ -39,4 +39,4 @@
|
||||
if(!stat && isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.mob_size > MOB_SIZE_TINY)
|
||||
playsound(src, 'sound/effects/Huuu.ogg', 50, 1)
|
||||
playsound(src, 'sound/effects/Huuu.ogg', 50, 1)
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
return message
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/parrot/radio(message, message_mode, list/spans) //literally copied from human/radio(), but there's no other way to do this. at least it's better than it used to be.
|
||||
/mob/living/simple_animal/parrot/radio(message, message_mode, list/spans, language) //literally copied from human/radio(), but there's no other way to do this. at least it's better than it used to be.
|
||||
. = ..()
|
||||
if(. != 0)
|
||||
return .
|
||||
@@ -162,17 +162,17 @@
|
||||
switch(message_mode)
|
||||
if(MODE_HEADSET)
|
||||
if (ears)
|
||||
ears.talk_into(src, message, , spans)
|
||||
ears.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(MODE_DEPARTMENT)
|
||||
if (ears)
|
||||
ears.talk_into(src, message, message_mode, spans)
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
if(message_mode in radiochannels)
|
||||
if(ears)
|
||||
ears.talk_into(src, message, message_mode, spans)
|
||||
ears.talk_into(src, message, message_mode, spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
return 0
|
||||
@@ -894,6 +894,7 @@
|
||||
desc += " Over [rounds_survived] shifts without a \"terrible\" \"accident\"!"
|
||||
else
|
||||
speak += pick("...alive?", "This isn't parrot heaven!", "I live, I die, I live again!", "The void fades!")
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/Life()
|
||||
|
||||
@@ -95,6 +95,9 @@
|
||||
if(!loc)
|
||||
stack_trace("Simple animal being instantiated in nullspace")
|
||||
|
||||
// goats bray, cows go moo, and the fox says Geckers
|
||||
grant_language(/datum/language/common)
|
||||
|
||||
/mob/living/simple_animal/Login()
|
||||
if(src && src.client)
|
||||
src.client.screen = list()
|
||||
|
||||
@@ -170,8 +170,6 @@
|
||||
|
||||
var/mob/living/simple_animal/slime/new_slime = pick(babies)
|
||||
new_slime.a_intent = INTENT_HARM
|
||||
new_slime.languages_spoken = languages_spoken
|
||||
new_slime.languages_understood = languages_understood
|
||||
if(src.mind)
|
||||
src.mind.transfer_to(new_slime)
|
||||
else
|
||||
|
||||
@@ -13,8 +13,6 @@ var/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
|
||||
gender = NEUTER
|
||||
var/is_adult = 0
|
||||
var/docile = 0
|
||||
languages_spoken = SLIME | HUMAN
|
||||
languages_understood = SLIME | HUMAN
|
||||
faction = list("slime","neutral")
|
||||
|
||||
harm_intent_damage = 5
|
||||
@@ -94,6 +92,7 @@ var/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
|
||||
E.Grant(src)
|
||||
create_reagents(100)
|
||||
set_colour(new_colour)
|
||||
grant_language(/datum/language/slime)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/slime/proc/set_colour(new_colour)
|
||||
@@ -424,4 +423,4 @@ var/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange",
|
||||
return 3
|
||||
|
||||
/mob/living/simple_animal/slime/random/Initialize(mapload, new_colour, new_is_adult)
|
||||
. = ..(mapload, pick(slime_colours), prob(50))
|
||||
. = ..(mapload, pick(slime_colours), prob(50))
|
||||
|
||||
@@ -131,8 +131,6 @@
|
||||
|
||||
var/has_unlimited_silicon_privilege = 0 // Can they interact with station electronics
|
||||
|
||||
var/force_compose = 0 //If this is nonzero, the mob will always compose it's own hear message instead of using the one given in the arguments.
|
||||
|
||||
var/obj/control_object //Used by admins to possess objects. All mobs should have this var
|
||||
var/atom/movable/remote_control //Calls relaymove() to whatever it is
|
||||
|
||||
|
||||
@@ -464,17 +464,6 @@ var/static/regex/firstname = new("^\[^\\s-\]+") //First word before whitespace o
|
||||
message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
|
||||
return FALSE
|
||||
|
||||
//toggles the talk wheel
|
||||
/mob/verb/toggle_talk_wheel()
|
||||
set name = "talk-wheel"
|
||||
set hidden = 1
|
||||
|
||||
if(isliving(src))
|
||||
var/mob/living/L = src
|
||||
if(L.hud_used)
|
||||
for(var/obj/screen/wheel/talk/TW in L.hud_used.wheels)
|
||||
TW.Click()
|
||||
|
||||
/mob/proc/is_flying(mob/M = src)
|
||||
if(M.movement_type & FLYING)
|
||||
return 1
|
||||
@@ -499,4 +488,4 @@ var/static/regex/firstname = new("^\[^\\s-\]+") //First word before whitespace o
|
||||
|
||||
var/list/timestamped_message = list("[LAZYLEN(logging[message_type]) + 1]\[[time_stamp()]\] [key_name(src)]" = message)
|
||||
|
||||
logging[message_type] += timestamped_message
|
||||
logging[message_type] += timestamped_message
|
||||
|
||||
@@ -7,13 +7,17 @@
|
||||
return
|
||||
usr.say(message)
|
||||
|
||||
/mob/verb/whisper(message as text)
|
||||
|
||||
/mob/verb/whisper_verb(message as text)
|
||||
set name = "Whisper"
|
||||
set category = "IC"
|
||||
if(say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
say(message) //only carbons actually whisper, everything else just talks
|
||||
whisper(message)
|
||||
|
||||
/mob/proc/whisper(message, datum/language/language=null)
|
||||
say(message, language) //only carbons actually whisper, everything else just talks
|
||||
|
||||
/mob/verb/me_verb(message as text)
|
||||
set name = "Me"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
gender = NEUTER
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "paper"
|
||||
item_state = "paper"
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_range = 1
|
||||
|
||||
@@ -101,6 +101,6 @@
|
||||
change_setting(current, user)
|
||||
..()
|
||||
|
||||
/obj/machinery/power/floodlight/attack_ai(mob/living/silicon/user)
|
||||
/obj/machinery/power/floodlight/attack_ai(mob/user)
|
||||
attack_hand(user)
|
||||
..()
|
||||
|
||||
@@ -43,10 +43,14 @@
|
||||
|
||||
#define HALLUCINATION_RANGE(P) (min(7, round(P ** 0.25)))
|
||||
|
||||
|
||||
#define GRAVITATIONAL_ANOMALY "gravitational_anomaly"
|
||||
#define FLUX_ANOMALY "flux_anomaly"
|
||||
#define PYRO_ANOMALY "pyro_anomaly"
|
||||
|
||||
#define SPEAK(message) radio.talk_into(src, message, null, get_spans(), get_default_language())
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter_shard
|
||||
name = "supermatter shard"
|
||||
desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure."
|
||||
@@ -333,28 +337,27 @@
|
||||
var/stability = num2text(round((damage / explosion_point) * 100))
|
||||
|
||||
if(damage > emergency_point)
|
||||
|
||||
radio.talk_into(src, "[emergency_alert] Instability: [stability]%")
|
||||
SPEAK("[emergency_alert] Instability: [stability]%")
|
||||
lastwarning = REALTIMEOFDAY
|
||||
if(!has_reached_emergency)
|
||||
investigate_log("has reached the emergency point for the first time.", "supermatter")
|
||||
message_admins("[src] has reached the emergency point <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>(JMP)</a>.")
|
||||
has_reached_emergency = 1
|
||||
else if(damage >= damage_archived) // The damage is still going up
|
||||
radio.talk_into(src, "[warning_alert] Instability: [stability]%")
|
||||
SPEAK("[warning_alert] Instability: [stability]%")
|
||||
lastwarning = REALTIMEOFDAY - (WARNING_DELAY * 5)
|
||||
|
||||
else // Phew, we're safe
|
||||
radio.talk_into(src, "[safe_alert] Instability: [stability]%")
|
||||
SPEAK("[safe_alert] Instability: [stability]%")
|
||||
lastwarning = REALTIMEOFDAY
|
||||
|
||||
if(power > POWER_PENALTY_THRESHOLD)
|
||||
radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.")
|
||||
SPEAK("Warning: Hyperstructure has reached dangerous power level.")
|
||||
if(powerloss_inhibitor < 0.5)
|
||||
radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.")
|
||||
SPEAK("DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.")
|
||||
|
||||
if(combined_gas > MOLE_PENALTY_THRESHOLD)
|
||||
radio.talk_into(src, "Warning: Critical coolant mass reached.")
|
||||
SPEAK("Warning: Critical coolant mass reached.")
|
||||
|
||||
if(damage > explosion_point)
|
||||
for(var/mob in living_mob_list)
|
||||
|
||||
@@ -261,9 +261,8 @@
|
||||
|
||||
if(!new_mob)
|
||||
return
|
||||
|
||||
new_mob.languages_spoken |= HUMAN
|
||||
new_mob.languages_understood |= HUMAN
|
||||
new_mob.grant_language(/datum/language/common)
|
||||
SET_SECONDARY_FLAG(new_mob, OMNITONGUE)
|
||||
new_mob.logging = M.logging
|
||||
|
||||
// Some forms can still wear some items
|
||||
|
||||
@@ -556,7 +556,7 @@
|
||||
//~~~~~~~~Admin logging proc, aka the Powergamer Alarm~~~~~~~~
|
||||
/obj/machinery/r_n_d/experimentor/proc/warn_admins(mob/user, ReactionName)
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("Experimentor reaction: [ReactionName] generated by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) at ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
message_admins("Experimentor reaction: [ReactionName] generated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game("Experimentor reaction: [ReactionName] generated by [key_name(user)] in ([T.x],[T.y],[T.z])")
|
||||
|
||||
#undef SCANTYPE_POKE
|
||||
@@ -703,6 +703,6 @@
|
||||
var/turf/T = get_turf(src)
|
||||
var/log_msg = "[RelicType] relic used by [key_name(user)] in ([T.x],[T.y],[T.z])"
|
||||
if(priority) //For truly dangerous relics that may need an admin's attention. BWOINK!
|
||||
message_admins("[RelicType] relic activated by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
message_admins("[RelicType] relic activated by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1)
|
||||
log_game(log_msg)
|
||||
investigate_log(log_msg, "experimentor")
|
||||
|
||||
@@ -190,8 +190,6 @@
|
||||
if(candidates.len)
|
||||
theghost = pick(candidates)
|
||||
SM.key = theghost.key
|
||||
SM.languages_spoken |= HUMAN
|
||||
SM.languages_understood |= HUMAN
|
||||
SM.mind.enslave_mind_to_creator(user)
|
||||
SM.sentience_act()
|
||||
to_chat(SM, "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>")
|
||||
@@ -238,8 +236,6 @@
|
||||
|
||||
|
||||
user.mind.transfer_to(SM)
|
||||
SM.languages_spoken = user.languages_spoken
|
||||
SM.languages_understood = user.languages_understood
|
||||
SM.faction = user.faction.Copy()
|
||||
SM.sentience_act() //Same deal here as with sentience
|
||||
user.death()
|
||||
|
||||
@@ -65,9 +65,10 @@
|
||||
var/never_spoken = TRUE
|
||||
flags = NODECONSTRUCT
|
||||
|
||||
/obj/structure/table/abductor/wabbajack/New()
|
||||
/obj/structure/table/abductor/wabbajack/Initialize(mapload)
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
grant_language(/datum/language/common)
|
||||
|
||||
/obj/structure/table/abductor/wabbajack/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -145,14 +146,13 @@
|
||||
laws = "1. Serve drinks.\n\
|
||||
2. Talk to patrons.\n\
|
||||
3. Don't get messed up in their affairs."
|
||||
languages_spoken = ALL
|
||||
languages_understood = ALL
|
||||
status_flags = GODMODE // Please don't punch the barkeeper
|
||||
unique_name = FALSE // disables the (123) number suffix
|
||||
|
||||
/mob/living/simple_animal/drone/snowflake/bardrone/Initialize()
|
||||
. = ..()
|
||||
access_card.access |= access_cent_bar
|
||||
grant_all_languages(omnitongue=TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/maid/barmaid
|
||||
gold_core_spawnable = 0
|
||||
@@ -160,8 +160,6 @@
|
||||
desc = "A barmaid, a maiden found in a bar."
|
||||
pass_flags = PASSTABLE
|
||||
status_flags = GODMODE
|
||||
languages_spoken = ALL
|
||||
languages_understood = ALL
|
||||
unique_name = FALSE
|
||||
AIStatus = AI_OFF
|
||||
stop_automated_movement = TRUE
|
||||
@@ -174,6 +172,8 @@
|
||||
access_card.access |= access_cent_bar
|
||||
access_card.flags |= NODROP
|
||||
|
||||
grant_all_languages(omnitongue=TRUE)
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/maid/barmaid/Destroy()
|
||||
qdel(access_card)
|
||||
. = ..()
|
||||
@@ -218,7 +218,7 @@
|
||||
//Luxury Shuttle Blockers
|
||||
|
||||
/obj/effect/forcefield/luxury_shuttle
|
||||
var/threshhold = 500
|
||||
var/threshold = 500
|
||||
var/static/list/approved_passengers = list()
|
||||
|
||||
/obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
@@ -234,15 +234,15 @@
|
||||
for(var/obj/item/weapon/coin/C in mover.GetAllContents())
|
||||
total_cash += C.value
|
||||
counted_money += C
|
||||
if(total_cash >= threshhold)
|
||||
if(total_cash >= threshold)
|
||||
break
|
||||
for(var/obj/item/stack/spacecash/S in mover.GetAllContents())
|
||||
total_cash += S.value * S.amount
|
||||
counted_money += S
|
||||
if(total_cash >= threshhold)
|
||||
if(total_cash >= threshold)
|
||||
break
|
||||
|
||||
if(total_cash >= threshhold)
|
||||
if(total_cash >= threshold)
|
||||
for(var/obj/I in counted_money)
|
||||
qdel(I)
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
for(var/mob/living/carbon/human/H in targets)
|
||||
if(!H.mind)
|
||||
continue
|
||||
for(var/datum/objective/sintouched/A in H.mind.objectives)
|
||||
if(locate(/datum/objective/sintouched) in H.mind.objectives)
|
||||
continue
|
||||
H.influenceSin()
|
||||
H.Weaken(2)
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
for(var/path in possible_shapes)
|
||||
var/mob/living/simple_animal/A = path
|
||||
animal_list[initial(A.name)] = path
|
||||
shapeshift_type = input(M, "Choose Your Animal Form!", "It's Morphing Time!", null) as anything in animal_list
|
||||
var/new_shapeshift_type = input(M, "Choose Your Animal Form!", "It's Morphing Time!", null) as null|anything in animal_list
|
||||
if(shapeshift_type)
|
||||
return
|
||||
shapeshift_type = new_shapeshift_type
|
||||
if(!shapeshift_type) //If you aren't gonna decide I am!
|
||||
shapeshift_type = pick(animal_list)
|
||||
shapeshift_type = animal_list[shapeshift_type]
|
||||
@@ -80,4 +83,4 @@
|
||||
shapeshift_type = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
|
||||
list/current_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser)
|
||||
list/current_casters = list()
|
||||
list/possible_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser)
|
||||
list/possible_shapes = list(/mob/living/simple_animal/hostile/megafauna/dragon/lesser)
|
||||
|
||||
@@ -512,9 +512,18 @@
|
||||
zone = "mouth"
|
||||
slot = "tongue"
|
||||
attack_verb = list("licked", "slobbered", "slapped", "frenched", "tongued")
|
||||
var/list/languages_possible
|
||||
var/say_mod = null
|
||||
var/taste_sensitivity = 15 // lower is more sensitive.
|
||||
|
||||
/obj/item/organ/tongue/Initialize(mapload)
|
||||
..()
|
||||
languages_possible = typecacheof(list(
|
||||
/datum/language/common,
|
||||
/datum/language/monkey,
|
||||
/datum/language/ratvar
|
||||
))
|
||||
|
||||
/obj/item/organ/tongue/get_spans()
|
||||
return list()
|
||||
|
||||
@@ -531,6 +540,9 @@
|
||||
if(say_mod && M.dna && M.dna.species)
|
||||
M.dna.species.say_mod = initial(M.dna.species.say_mod)
|
||||
|
||||
/obj/item/organ/tongue/can_speak_in_language(datum/language/dt)
|
||||
. = is_type_in_typecache(dt, languages_possible)
|
||||
|
||||
/obj/item/organ/tongue/lizard
|
||||
name = "forked tongue"
|
||||
desc = "A thin and long muscle typically found in reptilian races, apparently moonlights as a nose."
|
||||
@@ -617,6 +629,14 @@
|
||||
say_mod = "hisses"
|
||||
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
|
||||
|
||||
/obj/item/organ/tongue/alien/Initialize(mapload)
|
||||
..()
|
||||
languages_possible = typecacheof(list(
|
||||
/datum/language/xenocommon,
|
||||
/datum/language/common,
|
||||
/datum/language/ratvar,
|
||||
/datum/language/monkey))
|
||||
|
||||
/obj/item/organ/tongue/alien/TongueSpeech(var/message)
|
||||
playsound(owner, "hiss", 25, 1, 1)
|
||||
return message
|
||||
@@ -664,6 +684,17 @@
|
||||
attack_verb = list("beeped", "booped")
|
||||
taste_sensitivity = 25 // not as good as an organic tongue
|
||||
|
||||
/obj/item/organ/tongue/robot/Initialize(mapload)
|
||||
..()
|
||||
languages_possible = typecacheof(list(
|
||||
/datum/language/xenocommon,
|
||||
/datum/language/common,
|
||||
/datum/language/ratvar,
|
||||
/datum/language/monkey,
|
||||
/datum/language/drone,
|
||||
/datum/language/machine,
|
||||
/datum/language/swarmer))
|
||||
|
||||
/obj/item/organ/tongue/robot/get_spans()
|
||||
return ..() | SPAN_ROBOT
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* tgui state: language_menu_state
|
||||
*/
|
||||
|
||||
/var/global/datum/ui_state/language_menu/language_menu_state = new()
|
||||
|
||||
/datum/ui_state/language_menu/can_use_topic(src_object, mob/user)
|
||||
. = UI_CLOSE
|
||||
if(check_rights_for(user.client, R_ADMIN))
|
||||
. = UI_INTERACTIVE
|
||||
else if(istype(src_object, /datum/language_menu))
|
||||
var/datum/language_menu/LM = src_object
|
||||
if(LM.owner == user)
|
||||
. = UI_INTERACTIVE
|
||||
Reference in New Issue
Block a user