From b2868c31e0f94dd7950b150caa698d46b5166955 Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Fri, 17 Feb 2017 17:43:33 -0800 Subject: [PATCH] Add [OPEN] option for AI in radio messages Also mildly refactors hear_radio to kill those nasty istype(src)'s. This makes an [OPEN] link appear on all radio messages the AI hears (to the right of the follow link). When clicked, it allows the AI to open the door nearest to the speaker (or, if it is a voice changer, the door nearest to the poor sap who had his voice stolen) --- code/modules/mob/dead/observer/say.dm | 9 +++ code/modules/mob/hear_say.dm | 77 +++++--------------- code/modules/mob/living/silicon/ai/ai.dm | 87 ++++++++++------------- code/modules/mob/living/silicon/ai/say.dm | 67 +++++++++++++++++ 4 files changed, 132 insertions(+), 108 deletions(-) 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