ID:2642352
 
(See the best response by Kaiochao.)
Code:
obj/diag
plane = HUD_PLANE
screen_loc = "2,2"
var/placex=2
var/place=2
maptext_width = 420
mouse_opacity = 0
alpha=255
New()
..()
spawn(100)
if(src)del(src)

proc/Update(var/T as text, var/color="white", var/outline="navy")
maptext = "<font style=\"color:[color]; -dm-text-outline: 1px [outline];\">[T]</font>"
screen_loc = "[placex],2"
for(var/obj/diag/d in usr.client.screen)
if(d&&d!=src)
d.place++
d.screen_loc = "[placex],[d.place]"
if(d.place==6)
animate(d,, alpha = 130,, easing = ELASTIC_EASING)
else if(d.place==7)
animate(d,, alpha = 50,, easing = ELASTIC_EASING)
else if(d.place>=8)
del(d)
mob
proc
OUTPUT(var/T as text)
if(!src.client||!src)return
var/obj/diag/d = new/obj/diag
client.screen += d
d.Update(T)


proc
ANNOUNCE(var/T as text,var/color="white", var/outline="navy")
for(var/mob/M in world)
if(!M.client||!M)continue
M.OUTPUT(T)


////Test verb
mob
verb
Anon(var/t as text)
ANNOUNCE("[t]")


Problem description:
Attempting to create an announcement system that displays to all clients.

Messages either stack on top of each other, or jump too far up on the screen.

Is there a better approach to this?
Best response
usr doesn't automagically refer to the player with src in their client.screen.

Push up the other diags in mob.OUTPUT() before adding the new one to client.screen, instead of doing it in diag.Update() for the wrong mob. Make sure not to use usr.

usr refers to the mob that initiated the call stack, which starts at the Anon verb, which calls global.ANNOUNCE, which calls mob.OUTPUT, which calls diag.New and diag.Update.
In response to Kaiochao
Ah, I see! I assumed since each player is running the Output proc that they would each run the Update proc separately. So I assumed it would apply correctly.

Thanks for the clarification.