ID:156942
 
I'm trying to think of the best way to find the location of mobs on the map, without using for(var/mob/M in world).

The mob (a player) can create two rows of objects that span an entire map, above and below them (see crude display below). These objects are dense, so as to trap other mobs inside. What id like to do is be able to find all mobs within that area between the two lines (so i can do something to those mobs).


(Y) (Y)
-----------------------------------
(P)
X

-----------------------------------
(Y)

So, (P) would have created the lines. And X would be the only one id want to find. The (Y) outside the lines would be ignored.

Previously, id created the objects below the player, and they were added to a list. Then i searched through the list of objects to find Mobs standing in the same turf location as those objects. This worked fine, but now i dont have objects covering where i want to find mobs. The objects just border it.

I dont want to span invisible objects either in this space, as the map is large (125x125) and that would be 1000's of objects.

My original idea was to do some sort of mob.y comparison, but that can change depending on what its taking the Y from.

Anyone think of a simple solution? My only other idea is to create a single non-dense invisible object in the middle of these lines, and then extrapolate the range from that. But then, what would i do, for(var/mob/M in ?) view? Could i do a view thats the map sized?? hmmm. Would be better than looping through every mob to check they are on the same level as me i guess.

Anyone have some better suggestions id love to hear them.
I'm still new at all this so I wouldn't take my opinion too seriously, but this seems pretty simple. When you're creating the wall of objects you should know the Y value you're creating the objects at. When you create the walls, call a function which takes the top y and lower y as arguments. Since I don't think your game will have many mobs, just loop through all the mobs in the world and check if each one has a y in between the top and bottom values. If so, perform whatever action on the mob.
In response to 167981728 (#1)
167981728 wrote:
Since I don't think your game will have many mobs, just loop through all the mobs in the world and check if each one has a y in between the top and bottom values. If so, perform whatever action on the mob.

It will have around 100 so id like to avoid this if possible. It's true about the Y of the Objects on creation, suppose id have to store them in a tmp variable somewhere. Hmmm.
You can try looping through block(). Ex:
Tech/Ultimate/Flood
for(var/mob/M in block(locate(1,src.y-1,src.z),locate(world.maxx,src.y+1,src.z))-src)
M << "YOU DROWNED! MWAHAHAHAHAHA!"


I can't remember if it can be used like that. If it can't, assign a /turf variable to the block() in the for() loop and check for any mobs in that turf.
In response to GhostAnime (#3)
GhostAnime wrote:
You can try looping through block(). Ex:
Tech/Ultimate/Flood
> for(var/mob/M in block(locate(1,src.y-1,src.z),locate(world.maxx,src.y+1,src.z))-src)
> M << "YOU DROWNED! MWAHAHAHAHAHA!"
>


I can't remember if it can be used like that. If it can't, assign a /turf variable to the block() in the for() loop and check for any mobs in that turf.

Did not seem to work so i did;

    for(var/turf/T in block(locate(1,Control.flameloc[1],src.z),locate(world.maxx,Control.flameloc[2],src.z))-src)
if(T)
var/mob/M = locate() in T
if(M) world << "Found a [M]"


flameloc() being a list on the mob, thats set to the upper most and lower most .y of the flames. This seemed to work.

Btw, what is ))-src) for? I checked for block() and couldnt quite work out what the purpose of that was. To exclude the turf the current src is on? Didnt know you could do that from looking at the reference.
In response to EternalDuelistSoul (#4)
The -src was dealing with the mob loop, since we would have wanted to have the mob who called it to be removed from the list.

BTW, the if(T) line is useless. If a /turf wasn't there, it wouldn't be assigned as a T.

I hope you know that locate() finds one instance of a path. If there'll be 2+ instances, you would want to for() loop it.
In response to GhostAnime (#5)
GhostAnime wrote:
The -src was dealing with the mob loop, since we would have wanted to have the mob who called it to be removed from the list.

BTW, the if(T) line is useless. If a /turf wasn't there, it wouldn't be assigned as a T.

I hope you know that locate() finds one instance of a path. If there'll be 2+ instances, you would want to for() loop it.

Oh i didnt know you could do that with mob loops (-src). Good point on the locate() I did assume it would ignore mobs that were standing on the same turf. Which it did, so as you said, a loop fixed that.
In response to EternalDuelistSoul (#2)
Yes, looping through the block is more reasonable as instead of checking every mob and then checking each one if they're in that block. This way instead of looping through, say 200 mobs (including NPC's) you're only looping through about 100 turfs. It saves a good chunk of time for that procedure.

However, if you're only looking for players and Not NPC's you might just want to loop through the world for clients instead of mobs, then check their mob and see if it's within the area you predetermined. When looping through client you're only looking through the people who are actually on the server so even if the server is full of people you may less clients than turfs in that block.