ID:264467
 
Code:
mob/Basic/verb/Say()
set name="Say"
set desc="Talk to those on your screen."
var/list/L
L = list("<font","<B>","<I>","<U>","")
usr.overlays+='SpeachBubble.dmi'
var/msg=input("","Say") as text
for(var/H in L)
if(findtext(msg,H))
usr.overlays-='SpeachBubble.dmi'; return
usr.overlays-='SpeachBubble.dmi'
if(msg)
for(var/mob/player/v in view(usr))
v<<output("[usr] says: [msg]","Chat")

The above code makes nothing appear.

mob/Basic/verb/Say()
set name="Say"
set desc="Talk to those on your screen."
var/list/L
L = list("<font","<B>","<I>","<U>","")
usr.overlays+='SpeachBubble.dmi'
var/msg=input("","Say") as text
for(var/H in L)
if(findtext(msg,H))
usr.overlays-='SpeachBubble.dmi'; return
else
usr.overlays-='SpeachBubble.dmi'
if(msg)
for(var/mob/player/v in view(usr))
v<<output("[usr] says: [msg]","Chat")
return //<----Without that, the message is repeated for each of the vars in the list: L
//with the 'return', it only displays a message on the usr's screen.


Problem description:
The version where 4 messages appear (one for each of the list entries) worked perfectly before I used the output() proc.
My converted OOC still works fine, I'm guessing because it defines the message in the verbs title - but I want a speech bubble to appear while the person is using Say...
I think the reason this isn't working is because of the "" in the list. When findtext checks if an empty string ("") is in the text, it always returns 1. So, when the loop gets to the "" part it always ends right there and doesn't let the message go through regardless of what they type. I think that you must have added that recently without thinking it made any difference.
list("<font","<B>","<I>","<U>","")//<-- "" (an empty string) is not allowed?
findtext(msg,"")//<--will always return 1

Also, it might be notable that the following doesn't need to be done in two lines.
    var/list/L
L = list("<font","<B>","<I>","<U>","")
//vars can have initial values, lists aren't an exception, so you can just do
var/list/L = list("<font","<B>","<I>","<U>","")

Also, you can use the output operator (the << operator) on a list instead of looping through the list and using it on each thing in the list. Example:
//instead of this:
for(var/mob/player/v in view(usr))
v<<output("[usr] says: [msg]","Chat")
//you can simply do this:
view(usr)<<output("[usr] says: [msg]","Chat") //also, the default value of view() is usr,
//or so in this case you can leave it blank
view()<<output("[usr] says: [msg]","Chat")
/*you could also use viewers() instead of view() if you wanted it to be based upon who can see the
person talking instead of what the person talking can see (which makes more sense)
Or even hearers() if you wanted, say, blind people to be able to hear.*/
In response to Naokohiro
Mhmm. Thanks I'll try the things suggested.
On a side note, I knew the two lines could be one. Well, I knew recently. When I made the verb a year ago or so, I was 'tarded :P
As for the for(m in view()) bit; that wasn't originally like it, it was something I tried because its how OOC is (which works). :)

p.s. I prefer view, because I have an adjustable screen size; and like players to know whether or not the recipients have heard what they've said.
In response to Saucepan Man
You could instead use hearers() like so:

hearers(usr.screen_size,usr)<<"Hi"


Of course, even hearers(usr) should return the same thing. Either way, don't use view() for a Say verb EVER. Use hearers instead.
You have a for loop in a for loop... ex;
for(var/i=5,i>0,i--)
world<<i
for(var/e=5,e>0,e--)
world<<e

This is a good example of a for for loop, it causes the ouput;
5//starts first for loop, displays 5
5//then the second loop is started, so it counts down from 5 again
4
3
2
1
4// first loop now loops
5// causing the second loop to be called again
4
3
2
1
3
5
4
3
2
1
2
5
4
3
2
1
1
5
4
3
2
1

Beware with loops! Especially while() loops, I find myself accidentally making infinite loops all over the place when I start a new project.
In response to Demon_F0rce
Mhmm actually I agree.
I kinda thought I was future proofing when I started coding things like that... I thought there might be an instance when you couldnt see them but they should be able to hear your; turns out "no".
In response to Saucepan Man
Saucepan Man wrote:
p.s. I prefer view, because I have an adjustable screen size; and like players to know whether or not the recipients have heard what they've said.

The problem with this is that you won't be able to hear what they're saying if they can't see you!
In response to Naokohiro
In which case, how would they know that you're there?
Which is why I agreed with the other guy about using hearers()
In response to Demon_F0rce
Demon_F0rce wrote:
You could instead use hearers() like so:
hearers(usr.screen_size,usr)<<"Hi"

Of course, even hearers(usr) should return the same thing.

Well, not if say, the game has an adjustable view size and the player has changed his from the default. The default range of all that 'family' of procs (which includes view(),range(),viewers(),etc) is always world.view. With say, view(), you could do what you say and do something like view(usr,usr.client.view), but for the viewers()/hearers() side, it isn't that simple (though still pretty simple =P). For viewers(), just using the maximum range possible might work if, for some reason, you really wanted to try to catch everyone who can see someone, but I dunno how well that would work. It's likely that you may get back inapplicable NPCs or maybe even players, so that's a shot in the dark.
So, to recap, viewers(X) isn't necessarily a list of all the mobs who can see X - it's a list of mobs who can see X that are within a certain range of it: viewers(X) ~== viewers(X,world.view).
In response to Saucepan Man
Saucepan Man wrote:
In which case, how would they know that you're there?
Because they can hear you talking... Duh?