Fixes Runechat runtimes and Adds Singing And fixes lots of other runtimes (#10325)

* E

* More runtimes

* Fucking i(n)dent I swear
This commit is contained in:
Jamie D
2020-11-05 20:25:37 +00:00
committed by GitHub
parent a9d58988e9
commit b80a77572d
54 changed files with 272 additions and 245 deletions

View File

@@ -3,6 +3,10 @@
Currently contains speech spans and message modes
*/
#define RADIO_EXTENSION "department specific"
#define RADIO_KEY "department specific key"
#define LANGUAGE_EXTENSION "language specific"
//Message modes. Each one defines a radio channel, more or less.
#define MODE_HEADSET "headset"
#define MODE_ROBOT "robot"
@@ -20,6 +24,7 @@
#define MODE_KEY_BINARY "b"
#define MODE_TOKEN_BINARY ":b"
#define WHISPER_MODE "the type of whisper"
#define MODE_WHISPER "whisper"
#define MODE_WHISPER_CRIT "whispercrit"
@@ -45,6 +50,8 @@
#define MODE_MONKEY "monkeyhive"
#define MODE_SING "sing"
#define MODE_DARKSPAWN "mindlink"
//Spans. Robot speech, italics, etc. Applied in compose_message().
@@ -56,6 +63,7 @@
#define SPAN_REALLYBIG "reallybig"
#define SPAN_COMMAND "command_headset"
#define SPAN_CLOWN "clown"
#define SPAN_SINGING "singing"
//bitflag #defines for return value of the radio() proc.
#define ITALICS (1<<0)

View File

@@ -146,10 +146,10 @@
friend_talk(message)
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
/mob/camera/imaginary_friend/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode))
create_chat_message(speaker, message_language, raw_message, spans)
to_chat(src, compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mods))
/mob/camera/imaginary_friend/proc/friend_talk(message)
message = capitalize(trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)))

View File

@@ -47,6 +47,7 @@
var/datum/chatmessage/prev
/// The current index used for adjusting the layer of each sequential chat message such that recent messages will overlay older ones
var/static/current_z_idx = 0
/**
* Constructs a chat message overlay
*
@@ -91,7 +92,7 @@
* Arguments:
* * text - The text content of the overlay
* * target - The target atom to display the overlay at
* * owner - The mob that owns this overlay, only this mob will be able to view it#
* * owner - The mob that owns this overlay, only this mob will be able to view it
* * language - The language this message was spoken in
* * extra_classes - Extra classes to apply to the span that holds the text
* * lifespan - The lifespan of the message in deciseconds
@@ -224,7 +225,6 @@
* * message_language - The language that the message is said in
* * raw_message - The text content of the message
* * spans - Additional classes to be added to the message
* * message_mode - Bitflags relating to the mode of the message
*/
/mob/proc/create_chat_message(atom/movable/speaker, datum/language/message_language, raw_message, list/spans, runechat_flags = NONE)
// Ensure the list we are using, if present, is a copy so we don't modify the list provided to us

View File

@@ -16,6 +16,7 @@
var/verb_ask = "asks"
var/verb_exclaim = "exclaims"
var/verb_whisper = "whispers"
var/verb_sing = "sings"
var/verb_yell = "yells"
var/speech_span
var/inertia_dir = 0

View File

@@ -22,7 +22,7 @@
if(voice_activated)
flags_1 |= HEAR_1
/obj/machinery/door/password/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/obj/machinery/door/password/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(!density || !voice_activated || radio_freq)
return

View File

@@ -420,17 +420,17 @@ obj/machinery/holopad/secure/Initialize()
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/holopad/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
/obj/machinery/holopad/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(speaker && LAZYLEN(masters) && !radio_freq)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios.
for(var/mob/living/silicon/ai/master in masters)
if(masters[master] && speaker != master)
master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mods)
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad == src && speaker != HC.hologram)
HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mods)
if(outgoing_call && speaker == outgoing_call.user)
outgoing_call.hologram.say(raw_message)

View File

@@ -344,7 +344,7 @@ GLOBAL_LIST_EMPTY(req_console_ckey_departments)
updateUsrDialog()
/obj/machinery/requests_console/say_mod(input, message_mode)
/obj/machinery/requests_console/say_mod(input, list/message_mods = list())
if(spantext_char(input, "!", -3))
return "blares"
else

View File

@@ -103,6 +103,7 @@
datum/language/language, // the language of the message
message, // the text content of the message
spans, // the list of spans applied to the message
list/message_mods, // the list of modification applied to the message. Whispering, singing, ect
lvls = null //Yogs -- For NTSL. It's the list of Z-levels that should hear this message.
)
src.source = source
@@ -116,7 +117,8 @@
"message" = message,
"compression" = rand(35, 65),
"language" = lang_instance.name,
"spans" = spans
"spans" = spans,
"mods" = message_mods
)
//Yogs start
if(lvls)
@@ -188,9 +190,10 @@
// Render the message and have everybody hear it.
// Always call this on the virtualspeaker to avoid issues.
var/spans = data["spans"]
var/list/message_mods = data["mods"]
var/rendered = virt.compose_message(virt, language, message, frequency, spans)
for(var/atom/movable/hearer in receive)
hearer.Hear(rendered, virt, language, message, frequency, spans)
hearer.Hear(rendered, virt, language, message, frequency, spans, message_mods)
// This following recording is intended for research and feedback in the use of department radio channels
if(length(receive))

