ID:161739
 
I'm setting people invisible to a player as previously displayed here.

http://www.byond.com/developer/forum/?id=628836

However it seems that whenever I make text output to view via a verb ( say() ) it allows the player to hear people that they cannot actually see?

Say()
// Mute/Spam checks here.
var/text = input("Say Something. What?","Say" as text
for(var/mob/PC/p in view(usr))
p<<"[usr]: [text]"


So, how can I resolve this issue?

p.s this is just a basic verb to demonstrate that it's not working, this isn't my actual verb :)




It became later apparent that this wouldn't be effective for me, even if I had managed to solve this (Although I do believe GhostAnime would have found the solution) as there were several commands that needed attention, and so it became easier to strip the verbs they were not allowed
Remember view() contains a list of things that the usr can see.

What you want is viewers() or hearers() ;)
In response to GhostAnime
GhostAnime wrote:
Remember view() contains a list of things that the usr can see.

What you want is viewers() or hearers() ;)


Say()
// Mute/Spam checks here.
var/text = input("Say Something. What?","Say" as text
for(var/mob/PC/p in hearers(usr))
p<<"[usr]: [text]"


M'afraid I can still hear invisible people with this change.
In response to Bunnie
...You did read what hearers() is intended for right, in the DM Reference? It is always a good idea to read what a procedure actually does if you do not know about it.

As a side note, the default center value for view()/hearers()/viewers() is usr, so all you need to do is :
for(var/X in viewers())
What I can get from this is you don't want people who are invisible to hear people talk. If thats the case, view() should work.

You also do not need to do the for(mob/m in view()) thing. You can just do this.

view()<<"[usr]:[msg]"

Now if your trying to do the opposite and make it so people invisible CAN hear the non-invis, here is something you could do.

hearers(world.view,usr.loc)<<"[usr]:[msg]"

(hearers thing was done by chessmaster12(Max Quickstaff))
In response to Valen45
Valen45 wrote:
What I can get from this is you don't want people who are invisible to hear people talk. If thats the case, view() should work.

You also do not need to do the for(mob/m in view()) thing. You can just do this.

view()<<"[usr]:[msg]"

Now if your trying to do the opposite and make it so people invisible CAN hear the non-invis, here is something you could do.

hearers(world.view,usr.loc)<<"[usr]:[msg]"

(hearers thing was done by chessmaster12(Max Quickstaff))

As I did explain in the first post, that was a demo proc, I have created my own 'Speak' Proc which I send a list of people to and handle various things with which I use for all communication commands, so I -do- need for(var/mob/M in view())

As explained in the previous topic about this, I am making a area where you only see yourself, not other mob's.

So yeah, basically the say command should be ineffective in this area. I am beginning to consider stripping the user of the command while their inside.

This would be undesireable however, as people could teleport out of the area, and returning verbs does not happen in that instance, even if used inside exited()
In response to Valen45
Valen45 wrote:
You also do not need to do the for(mob/m in view()) thing. You can just do this.

view()<<"[usr]:[msg]"

That's the only correct thing in your post, no offense but the rest is all wrong. Yes, you can just output text to a list containing mobs/clients, and every mob/client in the list will get the message. It should be faster than looping threw the list yourself threw DM softcode.

you don't want people who are invisible to hear people talk. If thats the case, view() should work.

No, it shouldn't! view(Ref) returns a list of atoms that Ref is able to see. So the invisible guy will still hear everyone he can see. Besides, what he wants is, people not to be able to hear invisible people. So if Bob can't see Rob (Rob's invisible), then he wants it so Bob can't hear Rob either.

Now if your trying to do the opposite and make it so people invisible CAN hear the non-invis, here is something you could do.
hearers(world.view,usr.loc)<<"[usr]:[msg]"

This will work, but also wrong on principle, you apparently don't realize what hearers(Ref) does. It returns a list of "people" that can hear Ref, which is similar but slightly different to viewers(Ref) which returns a list of people that are able to see Ref.
So the correct thing to use in a Say() verb is hearers(usr), though this should make people able to hear people that are invisible (ie, have more invisibility than viewer's see_invisible etc, but not people that an opaque wall is blocking the path to them) - but I still find this correct since realistically you actually should be able to hear invisible people. But if you're sure you want people not to be able to hear who they can't see, you'd use the appropriate viewers() proc instead.

Use the DM Reference people! Preferably a lot.
In response to Bunnie
Bunnie wrote:
This would be undesireable however, as people could teleport out of the area, and returning verbs does not happen in that instance, even if used inside exited()

That is EXACTLY why you should never move (or teleport, it is the same) atoms by setting the 'loc' directly (or the coordinate variables which is even worse) - always use Move() instead, or otherwise make sure all procs (Entered(), Enter()...) will work and be called as needed.
If you want a teleport, then what you basically want is to Move() the movable to the new location disregarding if something dense if blocking the way, right? Then, you want to disregard density. You can use a simple trick for this, by temporarily making density 0 while the default Move() proc runs (otherwise you'd need to imitate Move() or redefine it, or similar. I have made an example(s) of such a proc somewhere in the forum, you can try searching for "author:kaioken set_loc(" in the search box).
Here's how to do it:
atom/movable/proc/Teleport(atom/newloc,dir) //defining a new proc for movables
//this proc will be a "wrapper" for calling the Move() proc.
var/old_density = src.density //remember the current atom's density value
src.density = 0 //make it non-dense so it's movement won't be blocked by density
. = src.Move(newloc,dir) //call the Move() proc to do the actual movement.
//note the setting of the . variable. this is so the proc that called Teleport() can know if the movement succeeded or not. more on this later
src.density = old_density //restore the density to what it was before

Using this code to teleport will make sure the movement will not fail because of any blocking density-related, but it could still be blocked by your custom Enter() and Exit() overrides, which is good! Also, if the movement succeeded, all related procs will run like Entered() etc, and make their effect.

On the subject of the . variable, I've recently explained it (for the 30th time or so? this doesn't really personally have to do with you though) here <[link]>, so I won't do it again in this post.
In response to Kaioken
I had that done for all commands, except for a GM's teleport. My apologies.
In response to Bunnie
Bunnie wrote:
My apologies.

None needed. :) Also, my post didn't go to a complete waste. You probably learned a thing or two, and regardless, this is a public forum, which is good since everyone can read posts and learn.
In response to Kaioken
Kaioken wrote:
Bunnie wrote:
My apologies.

None needed. :) Also, my post didn't go to a complete waste. You probably learned a thing or two, and regardless, this is a public forum, which is good since everyone can read posts and learn.

oh, and viewers() didn't work by the way. Invisible people are still heard.
In response to Bunnie
Strange... I'll try testing it out.

For now, you can do a round-about way by:
for(var/mob/X in Y) // X = mob, Y = viewers(), etc
if(X.see_invisible < src.invisibility) continue
The above if() checks if the person can not see 'src'. If not, it'll essentially skip the person (X) to the next mob (as you can tell, break/return would not be a good idea... don't want to stop/break the loop because of one person)
In response to GhostAnime
GhostAnime wrote:
Strange... I'll try testing it out.

For now, you can do a round-about way by:
for(var/mob/X in Y) // X = mob, Y = viewers(), etc
> if(X.see_invisible < src.invisibility) continue
The above if() checks if the person can not see 'src'. If it cannot see, than it'll essentially skip the person to the next value (as you can tell, break/return would not be a good idea... don't want to stop/break the loop because of one person)




That seems sensible. So I could try..

for(var/mob/M in viewers())
if(src.see_invisible > M.invisibility) //add to list of 'seen'
In response to Bunnie
I tried becoming invisible and I couldn't here what I mentioned (kinda obvious since I can not see myself), however, those who couldn't see me couldn't hear what I said either.

When I saw myself (invisible to others), I could hear myself but they couldn't.

When the others can see (via see_invisible), they heard me as well... so it is not really the fault of the procedure (I used viewers())

I think something may be wrong with you became invisible... maybe. You sure you were invisible to others? If so, please show us the snippet of how you tried being invisible.