diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 4cd216bd040..fa6e446b152 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -225,7 +225,6 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
var/message, var/name, var/job, var/realname, var/vname,
var/data, var/compression, var/list/level, var/freq, var/verbage = "says", var/datum/language/speaking = null)
- world << "in broadcast_message, verb = [verbage], language = [speaking ? speaking.name : null] ([src])"
/* ###### Prepare the radio connection ###### */
@@ -447,113 +446,41 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
blackbox.messages += blackbox_msg
//End of research and feedback code.
-
- var/aitrack = ""
- var/aiopen = ""
/* ###### Send the message ###### */
/* --- Process all the mobs that heard a masked voice (understood) --- */
if (length(heard_masked))
- var/N = name
- var/J = job
- world << "heard_masked"
- var/rendered = "[part_a][N][part_b][quotedmsg][part_c]"
for (var/mob/R in heard_masked)
- aitrack = ""
- aiopen = "\[OPEN\] "
- if(data == 4)
- aitrack = ""
-
- if(istype(R, /mob/living/silicon/ai))
- //R.show_message("[part_a][aitrack][N] ([J]) [part_b][quotedmsg][part_c]", 2)
- else
- //R.show_message(rendered, 2)
+ R.hear_radio(message,verbage, speaking, part_a, part_b, M)
/* --- Process all the mobs that heard the voice normally (understood) --- */
if (length(heard_normal))
- var/rendered = "[part_a][realname][part_b][quotedmsg][part_c]"
- world << "heard_normal"
for (var/mob/R in heard_normal)
- aitrack = ""
- aiopen = "\[OPEN\] "
- if(data == 4)
- aitrack = ""
-
- //if(istype(R, /mob/living/silicon/ai))
R.hear_radio(message, verbage, speaking, part_a, part_b, M)
- //R.show_message("[part_a][aitrack][realname] ([job]) [part_b][quotedmsg][part_c]", 2)
- //else
- //R.show_message(rendered, 2)
/* --- Process all the mobs that heard the voice normally (did not understand) --- */
if (length(heard_voice))
- var/rendered = "[part_a][vname][part_b][vmessage][part_c]"
-
for (var/mob/R in heard_voice)
- aitrack = ""
- aiopen = "\[OPEN\] "
- if(data == 4)
- aitrack = ""
-
R.hear_radio(message,verbage, speaking, part_a, part_b, M)
-/*
- if(istype(R, /mob/living/silicon/ai))
- R.show_message("[part_a][aitrack][vname] ([job]) [aiopen][part_b][vmessage]][part_c]", 2)
- else
- R.show_message(rendered, 2)
-*/
/* --- Process all the mobs that heard a garbled voice (did not understand) --- */
// Displays garbled message (ie "f*c* **u, **i*er!")
if (length(heard_garbled))
- if(M)
- quotedmsg = M.say_quote(stars(message))
- else
- quotedmsg = stars(quotedmsg)
-
- var/rendered = "[part_a][vname][part_b][quotedmsg][part_c]"
-
for (var/mob/R in heard_garbled)
- aitrack = ""
- aiopen = "\[OPEN\] "
- if(data == 4)
- aitrack = ""
-
-
- if(istype(R, /mob/living/silicon/ai))
- R.show_message("[part_a][aitrack][vname][aiopen][part_b][quotedmsg][part_c]", 2)
- else
- R.show_message(rendered, 2)
+ R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1)
/* --- Complete gibberish. Usually happens when there's a compressed message --- */
if (length(heard_gibberish))
- if(M)
- quotedmsg = M.say_quote(Gibberish(message, compression + 50))
- else
- quotedmsg = Gibberish(quotedmsg, compression + 50)
-
- var/rendered = "[part_a][Gibberish(name, compression + 50)][part_b][quotedmsg][part_c]"
-
for (var/mob/R in heard_gibberish)
- aitrack = ""
- aiopen = "\[OPEN\] "
- if(data == 4)
- aitrack = ""
-
-
- if(istype(R, /mob/living/silicon/ai))
- R.show_message("[part_a][aitrack][Gibberish(realname, compression + 50)] ([Gibberish(job, compression + 50)]) [aiopen][part_b][quotedmsg][part_c]", 2)
- else
- R.show_message(rendered, 2)
-
+ R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1)
/proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level)
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index af6438f89f8..2121b7cf334 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -220,10 +220,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
return
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
- if(speaking)
- world << "radio talk_into language = [speaking.name]"
- else
- world << "radio talk_into language = null"
if(!on) return // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
if(!M || !message) return
@@ -432,7 +428,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
//THIS IS TEMPORARY.
if(!connection) return //~Carn
- world << "WTF, WE'RE JUST DOING A STRAIGHT BROADCAST"
Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
src, message, displayname, jobname, real_name, M.voice_name,
filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
@@ -441,7 +436,6 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
else // OLD RADIO SYSTEMS: By Goons?
- world << "WTF we're in old system"
var/datum/radio_frequency/connection = null
if(channel && channels && channels.len > 0)
if (channel == "department")
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 21554782bab..db9bfdbdc88 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -76,6 +76,31 @@
real_name = name
..()
+
+/mob/dead/observer/Topic(href, href_list)
+ if (href_list["track"])
+ var/mob/target = locate(href_list["track"]) in mob_list
+ if(target)
+ ManualFollow(target)
+
+
+
+/mob/dead/attackby(obj/item/W, mob/user)
+ if(istype(W,/obj/item/weapon/tome))
+ var/mob/dead/M = src
+ if(src.invisibility != 0)
+ M.invisibility = 0
+ user.visible_message( \
+ "\red [user] drags ghost, [M], to our plan of reality!", \
+ "\red You drag [M] to our plan of reality!" \
+ )
+ else
+ user.visible_message ( \
+ "\red [user] just tried to smash his book into that ghost! It's not very effective", \
+ "\red You get the feeling that the ghost can't become any more visible." \
+ )
+
+
/mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
return 1
/*
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
index 6e98e06e16e..6268e3c14a8 100644
--- a/code/modules/mob/hear_say.dm
+++ b/code/modules/mob/hear_say.dm
@@ -23,6 +23,16 @@
var/mob/living/carbon/human/H = speaker
speaker_name = H.GetVoice()
+ if(italics)
+ message = "[message]"
+
+ var/track = null
+ if(istype(src, /mob/dead/observer))
+ if(speaker_name != speaker.real_name)
+ speaker_name = "[speaker.real_name] ([speaker_name])"
+ track = "(follow) "
+ if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
+ message = "[message]"
if(sdisabilities & DEAF || ear_deaf)
if(speaker == src)
@@ -30,15 +40,15 @@
else
src << "[speaker_name][alt_name] talks but you cannot hear them."
else
- src << "[speaker_name][alt_name] [verb], \"[message]\""
+ src << "[speaker_name][alt_name] [track][verb], \"[message]\""
-
-/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null)
+/mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0)
if(!client)
return
+ var/track = ""
+
var/style = "body"
- world << "in hear_radio and language = [language ? language.name : null]"
if(language)
world << "in language check"
if(!say_understands(speaker,language))
@@ -46,6 +56,9 @@
verb = language.speech_verb
style = language.colour
+ if(hard_to_hear)
+ message = stars(message)
+
if(verb == "says")
var/ending = copytext(message,length(message))
if(ending=="!")
@@ -56,10 +69,39 @@
var/speaker_name = speaker.name
if(istype(speaker, /mob/living/carbon/human))
var/mob/living/carbon/human/H = speaker
- speaker_name = H.GetVoice()
+ if(H.voice)
+ speaker_name = H.voice
+
+ if(hard_to_hear)
+ speaker_name = "unknown"
+
+ if(istype(src, /mob/living/silicon/ai) && !hard_to_hear)
+ var/jobname // the mob's "job"
+ if (ishuman(speaker))
+ var/mob/living/carbon/human/H = speaker
+ jobname = H.get_assignment()
+ else if (iscarbon(speaker)) // Nonhuman carbon mob
+ jobname = "No id"
+ else if (isAI(speaker))
+ jobname = "AI"
+ else if (isrobot(speaker))
+ jobname = "Cyborg"
+ else if (istype(speaker, /mob/living/silicon/pai))
+ jobname = "Personal AI"
+ else
+ jobname = "Unknown"
+
+ track = "[speaker_name] ([jobname])"
+
+ if(istype(src, /mob/dead/observer))
+ if(speaker_name != speaker.real_name)
+ speaker_name = "[speaker.real_name] ([speaker_name])"
+ track = "[speaker_name] (follow)"
if(sdisabilities & DEAF || ear_deaf)
if(prob(20))
src << "You feel your headset vibrate but can hear nothing from it!"
+ else if(track)
+ src << "[part_a][track][part_b] [verb], \"[message]\""
else
src << "[part_a][speaker_name][part_b] [verb], \"[message]\""
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 850ab155310..db45524ebb5 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -46,6 +46,8 @@
var/icon/stand_icon = null
var/icon/lying_icon = null
+ var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
+
var/speech_problem_flag = 0
var/miming = null //Toggle for the mime's abilities.
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 3963b054d62..ed14c08cf33 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -79,6 +79,8 @@
if(life_tick%30==15)
hud_updateflag = 1022
+ voice = GetVoice()
+
//No need to update all of these procs if the guy is dead.
if(stat != DEAD && !in_stasis)
if(air_master.current_cycle%4==2 || failed_last_breath) //First, resolve location and get a breath
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 68010312708..95833f0b0f6 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -118,7 +118,7 @@ var/list/department_radio_keys = list(
spawn(30) del(speech_bubble)
if(used_radios.len)
- for(var/mob/M in hearers(5, src))
+ for(var/mob/living/M in hearers(5, src))
if(M != src)
M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "radio"]")
@@ -136,5 +136,3 @@ var/list/department_radio_keys = list(
/mob/living/proc/GetVoice()
return name
-
-
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 24c827c46ad..d63078c05e6 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -433,9 +433,13 @@ var/list/ai_list = list()
if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list
+/*
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
if(A && target)
A.ai_actual_track(target)
+*/
+ if(target)
+ ai_actual_track(target)
return
else if (href_list["faketrack"])
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index a7ad5045bae..34b3e54f906 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -2,11 +2,15 @@
var/ending = copytext(text, length(text))
if (ending == "?")
- return "queries, \"[text]\"";
+ return "queries"
else if (ending == "!")
- return "declares, \"[text]\"";
+ return "declares"
- return "states, \"[text]\"";
+ return "states"
+
+#define IS_AI 1
+#define IS_ROBOT 2
+#define IS_PAI 3
/mob/living/silicon/say(var/message)
if (!message)
@@ -23,45 +27,97 @@
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
return say_dead(message)
+ var/bot_type = 0 //Let's not do a fuck ton of type checks, thanks.
+ if(istype(src, /mob/living/silicon/ai))
+ bot_type = IS_AI
+ else if(istype(src, /mob/living/silicon/robot))
+ bot_type = IS_ROBOT
+ else if(istype(src, /mob/living/silicon/pai))
+ bot_type = IS_PAI
+
+ var/mob/living/silicon/ai/AI = src //and let's not declare vars over and over and over for these guys.
+ var/mob/living/silicon/robot/R = src
+ var/mob/living/silicon/pai/P = src
+
+
//Must be concious to speak
if (stat)
return
- if (length(message) >= 2)
- var/prefix = copytext(message, 1, 3)
- if (department_radio_keys[prefix] == "binary")
- if(istype(src, /mob/living/silicon/pai))
- return ..(message)
- message = copytext(message, 3)
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
+ var/verb = say_quote(message)
+ var/message_mode = null
- // TODO: move the component system up to silicon so we don't have to use this ugly hack..
- if(istype(src, /mob/living/silicon/robot))
- var/mob/living/silicon/robot/R = src
- if(!R.is_component_functioning("comms"))
- src << "\red Your binary communications component isn't functional."
+
+ if(copytext(message,1,2) == ";")
+ message_mode = "general" // I don't know why but regular radio = fuck you we ain't broadcasting, pAI mode was what was in old say code.
+ message = trim(copytext(message,2))
+
+ else if(length(message) >= 2)
+ var/channel_prefix = copytext(message, 1 ,3)
+ if(!message_mode)
+ message_mode = department_radio_keys[channel_prefix]
+
+ if(message_mode && bot_type == IS_ROBOT)
+ if(message_mode != "binary" && !R.is_component_functioning("radio"))
+ src << "\red Your radio isn't functional at this time."
+ return
+
+
+ if(message_mode && message_mode != "general")
+ message = trim(copytext(message,3))
+
+ switch(message_mode)
+ if("department")
+ switch(bot_type)
+ if(IS_AI)
+ AI.holopad_talk(message)
+ if(IS_ROBOT)
+ log_say("[key_name(src)] : [message]")
+ R.radio.talk_into(src,message,message_mode,verb)
+ if(IS_PAI)
+ log_say("[key_name(src)] : [message]")
+ P.radio.talk_into(src,message,message_mode,verb)
+ return
+
+ if("binary")
+ switch(bot_type)
+ if(IS_ROBOT)
+ if(!R.is_component_functioning("comms"))
+ src << "\red Your binary communications component isn't functional."
+ return
+ if(IS_PAI)
+ src << "You do not appear to have that function"
return
robot_talk(message)
+ return
+ if("general")
+ switch(bot_type)
+ if(IS_AI)
+ src << "Yeah, not yet, sorry"
+ if(IS_ROBOT)
+ log_say("[key_name(src)] : [message]")
+ R.radio.talk_into(src,message,null,verb)
+ if(IS_PAI)
+ log_say("[key_name(src)] : [message]")
+ P.radio.talk_into(src,message,null,verb)
+ return
- else if (department_radio_keys[prefix] == "alientalk")
- if(!alien_talk_understand) return
- message = copytext(message, 3)
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
-
- alien_talk(message)
- else if (department_radio_keys[prefix] == "department")
- if(isAI(src)&&client)//For patching directly into AI holopads.
- var/mob/living/silicon/ai/U = src
- message = copytext(message, 3)
- message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
- U.holopad_talk(message)
- else//Will not allow anyone by an active AI to use this function.
- src << "This function is not available to you."
- return
else
- return ..(message)
- else
- return ..(message)
+ if(message_mode && message_mode in radiochannels)
+ switch(bot_type)
+ if(IS_AI)
+ src << "You don't have this function yet, I'm working on it"
+ return
+ if(IS_ROBOT)
+ log_say("[key_name(src)] : [message]")
+ R.radio.talk_into(src,message,message_mode,verb)
+ if(IS_PAI)
+ log_say("[key_name(src)] : [message]")
+ P.radio.talk_into(src,message,message_mode,verb)
+ return
+
+
+ return ..(message,null,verb)
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(var/message)
@@ -160,4 +216,8 @@
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain)) //No meta-evesdropping
rendered = "Robotic Talk, [name] (Follow) [message_a]"
- M.show_message(rendered, 2)
\ No newline at end of file
+ M.show_message(rendered, 2)
+
+#undef IS_AI
+#undef IS_ROBOT
+#undef IS_PAI