Merge pull request #1151 from Krausus/FollowThatEye

Adds ghost-following and admin-jumping for AI eyes and ghosts' bodies
This commit is contained in:
ZomgPonies
2015-05-24 10:19:12 -04:00
13 changed files with 78 additions and 41 deletions
+7 -2
View File
@@ -56,7 +56,7 @@ var/global/nologevent = 0
<a href='?src=\ref[src];traitor=\ref[M]'>TP</a> -
<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a> -
<a href='?src=\ref[src];subtlemessage=\ref[M]'>SM</a> -
<a href='?src=\ref[src];adminplayerobservejump=\ref[M]'>JMP</a>\] </b><br>
[admin_jump_link(M, src)]\] </b><br>
<b>Mob type</b> = [M.type]<br><br>
<A href='?src=\ref[src];boot2=\ref[M]'>Kick</A> |
<A href='?_src_=holder;warn=[M.ckey]'>Warn</A> |
@@ -79,8 +79,13 @@ var/global/nologevent = 0
(<A href='?src=\ref[src];mute=\ref[M];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"blue"]'>toggle all</font></a>)
"}
var/jumptoeye = ""
if(isAI(M))
var/mob/living/silicon/ai/A = M
if(A.client && A.eyeobj) // No point following clientless AI eyes
jumptoeye = " <b>(<A href='?src=\ref[src];jumpto=\ref[A.eyeobj]'>Eye</A>)</b>"
body += {"<br><br>
<A href='?src=\ref[src];jumpto=\ref[M]'><b>Jump to</b></A> |
<A href='?src=\ref[src];jumpto=\ref[M]'><b>Jump to</b></A>[jumptoeye] |
<A href='?src=\ref[src];getmob=\ref[M]'>Get</A> |
<A href='?src=\ref[src];sendmob=\ref[M]'>Send To</A>
<br><br>
+11 -3
View File
@@ -61,7 +61,7 @@
}
function expand(id,job,name,real_name,image,key,ip,antagonist,ref){
function expand(id,job,name,real_name,image,key,ip,antagonist,ref,eyeref){
clearAll();
@@ -81,7 +81,10 @@
body += "<a href='?src=\ref[src];traitor="+ref+"'>TP</a> - "
body += "<a href='?src=\ref[usr];priv_msg=\ref"+ref+"'>PM</a> - "
body += "<a href='?src=\ref[src];subtlemessage="+ref+"'>SM</a> - "
body += "<a href='?src=\ref[src];adminplayerobservejump="+ref+"'>JMP</a><br>"
body += "<a href='?src=\ref[src];adminplayerobservejump="+ref+"'>JMP</a>"
if(eyeref)
body += "|<a href='?src=\ref[src];adminplayerobservejump="+eyeref+"'>EYE</a>"
body += "<br>"
if(antagonist > 0)
body += "<font size='2'><a href='?src=\ref[src];check_antagonist=1'><font color='red'><b>Antagonist</b></font></a></font>";
@@ -287,6 +290,11 @@
M_key = replacetext(M_key, "\"", "")
M_key = replacetext(M_key, "\\", "")
var/M_eyeref = ""
if(isAI(M))
var/mob/living/silicon/ai/A = M
if(A.client && A.eyeobj) // No point following clientless AI eyes
M_eyeref = "\ref[A.eyeobj]"
//output for each mob
dat += {"
@@ -294,7 +302,7 @@
<td align='center' bgcolor='[color]'>
<span id='notice_span[i]'></span>
<a id='link[i]'
onmouseover='expand("item[i]","[M_job]","[M_name]","[M_rname]","--unused--","[M_key]","[M.lastKnownIP]",[is_antagonist],"\ref[M]")'
onmouseover='expand("item[i]","[M_job]","[M_name]","[M_rname]","--unused--","[M_key]","[M.lastKnownIP]",[is_antagonist],"\ref[M]", "[M_eyeref]")'
>
<b id='search[i]'>[M_name] - [M_rname] - [M_key] ([M_job])</b>
</a>
+24 -1
View File
@@ -1558,7 +1558,7 @@
src.owner << "Name = <b>[M.name]</b>; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = <b>[M.key]</b>;"
src.owner << "Location = [location_description];"
src.owner << "[special_role_description]"
src.owner << "(<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>) (<A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[M]'>VV</A>) (<A HREF='?src=\ref[src];subtlemessage=\ref[M]'>SM</A>) (<A HREF='?src=\ref[src];adminplayerobservejump=\ref[M]'>JMP</A>) (<A HREF='?src=\ref[src];secretsadmin=check_antagonist'>CA</A>)"
src.owner << "(<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>) (<A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[M]'>VV</A>) (<A HREF='?src=\ref[src];subtlemessage=\ref[M]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?src=\ref[src];secretsadmin=check_antagonist'>CA</A>)"
else if(href_list["adminspawncookie"])
if(!check_rights(R_ADMIN|R_EVENT)) return
@@ -2990,3 +2990,26 @@
current_tab = text2num(href_list["tab"])
Secrets(usr)
return 1
/proc/admin_jump_link(var/atom/target, var/source)
if(!target) return
// The way admin jump links handle their src is weirdly inconsistent...
if(istype(source, /datum/admins))
source = "src=\ref[source]"
else
source = "_src_=holder"
if(isAI(target)) // AI core/eye follow links
var/mob/living/silicon/ai/A = target
. = "<A HREF='?[source];adminplayerobservejump=\ref[target]'>JMP</A>"
if(A.client && A.eyeobj) // No point following clientless AI eyes
. += "|<A HREF='?[source];adminplayerobservejump=\ref[A.eyeobj]'>EYE</A>"
return
else if(istype(target, /mob/dead/observer))
var/mob/dead/observer/O = target
. = "<A HREF='?[source];adminplayerobservejump=\ref[target]'>JMP</A>"
if(O.mind && O.mind.current)
. += "|<A HREF='?[source];adminplayerobservejump=\ref[O.mind.current]'>BDY</A>"
return
else
return "<A HREF='?[source];adminplayerobservejump=\ref[target]'>JMP</A>"
+1 -1
View File
@@ -94,7 +94,7 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
if(!mob) return //this doesn't happen
var/ref_mob = "\ref[mob]"
msg = "\blue <b><font color=red>[selected_type]: </font>[key_name(src, 1, 1, selected_type)] (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=[ref_mob]'>JMP</A>) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""]:</b> [msg]"
msg = "\blue <b><font color=red>[selected_type]: </font>[key_name(src, 1, 1, selected_type)] (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(mob, "holder")]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>) [ai_found ? " (<A HREF='?_src_=holder;adminchecklaws=[ref_mob]'>CL</A>)" : ""]:</b> [msg]"
//send this msg to all admins
var/admin_number_afk = 0
+2 -2
View File
@@ -12,7 +12,7 @@
if(check_rights(R_ADMIN,0))
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << "<span class='admin_channel'>ADMIN: <span class='name'>[key_name(usr, 1)]</span> (<a href='?_src_=holder;adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
C << "<span class='admin_channel'>ADMIN: <span class='name'>[key_name(usr, 1)]</span> ([admin_jump_link(mob, "holder")]): <span class='message'>[msg]</span></span>"
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -34,6 +34,6 @@
spanclass = "mod_channel_admin"
for(var/client/C in admins)
if(R_MOD & C.holder.rights)
C << "<span class='[spanclass]'>MOD: <span class='name'>[key_name(usr, 1)]</span> (<A HREF='?src=\ref[C.holder];adminplayerobservejump=\ref[mob]'>JMP</A>): <span class='message'>[msg]</span></span>"
C << "<span class='[spanclass]'>MOD: <span class='name'>[key_name(usr, 1)]</span> ([admin_jump_link(mob, C.holder)]): <span class='message'>[msg]</span></span>"
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+4 -4
View File
@@ -13,7 +13,7 @@
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
msg = "\blue \icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[src]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]"
msg = "\blue \icon[cross] <b><font color=purple>PRAY: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src, "holder")]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
@@ -26,7 +26,7 @@
/proc/Centcomm_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "\blue <b><font color=orange>CENTCOMM:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
msg = "\blue <b><font color=orange>CENTCOMM:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, "holder")]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
@@ -34,7 +34,7 @@
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "\blue <b><font color='#DC143C'>SYNDICATE:</font> [key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>REPLY</A>):</b> [msg]"
msg = "\blue <b><font color='#DC143C'>SYNDICATE:</font> [key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, "holder")]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>REPLY</A>):</b> [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
@@ -42,7 +42,7 @@
/proc/HONK_announce(var/text , var/mob/Sender)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "\blue <b><font color=pink>HONK:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;HONKReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
msg = "\blue <b><font color=pink>HONK:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) ([admin_jump_link(Sender, "holder")]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;HONKReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
for(var/client/X in admins)
if(R_EVENT & X.holder.rights)
+19 -20
View File
@@ -499,6 +499,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return ..()
/proc/ghost_follow_link(var/atom/target, var/atom/ghost)
if((!target) || (!ghost)) return
if(isAI(target)) // AI core/eye follow links
var/mob/living/silicon/ai/A = target
. = "<a href='byond://?src=\ref[ghost];follow=\ref[A]'>core</a>"
if(A.client && A.eyeobj) // No point following clientless AI eyes
. += "|<a href='byond://?src=\ref[ghost];follow=\ref[A.eyeobj]'>eye</a>"
return
else if(istype(target, /mob/dead/observer))
var/mob/dead/observer/O = target
. = "<a href='byond://?src=\ref[ghost];follow=\ref[target]'>follow</a>"
if(O.mind && O.mind.current)
. += "|<a href='byond://?src=\ref[ghost];follow=\ref[O.mind.current]'>body</a>"
return
else
return "<a href='byond://?src=\ref[ghost];follow=\ref[target]'>follow</a>"
//BEGIN TELEPORT HREF CODE
/mob/dead/observer/Topic(href, href_list)
if(usr != src)
@@ -512,26 +529,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if (href_list["follow"])
var/atom/target = locate(href_list["follow"])
var/mob/A = usr;
A << "You are now following [target]"
//var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
if(target && target != usr)
following = target
spawn(0)
var/turf/pos = get_turf(A)
while(A.loc == pos)
var/turf/T = get_turf(target)
if(!T)
break
if(following != target)
break
if(!client)
break
A.loc = T
pos = A.loc
sleep(15)
following = null
if(target)
ManualFollow(target)
if (href_list["jump"])
var/mob/target = locate(href_list["jump"])
+2 -2
View File
@@ -55,7 +55,7 @@
return
if(speaker_name != speaker.real_name && speaker.real_name)
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "(<a href='byond://?src=\ref[src];track=\ref[speaker]'>follow</a>) "
track = "([ghost_follow_link(speaker, ghost=src)]) "
if(client.prefs.toggles & CHAT_GHOSTEARS && speaker in view(src))
message = "<b>[message]</b>"
@@ -170,7 +170,7 @@
if(istype(src, /mob/dead/observer))
if(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] (<a href='byond://?src=\ref[src];track=\ref[follow_target]'>follow</a>)"
track = "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
var/formatted
if(language)
+2 -2
View File
@@ -104,7 +104,7 @@
for(var/mob/player in player_list)
if(istype(player,/mob/dead) && follow)
var/msg_dead = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> (<a href='byond://?src=\ref[player];follow2=\ref[player];follow=\ref[speaker]'>follow</a>) [format_message(message, get_spoken_verb(message))]</span></i>"
var/msg_dead = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> ([ghost_follow_link(speaker, ghost=player)]) [format_message(message, get_spoken_verb(message))]</span></i>"
player << msg_dead
continue
@@ -446,7 +446,7 @@
for (var/mob/M in dead_mob_list)
if(!istype(M,/mob/new_player) && !istype(M,/mob/living/carbon/brain))
var/message_start_dead = "<i><span class='game say'>[name], <span class='name'>[speaker.name] (<a href='byond://?src=\ref[M];follow2=\ref[M];follow=\ref[speaker]'>follow</a>)</span>"
var/message_start_dead = "<i><span class='game say'>[name], <span class='name'>[speaker.name] ([ghost_follow_link(speaker, ghost=M)])</span>"
M.show_message("[message_start_dead] [message_body]", 2)
for (var/mob/living/S in living_mob_list)
+2 -2
View File
@@ -473,9 +473,9 @@ var/list/intents = list("help","disarm","grab","harm")
var/lname
if(subject)
if(subject != M)
follow = "(<a href='byond://?src=\ref[M];track=\ref[subject]'>follow</a>) "
follow = "([ghost_follow_link(subject, ghost=M)]) "
if(M.stat != DEAD && M.client.holder)
follow = "(<a href='?src=\ref[M.client.holder];adminplayerobservejump=\ref[subject]'>JMP</a>) "
follow = "([admin_jump_link(subject, M.client.holder)]) "
var/mob/dead/observer/DM
if(istype(subject, /mob/dead/observer))
DM = subject
+1 -1
View File
@@ -260,7 +260,7 @@ var/list/alldepartments = list()
/obj/machinery/photocopier/faxmachine/proc/message_admins(var/mob/sender, var/faxname, var/faxtype, var/obj/item/sent, font_colour="#006100")
var/msg = "\blue <b><font color='[font_colour]'>[faxname]: </font>[key_name(sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[sender]'>BSA</A>) (<a href='?_src_=holder;AdminFaxCreate=\ref[sender];originfax=\ref[src];faxtype=[faxtype];replyto=\ref[sent]'>REPLY</a>)</b>: Receiving '[sent.name]' via secure connection... <a href='?_src_=holder;AdminFaxView=\ref[sent]'>view message</a>"
var/msg = "\blue <b><font color='[font_colour]'>[faxname]: </font>[key_name(sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[sender]'>SM</A>) ([admin_jump_link(sender, "holder")]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[sender]'>BSA</A>) (<a href='?_src_=holder;AdminFaxCreate=\ref[sender];originfax=\ref[src];faxtype=[faxtype];replyto=\ref[sent]'>REPLY</a>)</b>: Receiving '[sent.name]' via secure connection... <a href='?_src_=holder;AdminFaxView=\ref[sent]'>view message</a>"
for(var/client/C in admins)
if(R_EVENT & C.holder.rights)