ID:261416
 
I have made a tell verb and it works fine but I need to know how to make it so that it only shows Players in the list if people to tell not npcs. I tryed doing mob/PC but it didn't work.

Tell(M as mob in world, msg as text)
set src in oview()
M << "\icon[usr] [usr] tells you: [msg]"
Try doing client/C as client in world, msg as text.

Tell me if that works.

-Rcet
This is a tutorial from Ensya. The actual proc it makes is pretty useless, since you can just do what Rcet said. But the concept is a good one to learn in case similar situation come up, but don't have such an easy solution.


<FONT SIZE=5>
Limited Return procs</FONT>

Limited Return Procs, as I call them, are procs that return a specific value, usually from a list. In this tutorial, I'm going to briefly show you how to create a limited return proc that will return only players (that is, mobs with clients) in view().

First of all, we need to declare the proc, and I'm going to call it get_client().
<FONT COLOR=silver>
proc/get_client(mob/X)
</FONT>The mob/X as the end is going to refer to the source mob, that is, the mob from which the view() originates. Next, we need to create a list to gather all the clients in.
<FONT COLOR=silver>
   var/list/Gather = list()
</FONT>Next, we need to search the view() for any nearby mobs, since clients only belong to mobs.
<FONT COLOR=silver>
   for(var/mob/M in view(X,world.view))
</FONT>Then we need to check and see if that mob has a client.
<FONT COLOR=silver>
      if(M.client)
</FONT>And if it does, add it to the Gather list.
<FONT COLOR=silver>
         Gather += M
</FONT>Now that we've gathered all the local mobs who also have clients, we need to send that list back through the proc.
<FONT COLOR=silver>
   return Gather
</FONT>
All right, now your end result should look something like this:

<FONT COLOR=silver>
proc/get_client(mob/X)
   var/list/Gather = list()
   for(var/mob/M in view(X,world.view))
      if(M.client)
         Gather += M
   return Gather
</FONT>With that out of the way, you can now proceed to use this new proc.

<FONT COLOR=silver>
mob/verb/ViewPlayers(mob/M in get_client(usr))
   usr << "You selected a client!"
   M << "You are a client!"
</FONT>The above verb will let you select ONLY mobs with clients in view.


In response to Rcet
Like this?



Tell(client/C as client in world, msg as text)
set src in oview()
M << "<font color=#6666FF>\icon[usr] [usr] tells you: [msg]</font>"








ERROR:::

Mob.dm:38:error: Bad input type: client
In response to Rcet
I don't believe clients are listed in world.contents. Also, "as client" will fail on compile, since client isn't a valid filter.

There are a couple of others options, though.
A) Maintain a list of players. Add to it on Login(), remove from it on Logout().

Tell(mob/M in players_list, msg as text)
M << "\icon[usr] [usr] tells you: [msg]"

2) have player mobs and NPC mobs be of different types:

Tell(mob/player/M in world, msg as text)
M << "\icon[usr] [usr] tells you: [msg]"

III) What Foomer said. This adds a bit of overhead compared to option A, though, as it has to cycle through a bunch of mobs and rebuild the list everytime someone tries to tell something to someone. Its a good method to use in a lot of other occasions, though, I just wouldn't do it when dealing with the whole world.

[Edit:] I should have read your post more clearly, and not just the replies. 2 is the option you want, since players are already of type /mob/PC. What you tried to do, I think, is filter like "M as mob/PC", which doesn't work. What you want to do it make sure that PCs are the only valid argument to the verb, which is what my code above does. You might want to keep option A in mind, though. Its a little more flexible, and can really be helpful in a lot of coding situations.

-AbyssDragon
In response to AbyssDragon
I get what your saying on number 2, I tryed it but it still seems to be letting you use the verbs on npcs. I have my npcs under mob/NPC and players under mob/PC. I think thats what you ment about making them different.
In response to Little Sally
Ok, try this:
mob
verb
Tell(mob/M as mob in world,msg as text)
if(istype(M,/mob/PC/))
//code here
else
usr << "You can only message players."

or
mob
verb
Tell(mob/M as mob in world,msg as text)
if(M.client
//code here
else
usr << "You can only message players."


...OR...
mob
verb
Tell(mob/PC/M as mob in world,msg as text)
//code here



hehe.. hope i helped.

-Rcet
In response to Rcet
Ok ty so much ;)
In response to AbyssDragon
AbyssDragon wrote:
I don't believe clients are listed in world.contents. Also, "as client" will fail on compile, since client isn't a valid filter.

There are a couple of others options, though.
A) Maintain a list of players. Add to it on Login(), remove from it on Logout().

Deadron's Players library stores online clients in a GameController. (I tend to favor event loops as offered by Event Loop's GameController anyway.)
Best solution to this problem (both in terms of server overhead, and clarity at runtime) is to reword the verb from the target's perspective, like so:

mob/pc/verb/tell(message as text)
set src in oview() //or world. or whatever.

Now, usr is the teller, and src is the tellee. With this method, you will only see the verb in right-click menus if the thing you're clicking on is an actual pc, and if there's no other pcs in the targetable area, the verb will not clutter the list.