View File

@@ -462,11 +462,11 @@
/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits.
return
/obj/mecha/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/obj/mecha/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(speaker == occupant)
if(radio?.broadcasting)
radio.talk_into(speaker, text, , spans, message_language)
radio.talk_into(speaker, text, , spans, message_language, message_mods)
//flick speech bubble
var/list/speech_bubble_recipients = list()
for(var/mob/M in get_hearers_in_view(7,src))

View File

@@ -376,7 +376,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
return 1
return 0
/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language)
/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language, list/message_mods)
return ITALICS | REDUCE_RANGE
/obj/item/proc/dropped(mob/user)

View File

@@ -60,7 +60,7 @@ GLOBAL_LIST_INIT(channel_tokens, list(
QDEL_NULL(keyslot2)
return ..()
/obj/item/radio/headset/talk_into(mob/living/M, message, channel, list/spans,datum/language/language)
/obj/item/radio/headset/talk_into(mob/living/M, message, channel, list/spans, datum/language/language, list/message_mods)
if (!listening)
return ITALICS | REDUCE_RANGE
return ..()

View File

@@ -112,8 +112,8 @@
return TRUE
/obj/item/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
if (message_mode == MODE_INTERCOM)
/obj/item/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, list/message_mods = list())
if(message_mods[RADIO_EXTENSION] == MODE_INTERCOM)
return // Avoid hearing the same thing twice
if(!anyai && !(speaker in ai)) // set the intercomms in AI cores to 0 when this gets implemented
return

View File

@@ -189,15 +189,15 @@
recalculateChannels()
. = TRUE
/obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language)
/obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language, list/message_mods)
if(!spans)
spans = list(M.speech_span)
if(!language)
language = M.get_selected_language()
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language)
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language, message_mods)
return ITALICS | REDUCE_RANGE
/obj/item/radio/proc/talk_into_impl(atom/movable/M, message, channel, list/spans, datum/language/language)
/obj/item/radio/proc/talk_into_impl(atom/movable/M, message, channel, list/spans, datum/language/language, list/message_mods)
if(!on)
return // the device has to be on
if(!M || !message)
@@ -246,7 +246,7 @@
var/atom/movable/virtualspeaker/speaker = new(null, M, src)
// Construct the signal
var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, message, spans)
var/datum/signal/subspace/vocal/signal = new(src, freq, speaker, language, message, spans, message_mods)
// Independent radios, on the CentCom frequency, reach all independent radios
if (independent && (freq == FREQ_CENTCOM || freq == FREQ_CTF_RED || freq == FREQ_CTF_BLUE))
@@ -278,21 +278,18 @@
signal.levels = list(T.z)
signal.broadcast()
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range)
return
if(message_mode == MODE_WHISPER || message_mode == MODE_WHISPER_CRIT)
// radios don't pick up whispers very well
raw_message = stars(raw_message)
else if(message_mode == MODE_L_HAND || message_mode == MODE_R_HAND)
if(message_mods[RADIO_EXTENSION] == MODE_L_HAND || message_mods[RADIO_EXTENSION] == MODE_R_HAND)
// try to avoid being heard double
if (loc == speaker && ismob(speaker))
var/mob/M = speaker
var/idx = M.get_held_index_of_item(src)
// left hands are odd slots
if (idx && (idx % 2) == (message_mode == MODE_L_HAND))
if (idx && (idx % 2) == (message_mods[RADIO_EXTENSION] == MODE_L_HAND))
return
talk_into(speaker, raw_message, , spans, language=message_language)

View File

@@ -114,7 +114,7 @@
icon_state = "taperecorder_idle"
/obj/item/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
/obj/item/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, list/message_mods = list())
. = ..()
if(mytape && recording)
mytape.timestamp += mytape.used_capacity

View File

@@ -153,7 +153,7 @@
interact(user)
return ..()
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, list/message_mods = list())
. = ..()
last_message = raw_message

View File

@@ -1569,7 +1569,7 @@ obj/item/toy/turn_tracker
to_chat(user, "You name the dummy as \"[doll_name]\"")
name = "[initial(name)] - [doll_name]"
/obj/item/toy/dummy/talk_into(atom/movable/A, message, channel, list/spans, datum/language/language)
/obj/item/toy/dummy/talk_into(atom/movable/A, message, channel, list/spans, datum/language/language, list/message_mods)
var/mob/M = A
if (istype(M))
M.log_talk(message, LOG_SAY, tag="dummy toy")

View File

