diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index fb5b7735633..b4ae61f3e82 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -37,3 +37,12 @@ return . = src.emote_dead(message) + +/mob/dead/observer/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear) + return "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])" + +/mob/dead/observer/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear) + var/speaker_name = ..() + if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs. + speaker_name = "[speaker.real_name] ([speaker_name])" + return speaker_name \ No newline at end of file diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index f158534475e..568033f3606 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -117,65 +117,8 @@ if(hard_to_hear) message = stars(message) - var/speaker_name = "unknown" - if(speaker) - speaker_name = speaker.name - - if(vname) - speaker_name = vname - if(hard_to_hear) - speaker_name = "unknown" - - var/changed_voice - - if(isAI(src) && !hard_to_hear) - var/jobname // the mob's "job" - var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any. - - if(ishuman(speaker)) - var/mob/living/carbon/human/H = speaker - - var/obj/item/weapon/card/id/id = H.wear_id - if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger()) - changed_voice = 1 - var/mob/living/carbon/human/I = locate(speaker_name) - if(I) - impersonating = I - jobname = impersonating.get_assignment() - else - jobname = "Unknown" - else - 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(ispAI(speaker)) - jobname = "Personal AI" - else if(isAutoAnnouncer(speaker)) - var/mob/living/automatedannouncer/AA = speaker - jobname = AA.role - else - jobname = "Unknown" - - if(changed_voice) - if(impersonating) - track = "[speaker_name] ([jobname])" - else - track = "[speaker_name] ([jobname])" - else - if(istype(follow_target, /mob/living/simple_animal/bot)) - track = "[speaker_name] ([jobname])" - else - track = "[speaker_name] ([jobname])" - - if(isobserver(src)) - if(speaker && (speaker_name != speaker.real_name) && !isAI(speaker)) //Announce computer and various stuff that broadcasts doesn't use it's real name but AI's can't pretend to be other mobs. - speaker_name = "[speaker.real_name] ([speaker_name])" - track = "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])" + var/speaker_name = handle_speaker_name(speaker, vname, hard_to_hear) + track = handle_track(message, verb, language, speaker, speaker_name, follow_target, hard_to_hear) var/formatted if(language) @@ -190,6 +133,22 @@ else to_chat(src, "[part_a][speaker_name][part_b][formatted]") +/mob/proc/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear) + var/speaker_name = "unknown" + if(speaker) + speaker_name = speaker.name + + if(vname) + speaker_name = vname + + if(hard_to_hear) + speaker_name = "unknown" + + return speaker_name + +/mob/proc/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear) + return + /mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) if(!client) return diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3235c6899c1..33e74cb6266 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -618,9 +618,10 @@ var/list/ai_verbs_default = list( sleep(40) continue - return - - return + else if(href_list["open"]) + var/mob/target = locate(href_list["open"]) in mob_list + if(target) + open_nearest_door(target) /mob/living/silicon/ai/bullet_act(var/obj/item/projectile/Proj) ..(Proj) @@ -1092,52 +1093,6 @@ var/list/ai_verbs_default = list( aiRadio.interact(src) -/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target) - if(!istype(target)) - return - spawn(0) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - var/obj/item/weapon/card/id/id = H.wear_id - if(istype(id) && id.is_untrackable()) - to_chat(src, "Unable to locate an airlock") - return - if(H.digitalcamo) - to_chat(src, "Unable to locate an airlock") - return - if(!near_camera(target)) - to_chat(src, "Target is not near any active cameras.") - return - var/obj/machinery/door/airlock/tobeopened - var/dist = -1 - for(var/obj/machinery/door/airlock/D in range(3,target)) - if(!D.density) - continue - if(dist < 0) - dist = get_dist(D, target) -// to_chat(world, dist) - tobeopened = D - else - if(dist > get_dist(D, target)) - dist = get_dist(D, target) -// to_chat(world, dist) - tobeopened = D -// to_chat(world, "found [tobeopened.name] closer") - else -// to_chat(world, "[D.name] not close enough | [get_dist(D, target)] | [dist]") - if(tobeopened) - switch(alert(src, "Do you want to open \the [tobeopened] for [target]?","Doorknob_v2a.exe","Yes","No")) - if("Yes") - var/nhref = "src=[tobeopened.UID()];aiEnable=7" - tobeopened.Topic(nhref, params2list(nhref), tobeopened, 1) - to_chat(src, "\blue You've opened \the [tobeopened] for [target].") - if("No") - to_chat(src, "\red You deny the request.") - else - to_chat(src, "\red You've failed to open an airlock for [target]") - return - - /mob/living/silicon/ai/proc/check_unable(flags = 0) if(stat == DEAD) to_chat(usr, "You are dead!") @@ -1234,3 +1189,37 @@ var/list/ai_verbs_default = list( view_core() //A BYOND bug requires you to be viewing your core before your verbs update verbs += /mob/living/silicon/ai/proc/choose_modules malf_picker = new /datum/module_picker + +/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target) + if(!istype(target)) + return + + if(target && target.can_track()) + var/obj/machinery/door/airlock/A = null + + var/dist = -1 + for(var/obj/machinery/door/airlock/D in range(3, target)) + if(!D.density) + continue + + var/curr_dist = get_dist(D, target) + + if(dist < 0) + dist = curr_dist + A = D + else if(dist > curr_dist) + dist = curr_dist + A = D + + if(istype(A)) + switch(alert(src, "Do you want to open \the [A] for [target]?", "Doorknob_v2a.exe", "Yes", "No")) + if("Yes") + A.AIShiftClick() + to_chat(src, "You open \the [A] for [target].") + else + to_chat(src, "You deny the request.") + else + to_chat(src, "Unable to locate an airlock near [target].") + + else + to_chat(src, "Target is not on or near any active cameras on the station.") \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 2a3b39c1c9b..ccd0f652b68 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -1,3 +1,70 @@ +/* + * AI Saycode + */ + + +/mob/living/silicon/ai/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear) + if(hard_to_hear) + return + + var/jobname // the mob's "job" + var/mob/living/carbon/human/impersonating //The crewmember being impersonated, if any. + var/changed_voice + + if(ishuman(speaker)) + var/mob/living/carbon/human/H = speaker + + var/obj/item/weapon/card/id/id = H.wear_id + if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger()) + changed_voice = 1 + var/mob/living/carbon/human/I = locate(speaker_name) + if(I) + impersonating = I + jobname = impersonating.get_assignment() + else + jobname = "Unknown" + else + 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(ispAI(speaker)) + jobname = "Personal AI" + else if(isAutoAnnouncer(speaker)) + var/mob/living/automatedannouncer/AA = speaker + jobname = AA.role + else + jobname = "Unknown" + + var/track = "" + var/mob/mob_to_track = null + if(changed_voice) + if(impersonating) + mob_to_track = impersonating + else + track = "[speaker_name] ([jobname])" + else + if(istype(follow_target, /mob/living/simple_animal/bot)) + track = "[speaker_name] ([jobname])" + else + mob_to_track = speaker + + if(mob_to_track) + track = "[speaker_name] ([jobname])" + track += "\[OPEN\]" + + return track + + + +/* + * AI VOX Announcements + */ + var/announcing_vox = 0 // Stores the time of the last announcement var/const/VOX_CHANNEL = 200 var/const/VOX_DELAY = 100