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)
This commit is contained in:
Tigercat2000
2017-02-17 17:43:33 -08:00
parent e0b23a1e10
commit b2868c31e0
4 changed files with 132 additions and 108 deletions
+9
View File
@@ -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
+18 -59
View File
@@ -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 = "<a href='byond://?src=[UID()];track=\ref[impersonating]'>[speaker_name] ([jobname])</a>"
else
track = "[speaker_name] ([jobname])"
else
if(istype(follow_target, /mob/living/simple_animal/bot))
track = "<a href='byond://?src=[UID()];trackbot=\ref[follow_target]'>[speaker_name] ([jobname])</a>"
else
track = "<a href='byond://?src=[UID()];track=\ref[speaker]'>[speaker_name] ([jobname])</a>"
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]</span></span>")
/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
+38 -49
View File
@@ -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, "<span class='warning'>You are dead!</span>")
@@ -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, "<span class='notice'>You open \the [A] for [target].</span>")
else
to_chat(src, "<span class='warning'>You deny the request.</span>")
else
to_chat(src, "<span class='warning'>Unable to locate an airlock near [target].</span>")
else
to_chat(src, "<span class='warning'>Target is not on or near any active cameras on the station.</span>")
+67
View File
@@ -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 = "<a href='byond://?src=[UID()];trackbot=\ref[follow_target]'>[speaker_name] ([jobname])</a>"
else
mob_to_track = speaker
if(mob_to_track)
track = "<a href='byond://?src=[UID()];track=\ref[mob_to_track]'>[speaker_name] ([jobname])</a>"
track += "<a href='byond://?src=[UID()];open=\ref[mob_to_track]'>\[OPEN\]</a>"
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