@@ -31,19 +31,19 @@ GLOBAL_LIST_INIT(freqtospan, list(
language = get_selected_language()
send_speech(message, 7, src, , spans, message_language=language)
/atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args)
/atom/movable/proc/can_speak()
return 1
/atom/movable/proc/send_speech(message, range = 7, obj/source = src, bubble_type, list/spans, datum/language/message_language = null, message_mode)
var/rendered = compose_message(src, message_language, message, , spans, message_mode)
/atom/movable/proc/send_speech(message, range = 7, obj/source = src, bubble_type, list/spans, datum/language/message_language = null, list/message_mods = list())
var/rendered = compose_message(src, message_language, message, , spans, message_mods)
for(var/_AM in get_hearers_in_view(range, source))
var/atom/movable/AM = _AM
AM.Hear(rendered, src, message_language, message, , spans, message_mode)
AM.Hear(rendered, src, message_language, message, , spans, message_mods)
/atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE)
/atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list(), face_name = FALSE)
//This proc uses text() because it is faster than appending strings. Thanks BYOND.
//Basic span
var/spanpart1 = "<span class='[radio_freq ? get_radio_span(radio_freq) : "game say"]'>"
@@ -61,7 +61,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
var/endspanpart = "</span></a>"// Yogs
//Message
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans, message_mode)]</span></span>"
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans, message_mods)]</span></span>"
var/languageicon = ""
var/datum/language/D = GLOB.language_datum_instances[message_language]
@@ -77,10 +77,12 @@ GLOBAL_LIST_INIT(freqtospan, list(
/atom/movable/proc/compose_job(atom/movable/speaker, message_langs, raw_message, radio_freq)
return ""
/atom/movable/proc/say_mod(input, message_mode)
/atom/movable/proc/say_mod(input, list/message_mods = list())
var/ending = copytext_char(input, -1)
if(copytext_char(input, -2) == "!!")
return verb_yell
else if(message_mods[MODE_SING])
. = verb_sing
else if(ending == "?")
return verb_ask
else if(ending == "!")
@@ -88,7 +90,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
else
return verb_say
/atom/movable/proc/say_quote(input, list/spans=list(speech_span), message_mode)
/atom/movable/proc/say_quote(input, list/spans=list(speech_span), list/message_mods = list())
if(!input)
input = "..."
@@ -96,23 +98,23 @@ GLOBAL_LIST_INIT(freqtospan, list(
spans |= SPAN_YELL
var/spanned = attach_spans(input, spans)
return "[say_mod(input, message_mode)], \"[spanned]\""
return "[say_mod(input, message_mods)], \"[spanned]\""
/atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, message_mode, no_quote = FALSE)
/atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, list/message_mods = list(), no_quote = FALSE)
if(has_language(language))
var/atom/movable/AM = speaker.GetSource()
if(AM) //Basically means "if the speaker is virtual"
return no_quote ? raw_message : AM.say_quote(raw_message, spans, message_mode)
return no_quote ? raw_message : AM.say_quote(raw_message, spans, message_mods)
else
return no_quote ? raw_message : speaker.say_quote(raw_message, spans, message_mode)
return no_quote ? raw_message : speaker.say_quote(raw_message, spans, message_mods)
else if(language)
var/atom/movable/AM = speaker.GetSource()
var/datum/language/D = GLOB.language_datum_instances[language]
raw_message = D.scramble(raw_message)
if(AM)
return no_quote ? raw_message : AM.say_quote(raw_message, spans, message_mode)
return no_quote ? raw_message : AM.say_quote(raw_message, spans, message_mods)
else
return no_quote ? raw_message : speaker.say_quote(raw_message, spans, message_mode)
return no_quote ? raw_message : speaker.say_quote(raw_message, spans, message_mods)
else
return "makes a strange sound."

View File

@@ -113,7 +113,7 @@ the new instance inside the host to be updated to the template's stats.
follow_next(Dir & NORTHWEST)
last_move_tick = world.time
/mob/camera/disease/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/mob/camera/disease/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
var/atom/movable/to_follow = speaker
if(radio_freq)
@@ -126,9 +126,9 @@ the new instance inside the host to be updated to the template's stats.
link = ""
// Create map text prior to modifying message for goonchat
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
create_chat_message(speaker, message_language, raw_message, spans)
// Recompose the message, because it's scrambled by default
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mods)
to_chat(src, "[link] [message]")

View File

@@ -25,7 +25,7 @@
. = ..()
. += "<span class='notice'>Use a multitool to swap between \"inclusive\", \"exclusive\", \"recognizer\", and \"voice sensor\" mode.</span>"
/obj/item/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/obj/item/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(speaker == src)
return

View File

@@ -145,8 +145,8 @@
if(!parent)
WARNING("Component is missing a pipenet! Rebuilding...")
SSair.add_to_rebuild_queue(src)
parent = parents[i]
parent.update = 1
else
parent.update = 1
/obj/machinery/atmospherics/components/returnPipenets()
. = list()

View File

@@ -35,7 +35,7 @@
else
environment_temperature = T.return_temperature()
if(abs(environment_temperature-pipe_air.return_temperature()) > minimum_temperature_difference)
if(abs(environment_temperature-pipe_air?.return_temperature()) > minimum_temperature_difference)
parent.temperature_interact(T, volume, thermal_conductivity)

View File

@@ -112,7 +112,7 @@
/obj/item/clothing/neck/bodycam/dropped(mob/wearer)
..()
if (bodcam.status)//if it's on
if (bodcam?.status)//if it's on
attack_self(wearer) //turn it off
GLOB.cameranet.updatePortableCamera(bodcam)
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)

View File

@@ -11,3 +11,4 @@
space_chance = 20
default_priority = 10
icon_state = "aphasia"
sing_verb = "gibbers"

View File

@@ -20,3 +20,4 @@
"tail", "trim", "tube", "wobble", "roll", "gnarly", "epic")
icon_state = "beach"
sing_verb = "parties"

View File

