diff --git a/baystation12.dme b/baystation12.dme
index 12abeb3abb..c22d70873e 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1279,6 +1279,7 @@
#include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
+#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
#include "code\modules\mob\living\simple_animal\bees.dm"
#include "code\modules\mob\living\simple_animal\corpse.dm"
#include "code\modules\mob\living\simple_animal\parrot.dm"
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 53416cd2b3..43cb71acc6 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -201,6 +201,7 @@
transfer.control_disabled = 0
transfer.aiRadio.disabledAi = 0
transfer.loc = get_turf(src)
+ transfer.create_eyeobj()
transfer.cancel_camera()
user << "\blue Transfer successful: \black [transfer.name] ([rand(1000,9999)].exe) downloaded to host terminal. Local copy wiped."
transfer << "You have been uploaded to a stationary terminal. Remote device connection restored."
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index a483a378b7..8084d7a990 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -110,6 +110,7 @@
ai.loc = src
ai.cancel_camera()
+ ai.destroy_eyeobj(src)
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
carded_ai = ai
diff --git a/code/modules/mob/freelook/ai/eye.dm b/code/modules/mob/freelook/ai/eye.dm
index c0a42ace48..93fda30055 100644
--- a/code/modules/mob/freelook/ai/eye.dm
+++ b/code/modules/mob/freelook/ai/eye.dm
@@ -27,23 +27,37 @@
// The AI's "eye". Described on the top of the page.
/mob/living/silicon/ai
- eyeobj = new /mob/eye/aiEye()
var/obj/machinery/hologram/holopad/holo = null
+/mob/living/silicon/ai/proc/destroy_eyeobj(var/atom/new_eye)
+ if(!eyeobj) return
+ if(!new_eye)
+ new_eye = src
+ eyeobj.owner = null
+ qdel(eyeobj) // No AI, no Eye
+ eyeobj = null
+ if(client)
+ client.eye = new_eye
+
+/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
+ if(eyeobj) destroy_eyeobj()
+ if(!newloc) newloc = src.loc
+ eyeobj = PoolOrNew(/mob/eye/aiEye, newloc)
+ eyeobj.owner = src
+ eyeobj.name = "[src.name] (AI Eye)" // Give it a name
+ if(client) client.eye = eyeobj
+ SetName(src.name)
+
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
/mob/living/silicon/ai/New()
..()
- eyeobj.owner = src
- eyeobj.name = "[src.name] (AI Eye)" // Give it a name
+ create_eyeobj()
spawn(5)
if(eyeobj)
eyeobj.loc = src.loc
/mob/living/silicon/ai/Destroy()
- if(eyeobj)
- eyeobj.owner = null
- qdel(eyeobj) // No AI, no Eye
- eyeobj = null
+ destroy_eyeobj()
..()
/atom/proc/move_camera_by_click()
@@ -53,23 +67,18 @@
AI.eyeobj.setLoc(src)
// Return to the Core.
-
/mob/living/silicon/ai/proc/core()
set category = "AI Commands"
set name = "AI Core"
view_core()
-
/mob/living/silicon/ai/proc/view_core()
camera = null
unset_machine()
if(!src.eyeobj)
- src << "ERROR: Eyeobj not found. Creating new eye..."
- src.eyeobj = new(src.loc)
- src.eyeobj.owner = src
- src.SetName(src.name)
+ return
if(client && client.eye)
client.eye = src
diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm
index d93edf3ac2..17a145ae02 100644
--- a/code/modules/mob/language/generic.dm
+++ b/code/modules/mob/language/generic.dm
@@ -25,7 +25,7 @@
speech_verb = "says"
whisper_verb = "whispers"
key = "0"
- flags = RESTRICTED
+ flags = RESTRICTED | COMMON_VERBS
syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah")
//TODO flag certain languages to use the mob-type specific say_quote and then get rid of these.
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 8919ab0952..b1c64b9109 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -128,6 +128,7 @@ proc/get_radio_key_from_channel(var/channel)
return verb
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="")
+
if(client)
if(client.prefs.muted & MUTE_IC)
src << "\red You cannot speak in IC (Muted)."
@@ -165,7 +166,6 @@ proc/get_radio_key_from_channel(var/channel)
else
speaking = get_default_language()
- var/ending = copytext(message, length(message))
if (speaking)
// This is broadcast to all mobs with the language,
// irrespective of distance or anything else.
@@ -173,9 +173,12 @@ proc/get_radio_key_from_channel(var/channel)
speaking.broadcast(src,trim(message))
return
//If we've gotten this far, keep going!
- verb = speaking.get_spoken_verb(ending)
+ if(speaking.flags & COMMON_VERBS)
+ verb = say_quote(message)
+ else
+ verb = speaking.get_spoken_verb(copytext(message, length(message)))
else
- verb = get_speech_ending(verb, ending)
+ verb = say_quote(message)
message = trim_left(message)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 201d5ecdb9..d2f2fb3ddd 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -261,7 +261,7 @@
src << "You are a maintenance drone, a tiny-brained robotic repair machine."
src << "You have no individual will, no personality, and no drives or urges other than your laws."
src << "Remember, you are lawed against interference with the crew. Also remember, you DO NOT take orders from the AI."
- src << "Use :d to talk to other drones and say to speak silently to your nearby fellows."
+ src << "Use say ;Hello to talk to other drones and say Hello to speak silently to your nearby fellows."
/mob/living/silicon/robot/drone/start_pulling(var/atom/movable/AM)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
new file mode 100644
index 0000000000..71ca1c6918
--- /dev/null
+++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
@@ -0,0 +1,40 @@
+/mob/living/silicon/robot/drone/say(var/message)
+ if(local_transmit)
+ if (src.client)
+ if(client.prefs.muted & MUTE_IC)
+ src << "You cannot send IC messages (muted)."
+ return 0
+ if (src.client.handle_spam_prevention(message,MUTE_IC))
+ return 0
+
+ message = sanitize(message)
+
+ if (stat == 2)
+ return say_dead(message)
+
+ if(copytext(message,1,2) == "*")
+ return emote(copytext(message,2))
+
+ if(copytext(message,1,2) == ";")
+ var/datum/language/L = all_languages["Drone Talk"]
+ if(istype(L))
+ return L.broadcast(src,trim(copytext(message,2)))
+
+ //Must be concious to speak
+ if (stat)
+ return 0
+
+ var/list/listeners = hearers(5,src)
+ listeners |= src
+
+ for(var/mob/living/silicon/D in listeners)
+ if(D.client && D.local_transmit)
+ D << "[src] transmits, \"[message]\""
+
+ for (var/mob/M in player_list)
+ if (istype(M, /mob/new_player))
+ continue
+ else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
+ if(M.client) M << "[src] transmits, \"[message]\""
+ return 1
+ ..(message)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 1fefa272e5..25052354ed 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -1,3 +1,35 @@
+/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ log_say("[key_name(src)] : [message]")
+
+/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ ..()
+ if(message_mode)
+ if(!is_component_functioning("radio"))
+ src << "Your radio isn't functional at this time."
+ return 0
+ if(message_mode == "general")
+ message_mode = null
+ return radio.talk_into(src,message,message_mode,verb,speaking)
+
+/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ ..()
+ if(message_mode == "department")
+ return holopad_talk(message, verb, speaking)
+ else if(message_mode)
+ if (aiRadio.disabledAi || aiRestorePowerRoutine || stat)
+ src << "System Error - Transceiver Disabled."
+ return 0
+ if(message_mode == "general")
+ message_mode = null
+ return aiRadio.talk_into(src,message,message_mode,verb,speaking)
+
+/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name)
+ ..()
+ if(message_mode)
+ if(message_mode == "general")
+ message_mode = null
+ return radio.talk_into(src,message,message_mode,verb,speaking)
+
/mob/living/silicon/say_quote(var/text)
var/ending = copytext(text, length(text))
@@ -23,131 +55,6 @@
return 1
return ..()
-/mob/living/silicon/say(var/message)
- if (!message)
- return 0
-
- if (src.client)
- if(client.prefs.muted & MUTE_IC)
- src << "You cannot send IC messages (muted)."
- return 0
- if (src.client.handle_spam_prevention(message,MUTE_IC))
- return 0
-
- message = sanitize(message)
-
- if (stat == 2)
- return say_dead(message)
-
- if(copytext(message,1,2) == "*")
- return emote(copytext(message,2))
-
- 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 0
-
- var/verb = say_quote(message)
-
- //parse radio key and consume it
- var/message_mode = parse_message_mode(message, "general")
- if (message_mode)
- if (message_mode == "general")
- message = trim(copytext(message,2))
- else
- message = trim(copytext(message,3))
-
- //parse language key and consume it
- var/datum/language/speaking = parse_language(message)
- if (speaking)
- verb = speaking.speech_verb
- message = trim(copytext(message,2+length(speaking.key)))
-
- if(speaking.flags & HIVEMIND)
- speaking.broadcast(src,trim(message))
- return 1
-
- // Currently used by drones.
- if(local_transmit)
- var/list/listeners = hearers(5,src)
- listeners |= src
-
- for(var/mob/living/silicon/D in listeners)
- if(D.client && istype(D,src.type))
- D << "[src] transmits, \"[message]\""
-
- for (var/mob/M in player_list)
- if (istype(M, /mob/new_player))
- continue
- else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
- if(M.client) M << "[src] transmits, \"[message]\""
- return 1
-
- if(message_mode && bot_type == IS_ROBOT && !R.is_component_functioning("radio"))
- src << "\red Your radio isn't functional at this time."
- return 0
-
- switch(message_mode)
- if("department")
- switch(bot_type)
- if(IS_AI)
- return AI.holopad_talk(message, verb, speaking)
- if(IS_ROBOT)
- log_say("[key_name(src)] : [message]")
- return R.radio.talk_into(src,message,message_mode,verb,speaking)
- if(IS_PAI)
- log_say("[key_name(src)] : [message]")
- return P.radio.talk_into(src,message,message_mode,verb,speaking)
- return 0
-
- if("general")
- switch(bot_type)
- if(IS_AI)
- if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
- src << "\red System Error - Transceiver Disabled"
- return 0
- else
- log_say("[key_name(src)] : [message]")
- return AI.aiRadio.talk_into(src,message,null,verb,speaking)
- if(IS_ROBOT)
- log_say("[key_name(src)] : [message]")
- return R.radio.talk_into(src,message,null,verb,speaking)
- if(IS_PAI)
- log_say("[key_name(src)] : [message]")
- return P.radio.talk_into(src,message,null,verb,speaking)
- return 0
-
- else
- if(message_mode)
- switch(bot_type)
- if(IS_AI)
- if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
- src << "\red System Error - Transceiver Disabled"
- return 0
- else
- log_say("[key_name(src)] : [message]")
- return AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
- if(IS_ROBOT)
- log_say("[key_name(src)] : [message]")
- return R.radio.talk_into(src,message,message_mode,verb,speaking)
- if(IS_PAI)
- log_say("[key_name(src)] : [message]")
- return P.radio.talk_into(src,message,message_mode,verb,speaking)
- return 0
-
- return ..(message,speaking,verb)
-
//For holopads only. Usable by AI.
/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)
diff --git a/code/setup.dm b/code/setup.dm
index 78f3f8280a..d6649aa41c 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -662,8 +662,8 @@ var/list/be_special_flags = list(
#define NONGLOBAL 32 // Do not add to general languages list.
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
-#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
-
+#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
+#define COMMON_VERBS 512 // Robots will apply regular verbs to this.
//Flags for zone sleeping
#define ZONE_ACTIVE 1
#define ZONE_SLEEPING 0