Ports Goonchat from Baystation. (#9635)

changes:

    rscadd: "Ported a new chat system, Goonchat, that allows for cool things like changing font style, size, spacing, highlighting up to 5 strings in the chat, and DARK MODE."
    rscadd: "Repeated chat messages can now get compacted. You can disable this in goonchat settings."
    rscadd: "You can change icon style to any font on your system."
    tweak: "The game window has been altered a bit to adjust for this."
    rscdel: "Removed skin style prefs as they are no longer used."
This commit is contained in:
Matt Atlas
2020-09-24 22:06:04 +02:00
committed by GitHub
parent a7401aeb1d
commit d4666caaac
277 changed files with 4057 additions and 2955 deletions
+6 -6
View File
@@ -1157,7 +1157,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS)) // src.client is so that ghosts don't have to listen to rats
if(istype(M, /mob/abstract/new_player))
continue
M.show_message("<span class='game say'>PDA Message - <span class='name'>[owner]</span> -> <span class='name'>[P.owner]</span>: <span class='message'>[t]</span></span>")
M.show_message("<span class='game say'>PDA Message - <span class='name'>[owner]</span> -> <span class='name'>[P.owner]</span>: <span class='message linkify'>[t]</span></span>")
if(!conversations.Find("\ref[P]"))
conversations.Add("\ref[P]")
@@ -1173,7 +1173,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if (!beep_silent)
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src] *[message_tone]*"))
O.show_message(text("[icon2html(src, O)] *[message_tone]*"))
//Search for holder of the PDA.
var/mob/living/L = null
if(loc && isliving(loc))
@@ -1188,7 +1188,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
SSnanoui.update_user_uis(L, src) // Update the receiving user's PDA UI so that they can see the new message
/obj/item/device/pda/proc/new_news(var/message)
new_info(news_silent, newstone, news_silent ? "" : "\icon[src] <b>[message]</b>")
new_info(news_silent, newstone, news_silent ? "" : "[icon2html(src, viewers(get_turf(src)))] <b>[message]</b>")
if(!news_silent)
new_news = 1
@@ -1201,7 +1201,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
new_message(sending_device, sending_device.owner, sending_device.ownjob, message)
/obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message)
var/reception_message = "\icon[src] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>)"
var/reception_message = "[icon2html(src, viewers(get_turf(src)))] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>)"
new_info(message_silent, ttone, reception_message)
log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]",ckey=key_name(usr),ckey_target=key_name(name))
@@ -1213,7 +1213,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(ismob(sending_unit.loc) && isAI(loc))
track = "(<a href='byond://?src=\ref[loc];track=\ref[sending_unit.loc];trackname=[html_encode(sender)]'>Follow</a>)"
var/reception_message = "\icon[src] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>) [track]"
var/reception_message = "[icon2html(src, viewers(get_turf(src)))] <b>Message from [sender] ([sender_job]), </b>\"[message]\" (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[sending_unit]'>Reply</a>) [track]"
new_info(message_silent, newstone, reception_message)
log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]",ckey=key_name(usr),ckey_target=key_name(name))
@@ -1534,7 +1534,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/CouldUseTopic(var/mob/user)
..()
if(iscarbon(user))
playsound(src, 'sound/machines/pda_click.ogg', 20)
playsound(loc, 'sound/machines/pda_click.ogg', 20)
//Some spare PDAs in a box
/obj/item/storage/box/PDAs
+1 -1
View File
@@ -36,7 +36,7 @@
if(!user || !M) return //sanity
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to flash [M.name] ([M.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='warning'>Used the [src.name] to flash [M.name] ([M.ckey])</span>")
msg_admin_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(M))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+1 -1
View File
@@ -57,7 +57,7 @@
to_chat(user, SPAN_WARNING("You are already hacking this door!"))
return 0
if(!is_type_in_list(target, supported_types))
to_chat(user, "\icon[src] <span class='warning'>Unable to hack this target!</span>")
to_chat(user, "[icon2html(src, user)] <span class='warning'>Unable to hack this target!</span>")
return 0
if(istype(target, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/door = target
@@ -205,7 +205,7 @@ var/global/list/default_medbay_channels = list(
/obj/item/device/radio/CouldUseTopic(var/mob/user)
..()
if(clicksound && iscarbon(user))
playsound(src, clicksound, clickvol)
playsound(loc, clicksound, clickvol)
/obj/item/device/radio/Topic(href, href_list)
if(..())
+6 -6
View File
@@ -565,14 +565,14 @@ BREATH ANALYZER
if(0 to 25)
to_chat(user,"Subject oxygen levels nominal.")
if(25 to 50)
to_chat(user,"<font color='blue'>Subject oxygen levels abnormal.</font>")
to_chat(user,"<span class='notice'>Subject oxygen levels abnormal.</span>")
if(50 to INFINITY)
to_chat(user,"<font color='blue'><b>Severe oxygen deprivation detected.</b></font>")
to_chat(user,"<span class='notice'><b>Severe oxygen deprivation detected.</b></span>")
var/obj/item/organ/internal/L = H.internal_organs_by_name[BP_LUNGS]
if(istype(L))
if(L.is_bruised())
to_chat(user,"<font color='red'><b>Ruptured lung detected.</b></font>")
to_chat(user,"<span class='warning'><b>Ruptured lung detected.</b></span>")
else if(L.is_damaged())
to_chat(user,"<b>Damaged lung detected.</b>")
else
@@ -588,11 +588,11 @@ BREATH ANALYZER
if(INTOX_MUSCLEIMP to INTOX_VOMIT)
additional_string = "\[MODERATELY INTOXICATED\]"
if(INTOX_VOMIT to INTOX_BALANCE)
additional_string = "<font color='red'>\[HEAVILY INTOXICATED\]</font>"
additional_string = "<span class='warning'>\[HEAVILY INTOXICATED\]</span>"
if(INTOX_BALANCE to INTOX_DEATH)
additional_string = "<font color='red'>\[ALCOHOL POISONING LIKELY\]</font>"
additional_string = "<span class='warning'>\[ALCOHOL POISONING LIKELY\]</span>"
if(INTOX_DEATH to INFINITY)
additional_string = "<font color='red'>\[DEATH IMMINENT\]</font>"
additional_string = "<span class='warning'>\[DEATH IMMINENT\]</span>"
to_chat(user,"<span class='normal'>Blood Alcohol Content: [round(bac,0.01)] <b>[additional_string]</b></span>")
if(H.breathing && H.breathing.total_volume)
@@ -35,7 +35,7 @@ effective or pretty fucking useless.
to_chat(user, "<span class='warning'>The mind batterer has been burnt out!</span>")
return
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used [src] to knock down people in the area.</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='warning'>Used [src] to knock down people in the area.</span>")
for(var/mob/living/carbon/human/M in orange(10, user))
spawn()
+2 -2
View File
@@ -68,7 +68,7 @@
H.forceMove(present)
H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been wrapped with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to wrap [H.name] ([H.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='warning'>Used the [src.name] to wrap [H.name] ([H.ckey])</span>")
msg_admin_attack("[key_name_admin(user)] used [src] to wrap [key_name_admin(H)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(H))
else
@@ -101,7 +101,7 @@
if(user in target) //no wrapping closets that you are inside - it's not physically possible
return
user.attack_log += text("\[[time_stamp()]\] <font color='blue'>Has used [src.name] on \ref[target]</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='notice'>Has used [src.name] on \ref[target]</span>")
if (istype(target, /obj/item) && !(istype(target, /obj/item/storage) && !istype(target,/obj/item/storage/box)))
+3 -3
View File
@@ -109,13 +109,13 @@
if(0)
damage_desc = "Unknown"
if(1 to 5)
damage_desc = "<font color='green'>negligible</font>"
damage_desc = "<span class='good'>negligible</span>"
if(5 to 15)
damage_desc = "<font color='green'>light</font>"
damage_desc = "<span class='good'>light</span>"
if(15 to 30)
damage_desc = "<font color='orange'>moderate</font>"
if(30 to 1000)
damage_desc = "<font color='red'>severe</font>"
damage_desc = "<span class='warning'>severe</span>"
if(!total_score) total_score = D.organs_scanned.len
+6 -6
View File
@@ -139,10 +139,10 @@ var/const/NO_EMAG_ACT = -50
/obj/item/card/id/proc/prevent_tracking()
return 0
/obj/item/card/id/proc/show(mob/user as mob)
/obj/item/card/id/proc/show(mob/user)
if(front && side)
to_chat(user, browse_rsc(front, "front.png"))
to_chat(user, browse_rsc(side, "side.png"))
send_rsc(user, front, "front.png")
send_rsc(user, side, "side.png")
var/datum/browser/popup = new(user, "idcard", name, 650, 260)
popup.set_content(dat())
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
@@ -214,8 +214,8 @@ var/const/NO_EMAG_ACT = -50
to_chat(user, "<span class='notice'>Biometric Imprinting successful!</span>")
return
for(var/mob/O in viewers(user, null))
O.show_message(text("[] shows you: \icon[] []: assignment: []", user, src, src.name, src.assignment), 1)
user.visible_message("<b>[user]</b> shows you: [icon2html(src, viewers(get_turf(src)))] [src.name]. The assignment on the card: [src.assignment]",\
"You flash your ID card: [icon2html(src, viewers(get_turf(src)))] [src.name]. The assignment on the card: [src.assignment]")
src.add_fingerprint(user)
return
@@ -280,7 +280,7 @@ var/const/NO_EMAG_ACT = -50
set category = "Object"
set src in usr
to_chat(usr, text("\icon[] []: The current assignment on the card is [].", src, src.name, src.assignment))
to_chat(usr, text("[icon2html(src, usr)] []: The current assignment on the card is [].", src.name, src.assignment))
to_chat(usr, "The age on the card is [age].")
to_chat(usr, "The citizenship on the card is [citizenship].")
to_chat(usr, "The religion on the card is [religion].")
@@ -138,7 +138,7 @@
injected_with_monkey = " <span class='danger'>(MONKEY)</span>"
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been injected with [name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [name] to inject [M.name] ([M.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='warning'>Used the [name] to inject [M.name] ([M.ckey])</span>")
log_attack("[user.name] ([user.ckey]) used the [name] to inject [M.name] ([M.ckey])",ckey=key_name(user),ckey_target=key_name(M))
message_admins("[key_name_admin(user)] injected [key_name_admin(M)] with \the [src][injected_with_monkey]")
@@ -125,7 +125,7 @@
if(!ptank)
to_chat(user, "<span class='notice'>Attach a phoron tank first!</span>")
return
var/dat = text("<TT><B>Flamethrower (<A HREF='?src=\ref[src];light=1'>[lit ? "<font color='red'>Lit</font>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A HREF='?src=\ref[src];amount=-100'>-</A> <A HREF='?src=\ref[src];amount=-10'>-</A> <A HREF='?src=\ref[src];amount=-1'>-</A> [throw_amount] <A HREF='?src=\ref[src];amount=1'>+</A> <A HREF='?src=\ref[src];amount=10'>+</A> <A HREF='?src=\ref[src];amount=100'>+</A><BR>\n<A HREF='?src=\ref[src];remove=1'>Remove phorontank</A> - <A HREF='?src=\ref[src];close=1'>Close</A></TT>")
var/dat = text("<TT><B>Flamethrower (<A HREF='?src=\ref[src];light=1'>[lit ? "<span class='warning'>Lit</span>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A HREF='?src=\ref[src];amount=-100'>-</A> <A HREF='?src=\ref[src];amount=-10'>-</A> <A HREF='?src=\ref[src];amount=-1'>-</A> [throw_amount] <A HREF='?src=\ref[src];amount=1'>+</A> <A HREF='?src=\ref[src];amount=10'>+</A> <A HREF='?src=\ref[src];amount=100'>+</A><BR>\n<A HREF='?src=\ref[src];remove=1'>Remove phorontank</A> - <A HREF='?src=\ref[src];close=1'>Close</A></TT>")
user << browse(dat, "window=flamethrower;size=600x300")
onclose(user, "flamethrower")
return
+2 -2
View File
@@ -75,7 +75,7 @@
if(user)
H.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been handcuffed (attempt) by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attempted to handcuff [H.name] ([H.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='warning'>Attempted to handcuff [H.name] ([H.ckey])</span>")
msg_admin_attack("[key_name_admin(user)] attempted to handcuff [key_name_admin(H)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(H))
feedback_add_details("handcuffs","H")
@@ -118,7 +118,7 @@
var/s = SPAN_WARNING("[H] chews on [H.get_pronoun("his")] [O.name]!")
H.visible_message(s, SPAN_WARNING("You chew on your [O.name]!"))
message_admins("[key_name_admin(H)] is chewing on [H.get_pronoun("his")] restrained hand - (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[H.x];Y=[H.y];Z=[H.z]'>JMP</a>)")
H.attack_log += text("\[[time_stamp()]\] <font color='red'>[s] ([H.ckey])</font>")
H.attack_log += text("\[[time_stamp()]\] <span class='warning'>[s] ([H.ckey])</span>")
log_attack("[s] ([H.ckey])",ckey=key_name(H))
if(O.take_damage(3, 0, damage_flags = DAM_SHARP|DAM_EDGE, used_weapon = "teeth marks"))
@@ -489,7 +489,7 @@ the implant may become unstable and either pre-maturely inject the subject or si
<b>Implant Specifications:</b><BR>
<b>Name:</b> Cybersun Industries Adrenalin Implant<BR>
<b>Life:</b> Five days.<BR>
<b>Important Notes:</b> <font color='red'>Illegal</font><BR>
<b>Important Notes:</b> <span class='warning'>Illegal</span><BR>
<HR>
<b>Implant Details:</b> Subjects injected with implant can activate a massive injection of adrenalin.<BR>
<b>Function:</b> Contains nanobots to stimulate body to mass-produce Adrenalin.<BR>
@@ -202,7 +202,7 @@
user.visible_message(SPAN_WARNING("\The [user] tags \the [M] with \the [src]!"), SPAN_NOTICE("You tag \the [M] with \the [src]."), range = 3)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'> Implanted with [src.name] ([src.ipc_tag.name]) by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] ([src.ipc_tag.name]) to implant [M.name] ([M.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <span class='warning'>Used the [src.name] ([src.ipc_tag.name]) to implant [M.name] ([M.ckey])</span>")
msg_admin_attack("[key_name_admin(user)] implanted [key_name_admin(M)] with [src.name] (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",ckey=key_name(user),ckey_target=key_name(M))
ipc_tag.replaced(H, H.organs_by_name[BP_HEAD])
@@ -58,7 +58,7 @@
<b>Implant Specifications:</b><BR>
<b>Name:</b> Freedom Beacon<BR>
<b>Life:</b> optimum 5 uses<BR>
<b>Important Notes:</b> <font color='red'>Illegal</font><BR>
<b>Important Notes:</b> <span class='warning'>Illegal</span><BR>
<HR>
<b>Implant Details:</b> <BR>
<b>Function:</b> Transmits a specialized cluster of signals to override handcuff locking
+2 -2
View File
@@ -76,7 +76,7 @@
<li>Open the control panel</li>
<li>Set the speed to 2</li>
<li>Start firing at the singularity generator</li>
<li><font color='red'><b>When the singularity reaches a large enough size so it starts moving on it's own set the speed down to 0, but don't shut it off</b></font></li>
<li><span class='warning'><b>When the singularity reaches a large enough size so it starts moving on it's own set the speed down to 0, but don't shut it off</b></span></li>
<li>Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?</li>
</ol>
@@ -238,7 +238,7 @@
A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps:
<ol>
<li><b><font color='red'>PANIC!</font></b></li>
<li><b><span class='warning'>PANIC!</span></b></li>
<li>Get your ass over to engineering! <b>QUICKLY!!!</b></li>
<li>Get to the <b>Area Power Controller</b> which controls the power to the emitters.</li>
<li>Swipe it with your <b>ID card</b> - if it doesn't unlock, continue with step 15.</li>
@@ -476,7 +476,7 @@
/obj/item/storage/box/mousetraps
name = "box of Pest-B-Gon mousetraps"
desc = "<B><FONT color='red'>WARNING:</FONT></B> <I>Keep out of reach of children</I>."
desc = "<B><span class='warning'>WARNING:</span></B> <I>Keep out of reach of children</I>."
icon_state = "mousetraps"
starts_with = list(/obj/item/device/assembly/mousetrap = 6)
@@ -103,7 +103,7 @@ Frequency:
src.temp += "<B>You are at \[[sr.x],[sr.y],[sr.z]\]</B> in orbital coordinates.<BR><BR><A href='byond://?src=\ref[src];refresh=1'>Refresh</A><BR>"
else
src.temp += "<B><FONT color='red'>Processing Error:</FONT></B> Unable to locate orbital position.<BR>"
src.temp += "<B><span class='warning'>Processing Error:</span></B> Unable to locate orbital position.<BR>"
else
if (href_list["freq"])
src.frequency += text2num(href_list["freq"])
+1 -1
View File
@@ -292,7 +292,7 @@
/obj/item/weldingtool/examine(mob/user)
if(..(user, 0))
to_chat(user, text("\icon[] [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel ))
to_chat(user, text("[icon2html(src, user)] [] contains []/[] units of fuel!", src.name, get_fuel(),src.max_fuel ))
/obj/item/weldingtool/attackby(obj/item/W, mob/user)
if(W.isscrewdriver())
+2 -2
View File
@@ -197,6 +197,6 @@
attack_verb = list("banned")
/obj/item/banhammer/attack(mob/M as mob, mob/user as mob)
to_chat(M, "<font color='red'><b> You have been banned FOR NO REISIN by [user]</b></font>")
to_chat(user, "<font color='red'> You have <b>BANNED</b> [M]</font>")
to_chat(M, "<span class='warning'><b> You have been banned FOR NO REISIN by [user]</b></span>")
to_chat(user, "<span class='warning'> You have <b>BANNED</b> [M]</span>")
playsound(loc, 'sound/effects/adminhelp.ogg', 15)
@@ -50,5 +50,5 @@
/obj/item/weldpack/examine(mob/user)
..(user)
to_chat(user, text("\icon[] [] units of fuel left!", src, src.reagents.total_volume))
to_chat(user, text("[icon2html(src, user)] [] units of fuel left!", src.reagents.total_volume))
return
+1 -8
View File
@@ -50,7 +50,7 @@
/obj/CanUseTopic(var/mob/user, var/datum/topic_state/state)
if(user.CanUseObjTopic(src))
return ..()
to_chat(user, "<span class='danger'>\icon[src]Access Denied!</span>")
to_chat(user, "<span class='danger'>[icon2html(src, user)]Access Denied!</span>")
return STATUS_CLOSE
/mob/living/silicon/CanUseObjTopic(var/obj/O)
@@ -159,13 +159,6 @@
/obj/proc/hear_talk(mob/M as mob, text, verb, datum/language/speaking)
if(talking_atom)
talking_atom.catchMessage(text, M)
/*
var/mob/mo = locate(/mob) in src
if(mo)
var/rendered = "<span class='game say'><span class='name'>[M.name]: </span> <span class='message'>[text]</span></span>"
mo.show_message(rendered, 2)
*/
return
/obj/proc/see_emote(mob/M as mob, text, var/emote_type)
return
+2 -2
View File
@@ -59,9 +59,9 @@
if(..(user, 1))
if (mybucket)
var/contains = mybucket.reagents.total_volume
to_chat(user, "\icon[src] The bucket contains [contains] unit\s of liquid!")
to_chat(user, "[icon2html(src, user)] The bucket contains [contains] unit\s of liquid!")
else
to_chat(user, "\icon[src] There is no bucket mounted on it!")
to_chat(user, "[icon2html(src, user)] There is no bucket mounted on it!")
//everything else is visible, so doesn't need to be mentioned
@@ -168,7 +168,7 @@
if(pulling)
occupant.visible_message("<span class='danger'>[pulling] has thrusted \the [name] into \the [A], throwing \the [occupant] out of it!</span>")
pulling.attack_log += "\[[time_stamp()]\]<font color='red'> Crashed [occupant.name]'s ([occupant.ckey]) [name] into \a [A]</font>"
pulling.attack_log += "\[[time_stamp()]\]<span class='warning'> Crashed [occupant.name]'s ([occupant.ckey]) [name] into \a [A]</span>"
occupant.attack_log += "\[[time_stamp()]\]<font color='orange'> Thrusted into \a [A] by [pulling.name] ([pulling.ckey]) with \the [name]</font>"
msg_admin_attack("[pulling.name] ([pulling.ckey]) has thrusted [occupant.name]'s ([occupant.ckey]) [name] into \a [A] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[pulling.x];Y=[pulling.y];Z=[pulling.z]'>JMP</a>)",ckey=key_name(pulling),ckey_target=key_name(occupant))
else