@@ -9,6 +9,7 @@
default_priority = 100
icon_state = "galcom"
sing_verb = "sings"
//Syllable Lists
/*

View File

@@ -18,3 +18,4 @@
)
icon_state = "lizard"
default_priority = 90
sing_verb = "sings"

View File

@@ -14,3 +14,4 @@
default_priority = 20
icon_state = "drone"
sing_verb = "chimes"

View File

@@ -21,7 +21,7 @@
var/list/spans = list()
var/list/scramble_cache = list()
var/default_priority = 0 // the language that an atom knows with the highest "default_priority" is selected by default.
var/sing_verb = "sings" // Used for singing.
// if you are seeing someone speak popcorn language, then something is wrong.
var/icon = 'icons/misc/language.dmi'
var/icon_state = "popcorn"

View File

@@ -12,6 +12,7 @@
default_priority = 90
icon_state = "eal"
sing_verb = "whistles melodically"
/datum/language/machine/get_random_name()
if(prob(70))

View File

@@ -8,5 +8,5 @@
space_chance = 100
syllables = list("oop", "aak", "chee", "eek")
default_priority = 80
sing_verb = "chimpers tunefully"
icon_state = "animal"

View File

@@ -9,3 +9,4 @@
sentence_chance = 0
default_priority = 80
syllables = list("poof", "pff", "pFfF", "piff", "puff", "pooof", "pfffff", "piffpiff", "puffpuff", "poofpoof", "pifpafpofpuf")
sing_verb = "puffs musically"

View File

@@ -6,6 +6,7 @@
exclaim_verb = "invokes"
key = "n"
sentence_chance = 8
sing_verb = "intones"
space_chance = 95 //very high due to the potential length of each syllable
var/static/list/base_syllables = list(
"h", "v", "c", "e", "g", "d", "r", "n", "h", "o", "p",

View File

@@ -13,3 +13,4 @@
"shiver","timbers","matey","swashbuckler"
)
icon_state = "pirate"
sing_verb = "shanties"

View File

@@ -7,5 +7,5 @@
key = "k"
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!")
default_priority = 70
sing_verb = "warbles"
icon_state = "slime"

View File

@@ -10,7 +10,7 @@
space_chance = 100
sentence_chance = 0
default_priority = 60
sing_verb = "tones"
icon_state = "swarmer"
// since various flats and sharps are the same,

View File

@@ -7,6 +7,7 @@
exclaim_verb = "declares"
key = "h"
space_chance = 20
sing_verb = "serenades"
syllables = list(
"fii", "sii", "rii", "rel", "maa", "ala", "san", "tol", "tok", "dia", "eres",
"fal", "tis", "bis", "qel", "aras", "losk", "rasa", "eob", "hil", "tanl", "aere",

View File

@@ -7,5 +7,5 @@
key = "4"
syllables = list("sss","sSs","SSS")
default_priority = 50
sing_verb = "hisses musically"
icon_state = "xeno"

View File

@@ -1,16 +1,27 @@
/mob/dead/observer/check_emote(message, forced)
if(message == "*spin" || message == "*flip")
emote(copytext(message, length(message[1]) + 1), intentional = !forced)
return TRUE
//Modified version of get_message_mods, removes the trimming, the only thing we care about here is admin channels
/mob/dead/observer/get_message_mods(message, list/mods)
var/key = message[1]
if((key in GLOB.department_radio_prefixes) && length(message) > length(key) + 1 && !mods[RADIO_EXTENSION])
mods[RADIO_KEY] = lowertext(message[1 + length(key)])
mods[RADIO_EXTENSION] = GLOB.department_radio_keys[mods[RADIO_KEY]]
return message
/mob/dead/observer/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
if (!message)
return
var/message_mode = get_message_mode(message)
if(client && (message_mode == MODE_ADMIN || message_mode == MODE_DEADMIN))
message = copytext_char(message, 3)
message = trim_left(message)
if(message_mode == MODE_ADMIN)
var/list/message_mods = list()
message = get_message_mods(message, message_mods)
if(client && (message_mods[RADIO_EXTENSION] == MODE_ADMIN || message_mods[RADIO_EXTENSION] == MODE_DEADMIN))
message = trim_left(copytext_char(message, length(message_mods[RADIO_KEY]) + 2))
if(message_mods[RADIO_EXTENSION] == MODE_ADMIN)
client.cmd_admin_say(message)
else if(message_mode == MODE_DEADMIN)
else if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN)
client.dsay(message)
return
@@ -19,7 +30,7 @@
. = say_dead(message)
/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
var/atom/movable/to_follow = speaker
if(radio_freq)
@@ -33,7 +44,7 @@
var/link = FOLLOW_LINK(src, to_follow)
// Create map text prior to modifying message for goonchat
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
create_chat_message(speaker, message_language, raw_message, spans)
// Recompose the message, because it's scrambled by default
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mods)
to_chat(src, "[link] [message]")

View File

@@ -10,11 +10,11 @@
..()
/mob/living/brain/radio(message, message_mode, list/spans, language)
if(message_mode == MODE_HEADSET && istype(container, /obj/item/mmi))
/mob/living/brain/radio(message, list/message_mods = list(), list/spans, language)
if(message_mods[MODE_HEADSET] && istype(container, /obj/item/mmi))
var/obj/item/mmi/R = container
if(R.radio)
R.radio.talk_into(src, message, language = language)
R.radio.talk_into(src, message, language = language, message_mods = message_mods)
return ITALICS | REDUCE_RANGE
else
return ..()

View File

@@ -20,4 +20,4 @@
/mob/living/carbon/hivecheck()
var/obj/item/organ/alien/hivenode/N = getorgan(/obj/item/organ/alien/hivenode)
if(N && !N.recent_queen_death) //Mob has alien hive node and is not under the dead queen special effect.
return N
return TRUE

View File

@@ -52,25 +52,22 @@
if(dongle.translate_binary)
return TRUE
/mob/living/carbon/human/radio(message, message_mode, list/spans, language)
/mob/living/carbon/human/radio(message, list/message_mods = list(), list/spans, language) //Poly has a copy of this, lazy bastard
. = ..()
if(. != 0)
if(. != FALSE)
return .
switch(message_mode)
if(MODE_HEADSET)
if (ears)
ears.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
if(MODE_DEPARTMENT)
if (ears)
ears.talk_into(src, message, message_mode, spans, language)
return ITALICS | REDUCE_RANGE
if(message_mode in GLOB.radiochannels)
if(message_mods[MODE_HEADSET])
if(ears)
ears.talk_into(src, message, message_mode, spans, language)
ears.talk_into(src, message, , spans, language, message_mods)
return ITALICS | REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] == MODE_DEPARTMENT)
if(ears)
ears.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return ITALICS | REDUCE_RANGE
else if(GLOB.radiochannels[message_mods[RADIO_EXTENSION]])
if(ears)
ears.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return ITALICS | REDUCE_RANGE
return 0

View File

@@ -82,33 +82,26 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return new_msg
/mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
var/static/list/crit_allowed_modes = list(MODE_WHISPER = TRUE, MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE)
var/static/list/crit_allowed_modes = list(WHISPER_MODE = TRUE, MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE)
var/static/list/unconscious_allowed_modes = list(MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE)
var/talk_key = get_key(message)
var/static/list/one_character_prefix = list(MODE_HEADSET = TRUE, MODE_ROBOT = TRUE, MODE_WHISPER = TRUE)
if(sanitize)
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
if(!message || message == "")
return
var/datum/saymode/saymode = SSradio.saymodes[talk_key]
var/message_mode = get_message_mode(message)
var/list/message_mods = list()
var/original_message = message
message = get_message_mods(message, message_mods)
var/datum/saymode/saymode = SSradio.saymodes[message_mods[RADIO_KEY]]
var/in_critical = InCritical()
if(one_character_prefix[message_mode])
message = copytext_char(message, 2)
else if(message_mode || saymode)
message = copytext_char(message, 3)
message = trim_left(message)
if(message_mode == MODE_ADMIN)
if(message_mods[RADIO_EXTENSION] == MODE_ADMIN)
if(client)
client.cmd_admin_say(message)
return
if(message_mode == MODE_DEADMIN)
if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN)
if(client)
client.dsay(message)
return
@@ -120,34 +113,28 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(check_emote(original_message, forced) || !can_speak_basic(original_message, ignore_spam))
return
if(in_critical)
if(!(crit_allowed_modes[message_mode]))
if(in_critical) //There are cheaper ways to do this, but they're less flexible, and this isn't ran all that often
var/end = TRUE
for(var/index in message_mods)
if(crit_allowed_modes[index])
end = FALSE
break
if(end)
return
else if(stat == UNCONSCIOUS)
if(!(unconscious_allowed_modes[message_mode]))
var/end = TRUE
for(var/index in message_mods)
if(unconscious_allowed_modes[index])
end = FALSE
break
if(end)
return
// 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_language(message_language))
language = message_language
message = copytext_char(message, 3)
// Trim the space if they said ",0 I LOVE LANGUAGES"
message = trim_left(message)
language = message_mods[LANGUAGE_EXTENSION]
if(!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
// ignore the language argument however.
if(saymode && !saymode.handle_message(src, message, language))
return
if(!can_speak_vocal(message))
to_chat(src, "<span class='warning'>You find yourself unable to speak!</span>")
return
@@ -157,13 +144,13 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/succumbed = FALSE
var/fullcrit = InFullCritical()
if((InCritical() && !fullcrit) || message_mode == MODE_WHISPER)
if((InCritical() && !fullcrit) || message_mods[WHISPER_MODE] == MODE_WHISPER)
if(fullcrit)
var/alertresult = alert(src, "You will be immediately killed by this action. Proceed?",,"Accept", "Decline")
if(alertresult == "Decline" || QDELETED(src))
return FALSE
message_range = 1
message_mode = MODE_WHISPER
message_mods[WHISPER_MODE] = MODE_WHISPER
src.log_talk(message, LOG_WHISPER)
if(fullcrit)
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
@@ -172,7 +159,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
message = copytext_char(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
message = Ellipsis(message, 10, 1)
last_words = message
message_mode = MODE_WHISPER_CRIT
message_mods[WHISPER_MODE] = MODE_WHISPER_CRIT
succumbed = TRUE
else
src.log_talk(message, LOG_SAY, forced_by=forced)
@@ -190,11 +177,26 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/datum/language/L = GLOB.language_datum_instances[language]
spans |= L.spans
var/radio_return = radio(message, message_mode, spans, language)
if(message_mods[MODE_SING])
var/randomnote = pick("\u2669", "\u266A", "\u266B")
message = "[randomnote] [message] [randomnote]"
spans |= SPAN_SINGING
//This is before anything that sends say a radio message, and after all important message type modifications, so you can scumb in alien chat or something
if(saymode && !saymode.handle_message(src, message, language))
return
var/radio_message = message
if(message_mods[WHISPER_MODE])
// radios don't pick up whispers very well
radio_message = stars(radio_message)
spans |= SPAN_ITALICS
var/radio_return = radio(radio_message, message_mods, spans, language)
if(radio_return & ITALICS)
spans |= SPAN_ITALICS
if(radio_return & REDUCE_RANGE)
message_range = 1
if(!message_mods[WHISPER_MODE])
message_mods[WHISPER_MODE] = MODE_WHISPER
if(radio_return & NOPASS)
return 1
@@ -208,15 +210,15 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
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, language, message_mode)
send_speech(message, message_range, src, bubble_type, spans, language, message_mods)
if(succumbed)
succumb(1)
to_chat(src, compose_message(src, language, message, , spans, message_mode))
to_chat(src, compose_message(src, language, message, , spans, message_mods))
return 1
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
/mob/living/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(!client)
return
@@ -231,20 +233,20 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
deaf_type = 2 // Since you should be able to hear yourself without looking
// Create map text prior to modifying message for goonchat
if (client?.prefs.chat_on_map && stat != UNCONSCIOUS && (client.prefs.see_chat_non_mob || ismob(speaker)) && can_hear())
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
create_chat_message(speaker, message_language, raw_message, spans)
// Recompose message for AI hrefs, language incomprehension.
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mods)
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, args)
show_message(message, 2, deaf_message, deaf_type)
return message
/mob/living/send_speech(message, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, message_mode)
/mob/living/send_speech(message, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, list/message_mods = list())
var/static/list/eavesdropping_modes = list(MODE_WHISPER = TRUE, MODE_WHISPER_CRIT = TRUE)
var/eavesdrop_range = 0
if(eavesdropping_modes[message_mode])
if(message_mods[WHISPER_MODE]) //If we're whispering
eavesdrop_range = EAVESDROP_EXTRA_RANGE
var/list/listening = get_hearers_in_view(message_range+eavesdrop_range, source)
var/list/the_dead = list()
@@ -257,7 +259,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(!M.client || !client) //client is so that ghosts don't have to listen to mice
continue
if(get_dist(M, src) > 7 || M.z != z) //they're out of range of normal hearing
if(eavesdropping_modes[message_mode] && !(M.client.prefs.chat_toggles & CHAT_GHOSTWHISPER)) //they're whispering and we have hearing whispers at any range off
if(eavesdrop_range && !(M.client.prefs.chat_toggles & CHAT_GHOSTWHISPER)) //they're whispering and we have hearing whispers at any range off
continue
if(!(M.client.prefs.chat_toggles & CHAT_GHOSTEARS)) //they're talking normally and we have hearing at any range off
continue
@@ -268,15 +270,15 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/eavesrendered
if(eavesdrop_range)
eavesdropping = stars(message)
eavesrendered = compose_message(src, message_language, eavesdropping, , spans, message_mode)
eavesrendered = compose_message(src, message_language, eavesdropping, , spans, message_mods)
var/rendered = compose_message(src, message_language, message, , spans, message_mode)
var/rendered = compose_message(src, message_language, message, , spans, message_mods)
for(var/_AM in listening)
var/atom/movable/AM = _AM
if(eavesdrop_range && get_dist(source, AM) > message_range && !(the_dead[AM]))
AM.Hear(eavesrendered, src, message_language, eavesdropping, , spans, message_mode)
AM.Hear(eavesrendered, src, message_language, eavesdropping, , spans, message_mods)
else
AM.Hear(rendered, src, message_language, message, , spans, message_mode)
AM.Hear(rendered, src, message_language, message, , spans, message_mods)
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIVING_SAY_SPECIAL, src, message)
//speech bubble
@@ -293,43 +295,29 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
/mob/living/can_speak(message) //For use outside of Say()
if(can_speak_basic(message) && can_speak_vocal(message))
return 1
return TRUE
/mob/living/proc/can_speak_basic(message, ignore_spam = FALSE) //Check BEFORE handling of xeno and ling channels
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "<span class='danger'>You cannot speak in IC (muted).</span>")
return 0
return FALSE
if(!ignore_spam && client.handle_spam_prevention(message,MUTE_IC))
return 0
return FALSE
return 1
return TRUE
/mob/living/proc/can_speak_vocal(message) //Check AFTER handling of xeno and ling channels
if(HAS_TRAIT(src, TRAIT_MUTE))
return 0
return FALSE
if(is_muzzled())
return 0
return FALSE
if(!IsVocal())
return 0
return FALSE
return 1
/mob/living/proc/get_key(message)
var/key = message[1]
if(key in GLOB.department_radio_prefixes)
return lowertext(message[1 + length(key)])
/mob/living/proc/get_message_language(message)
if(message[1] == ",")
var/key = message[1 + length(message[1])]
for(var/ld in GLOB.all_languages)
var/datum/language/LD = ld
if(initial(LD.key) == key)
return LD
return null
return TRUE
/mob/living/proc/treat_message(message)
if(HAS_TRAIT(src, TRAIT_UNINTELLIGIBLE_SPEECH))
@@ -351,33 +339,31 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return message
/mob/living/proc/radio(message, message_mode, list/spans, language)
/mob/living/proc/radio(message, list/message_mods = list(), list/spans, language)
var/obj/item/implant/radio/imp = locate() in src
if(imp && imp.radio.on)
if(message_mode == MODE_HEADSET)
imp.radio.talk_into(src, message, , spans, language)
if(message_mods[MODE_HEADSET])
imp.radio.talk_into(src, message, , spans, language, message_mods)
return ITALICS | REDUCE_RANGE
if(message_mode == MODE_DEPARTMENT || (message_mode in GLOB.radiochannels))
imp.radio.talk_into(src, message, message_mode, spans, language)
if(message_mods[RADIO_EXTENSION] == MODE_DEPARTMENT || (message_mods[RADIO_EXTENSION] in imp.radio.channels))
imp.radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return ITALICS | REDUCE_RANGE
switch(message_mode)
if(MODE_WHISPER)
return ITALICS
switch(message_mods[RADIO_EXTENSION])
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, language)
return r_hand.talk_into(src, message, , spans, language, message_mods)
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, language)
return l_hand.talk_into(src, message, , spans, language, message_mods)
return ITALICS | REDUCE_RANGE
if(MODE_INTERCOM)
for (var/obj/item/radio/intercom/I in view(1, null))
I.talk_into(src, message, , spans, language)
I.talk_into(src, message, , spans, language, message_mods)
return ITALICS | REDUCE_RANGE
if(MODE_BINARY)
@@ -385,11 +371,13 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 0
/mob/living/say_mod(input, message_mode)
if(message_mode == MODE_WHISPER)
/mob/living/say_mod(input, list/message_mods = list())
if(message_mods[WHISPER_MODE] == MODE_WHISPER)
. = verb_whisper
else if(message_mode == MODE_WHISPER_CRIT)
else if(message_mods[WHISPER_MODE] == MODE_WHISPER_CRIT)
. = "[verb_whisper] in [p_their()] last breath"
else if(message_mods[MODE_SING])
. = verb_sing
else if(stuttering)
. = "stammers"
else if(derpspeech)

View File

@@ -822,8 +822,8 @@
var/list/viewscale = getviewsize(client.view)
return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
var/treated_message = lang_treat(speaker, message_language, raw_message, spans, message_mode)
/mob/living/silicon/ai/proc/relay_speech(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
var/treated_message = lang_treat(speaker, message_language, raw_message, spans, message_mods)
var/start = "Relayed Speech: "
var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
var/hrefpart = "<a href='?src=[REF(src)];track=[html_encode(namepart)]'>"
@@ -841,7 +841,7 @@
var/rendered = "<i><span class='game say'>[start]<span class='name'>[hrefpart][namepart] ([jobpart])</a> </span><span class='message'>[treated_message]</span></span></i>"
if (client?.prefs.chat_on_map && (client.prefs.see_chat_non_mob || ismob(speaker)))
create_chat_message(speaker, message_language, raw_message, spans, message_mode)
create_chat_message(speaker, message_language, raw_message, spans)
show_message(rendered, 2)

View File

@@ -193,10 +193,10 @@
acceleration = !acceleration
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
/mob/camera/aiEye/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
/mob/camera/aiEye/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mods)
/obj/effect/overlay/ai_detect_hud
name = ""

View File

@@ -17,7 +17,7 @@
/mob/living/silicon/ai/IsVocal()
return !CONFIG_GET(flag/silent_ai)
/mob/living/silicon/ai/radio(message, message_mode, list/spans, language)
/mob/living/silicon/ai/radio(message, list/message_mods = list(), list/spans, language)
if(incapacitated())
return FALSE
if(!radio_enabled) //AI cannot speak if radio is disabled (via intellicard) or depowered.
@@ -25,13 +25,6 @@
return FALSE
..()
/mob/living/silicon/ai/get_message_mode(message)
var/static/regex/holopad_finder = regex(@"[:.#][hH]")
if(holopad_finder.Find(message, 1, 1))
return MODE_HOLOPAD
else
return ..()
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(message, language)
@@ -52,7 +45,7 @@
var/obj/effect/overlay/hologram = T.masters[src]
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
hologram.say("[message]")
send_speech(message, 7, T, "robot", message_language = language)
send_speech(message, 7, T, MODE_ROBOT, 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.")

View File

@@ -29,26 +29,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, language)
/mob/living/silicon/radio(message, list/message_mods = list(), list/spans, language)
. = ..()
if(. != 0)
return .
if(message_mode == "robot")
if (radio)
radio.talk_into(src, message, , spans, language)
if(message_mods[MODE_HEADSET])
if(radio)
radio.talk_into(src, message, , spans, language, message_mods)
return REDUCE_RANGE
else if(message_mode in GLOB.radiochannels)
else if(message_mods[RADIO_EXTENSION] in GLOB.radiochannels)
if(radio)
radio.talk_into(src, message, message_mode, spans, language)
radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return ITALICS | REDUCE_RANGE
return 0
/mob/living/silicon/get_message_mode(message)
. = ..()
if(..() == MODE_HEADSET)
return MODE_ROBOT
else
return .

View File

@@ -373,22 +373,19 @@
else
say(message)
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language)
/mob/living/simple_animal/bot/radio(message, list/message_mods = list(), list/spans, language)
. = ..()
if(. != 0)
return
switch(message_mode)
if(MODE_HEADSET)
Radio.talk_into(src, message, , spans, language)
return REDUCE_RANGE
if(MODE_DEPARTMENT)
Radio.talk_into(src, message, message_mode, spans, language)
return REDUCE_RANGE
if(message_mode in GLOB.radiochannels)
Radio.talk_into(src, message, message_mode, spans, language)
if(message_mods[MODE_HEADSET])
Radio.talk_into(src, message, , spans, language, message_mods)
return REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] == MODE_DEPARTMENT)
Radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] in GLOB.radiochannels)
Radio.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return REDUCE_RANGE
/mob/living/simple_animal/bot/proc/drop_part(obj/item/drop_item, dropzone)

View File

@@ -424,7 +424,7 @@ Difficulty: Very Hard
. += observer_desc
. += "It is activated by [activation_method]."
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, list/message_mods = list())
..()
if(isliving(speaker))
ActivationReaction(speaker, ACTIVATE_SPEECH)

View File

@@ -143,7 +143,7 @@
. += "Held Item: [held_item]"
. += "Mode: [a_intent]"
/mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
/mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, list/message_mods = list())
. = ..()
if(speaker != src && prob(50)) //Dont imitate ourselves
if(!radio_freq || prob(10))
@@ -153,29 +153,24 @@
if(speaker == src && !client) //If a parrot squawks in the woods and no one is around to hear it, does it make a sound? This code says yes!
return message
/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.
/mob/living/simple_animal/parrot/radio(message, list/message_mods = list(), 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 .
switch(message_mode)
if(MODE_HEADSET)
if (ears)
ears.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
if(MODE_DEPARTMENT)
if (ears)
ears.talk_into(src, message, message_mode, spans, language)
return ITALICS | REDUCE_RANGE
if(message_mode in GLOB.radiochannels)
if(message_mods[MODE_HEADSET])
if(ears)
ears.talk_into(src, message, message_mode, spans, language)
ears.talk_into(src, message, , spans, language, message_mods)
return ITALICS | REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] == MODE_DEPARTMENT)
if(ears)
ears.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return ITALICS | REDUCE_RANGE
else if(message_mods[RADIO_EXTENSION] in GLOB.radiochannels)
if(ears)
ears.talk_into(src, message, message_mods[RADIO_EXTENSION], spans, language, message_mods)
return ITALICS | REDUCE_RANGE
return 0
/*
* Inventory
*/

