ID:157258
 
I can't seem to find a simple way to do this. I do have a method but it seems to be overly wasteful of processing time...

var/Grass = 0
for(var/turf/Grass/T in world) if(T.x==src.x && T.y==src.y && T.z==src.z) Grass = 1

if(Grass) usr << "You are stood on Grass!"


There must be a better way than that? I thought using 'src.loc', but my attempts at getting it to work didnt result in much success.

Anyone done something like this for themselves and wouldnt mind throwing in some input. Thanks.
var/turf/grass/t=locate(x,y,z)
if(t&&istype(t))
var/mob/M=locate() in t
if(M) world<<"Found mob [M] in [t]"
In response to Emasym
Nope.

if(istype(loc, /turf/Grass))


Note that this is rather poor programming practice anyway, and you should check to see if there's some better way of doing things.
In response to Garthor
Garthor wrote:
Nope.

if(istype(loc, /turf/Grass))

Note that this is rather poor programming practice anyway, and you should check to see if there's some better way of doing things.

That did it, thanks. Why is it poor programming practise though? I tried something like what Emasym wrote there but it didnt work and it seemed to be still be more complicated than what i needed.
In response to EternalDuelistSoul
In general, any istype() checks (except for verifying the argument of some proc, like Entered()) are poor practice because you are doing the work in the wrong place. The object itself (the Grass in this case) should be the one handling interaction, not the object doing the interacting having to go through saying, "Okay, if it's a grass I'll do this, if it's a water I'll do this, if it's a dirt I'll do this..."

Of course, this is a rather broad topic and I can't really provide any specifics without knowing what you're doing.
In response to Garthor
Oh ok i see what you mean.

Well its simply a check to set the variable of a mob.

It's so it will switch on a variable that locks movement, but only when they are on an invisble track. If there is no track under it, then, i dont want it locking movement and saying its on auto pilot (since it wont steer them anywhere).

I also dont want this doing it automatically when they move over it.
In response to EternalDuelistSoul
Well I forgot checking whether T existed, whether it was the correct type, and other stuff.
In response to Emasym
What you forgot to do was anything even remotely related to the topic at hand.

I see you've edited your post, and it's still very very wrong. Might I suggest actually running your code through a test case in the future so you can tell when it doesn't work?
In response to Garthor
Editted it again, you're right, it didn't. This one however does (I'm sure you'll still find something, but meh) , and it negates the need to run through all the turfs in the world, which is never a good thing.
In response to Emasym
Still incorrect. There is no reason whatsoever to be using locate(). In the incredibly esoteric situation where you have a valid x,y,z location but are not standing on a turf, but another mob is, it would behave incorrectly as well.

Of course, I'm just telling you you're wrong until you produce something equivalent to the example I've already posted, I guess.

Have I already mentioned how silly doing locate(src.x,src.y,src.z) is? It's the same damn thing as src.loc, unless you are occupying an obj or mob, in which case you probably don't care about the turf anyway.
In response to Garthor
The idea was to fill in the x,y,z with the specified location, as you're right on that point. I guess I just understood OP's question wrong, I just never find looping through a whole list to find something specific to be the answer.
In response to Emasym
Emasym wrote:
> var/turf/grass/t=locate(x,y,z)
> if(t&&istype(t))
> var/mob/M=locate() in t
> if(M) world<<"Found mob [M] in [t]"
>


Thanks for that :) it helped me in another project for the game. Much appreciated.
In response to Emasym
Emasym wrote:
> var/turf/grass/t=locate(x,y,z)
> if(t&&istype(t))
> var/mob/M=locate() in t
> if(M) world<<"Found mob [M] in [t]"
>


Out of curiosity: the line "var/mob/M=locate() in t", I know that, since M is defined as /mob, then locate() is really treated as locate(/mob). But, my question is how that works, out of sheer curiosity. That's certainly not something that I could duplicate in my own function, is it, to have a default argument based on the context of the function call? Is this a trick of the compiler or is there deep DM magics involved to make that work or something else?
In response to Chessmaster_19
It's how the built-in procs are built, so it's probably a compiler trick. Same prediction goes for the istype(t) without need of a second argument.
In response to Chessmaster_19
Chessmaster_19 wrote:
That's certainly not something that I could duplicate in my own function, is it, to have a default argument based on the context of the function call?

Correct. That's not something you can duplicate in a custom function.

Is this a trick of the compiler

Yes, of course. First of all, note that this syntax relies on the defined type of the var (var/mob/M). This property doesn't even exist out of compile-time (its only effects are in compile-time*), so you can't ever do anything with it using DM itself (neither is the preprocessor advanced enough for you to do to neat stuff with it using it). It's a handy compiler "trick" for some built-in instructions, similar to how you can access src's properties without writing "src.".


*: Those effects are:
  • It's used for object vars and procs access error checking, which is done by the . operator, and to a lesser extent, by the : operator.
  • It's used for compile-time shorthands in various places. One is input type definitions in argument declarations, primarily used in verbs (MyProcedure(mob/M) is really compiled as MyProcedure(mob/M as mob)). Other places are built-in instructions with specific shorthands where if the type isn't specified, it's taken from the var's defined type instead. These instructions are new(), locate(), istype(). I may have missed some...
  • Some language features require using it as part of their syntax. Well, the only one I remember at the time is the for() object loop. If not overridden by an 'as' clause, the defined type of the looping var is used as the object type filter for the loop:
    for(var/mob/player/P in world)
    //loop through every /mob/player

    for(var/mob/player/P as anything in players)
    //loop through all values in the 'players' list

    This isn't actually a shorthand. It can't be replicated otherwise, using the 'as' clause because it supports any type while 'as' only supports the hardcoded, basic input types.
    Note that while the above examples declare the looping var inside for(), the same effect remains if it is declared elsewhere, and is then merely specified inside for().
In response to Kaioken
Thanks alot, that was interesting. (And to a lesser extent, useful)