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