View File

@@ -276,7 +276,7 @@
if(icon_gib)
new /obj/effect/temp_visual/gib_animation/animal(loc, icon_gib)
/mob/living/simple_animal/say_mod(input, message_mode)
/mob/living/simple_animal/say_mod(input, list/message_mods = list())
if(speak_emote && speak_emote.len)
verb_say = pick(speak_emote)
. = ..()

View File

@@ -1,4 +1,4 @@
/mob/living/simple_animal/slime/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
/mob/living/simple_animal/slime/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, list/message_mods = list())
. = ..()
if(speaker != src && !radio_freq && !stat)
if (speaker in Friends)

View File

@@ -116,20 +116,50 @@
/mob/proc/lingcheck()
return LINGHIVE_NONE
///The amount of items we are looking for in the message
#define MESSAGE_MODS_LENGTH 6
/**
* Get the mode of a message
* Extracts and cleans message of any extenstions at the begining of the message
* Inserts the info into the passed list, returns the cleaned message
*
* Result can be
* * SAY_MODE (Things like aliens, channels that aren't channels)
* * MODE_WHISPER (Quiet speech)
* * MODE_SING (Singing)
* * MODE_HEADSET (Common radio channel)
* * A department radio (lots of values here)
* * RADIO_EXTENSION the extension we're using (lots of values here)
* * RADIO_KEY the radio key we're using, to make some things easier later (lots of values here)
* * LANGUAGE_EXTENSION the language we're trying to use (lots of values here)
*/
/mob/proc/get_message_mode(message)
var/key = message[1]
if(key == "#")
return MODE_WHISPER
else if(key == ";")
return MODE_HEADSET
else if((length(message) > (length(key) + 1)) && (key in GLOB.department_radio_prefixes))
var/key_symbol = lowertext(message[length(key) + 1])
return GLOB.department_radio_keys[key_symbol]
/mob/proc/get_message_mods(message, list/mods)
for(var/I in 1 to MESSAGE_MODS_LENGTH)
var/key = message[1]
var/chop_to = 2 //By default we just take off the first char
if(key == "#" && !mods[WHISPER_MODE])
mods[WHISPER_MODE] = MODE_WHISPER
else if(key == "%" && !mods[MODE_SING])
mods[MODE_SING] = TRUE
else if(key == ";" && !mods[MODE_HEADSET])
mods[MODE_HEADSET] = TRUE
else if((key in GLOB.department_radio_prefixes) && length(message) > length(key) + 1 && !mods[RADIO_EXTENSION])
mods[RADIO_KEY] = lowertext(message[1 + length(key)])
mods[RADIO_EXTENSION] = GLOB.department_radio_keys[mods[RADIO_KEY]]
chop_to = length(key) + 2
else if(key == "," && !mods[LANGUAGE_EXTENSION])
for(var/ld in GLOB.all_languages)
var/datum/language/LD = ld
if(initial(LD.key) == message[1 + length(message[1])])
// No, you cannot speak in xenocommon just because you know the key
if(!can_speak_language(LD))
return message
mods[LANGUAGE_EXTENSION] = LD
chop_to = length(key) + length(initial(LD.key)) + 1
if(!mods[LANGUAGE_EXTENSION])
return message
else
return message
message = trim_left(copytext_char(message, chop_to))
if(!message)
return
return message

View File

@@ -55,6 +55,7 @@ em {font-style: normal; font-weight: bold;}
.aiprivradio {color: #ff00ff;}
.redteamradio {color: #ff0000;}
.blueteamradio {color: #0000ff;}
.singing {font-family: "Trebuchet MS", cursive, sans-serif; font-style: italic;}
.yell { font-weight: bold;}

View File

@@ -486,6 +486,7 @@ sigh
sign
signal
sin
sing
sip
ski
skip