ID:157763
 
How can i check the turf density in front of my mob depending on his dir, if my mob dir's is north i want to know if the turf north of him density's is 1, and i want to check other vars of the turf too.
var/turf/T=get_step(src,dir)
if(T.density) //it's dense
In response to Ripiz
thanks
In response to Ripiz
var/turf/theTurf = get_step(src, dir)
if(theTurf && theTurf.density) // You also want to make sure there is a turf before you try to do anything with it.
In response to Vermolius
I know that, but I think that would still throw error, not fully sure though.
In response to Ripiz
Ripiz wrote:
I know that, but I think that would still throw error, not fully sure though.

What error would it give? That fixes the potential null.density runtime error you could have gotten.
In response to GhostAnime
if(theTurf && theTurf.density)

For some reason I think, no matter if theTurf is true or false, it still would attempt to check theTurf.density, but possibly I'm wrong.
In response to Ripiz
Nope, because the && and || DM operators short-circuit, meaning that in an AND expression since once a value is evaluated as false it means the entire expression must always evaluate to false, that's done immediately, without bothering to evaluate the rest of the values.
if(0 && someproc() && world.Del())

So the above causes virtually nothing to happen.
In response to Vermolius
Vermolius wrote:
var/turf/theTurf = get_step(src, dir)
if(theTurf && theTurf.density) // You also want to make sure there is a turf before you try to do anything with it.


Catching an error like this isn't always the best move. get_step() might be returning null because there's a serious problem. Hiding this error doesn't fix the problem, it just makes the true problem harder to discover.

Run-time errors can be your friend. If the function that uses this bit of code isn't giving you the desired behavior but there's a run-time error, the error will give you a line number where you can start troubleshooting. If you're not getting the desired behavior and there are no run-time errors, you're at square one.
In response to Forum_account
What sort of serious problem do you have in mind and how might you solve it? Just wondering.
In response to Vermolius
Vermolius wrote:
What sort of serious problem do you have in mind and how might you solve it? Just wondering.

Here are two examples of reasonable looking code that doesn't work. In both cases there are no run-time errors.

These examples let players place bombs on the ground. Bombs are placed in front of the player but only if that tile is non-dense.

Example 1:
mob
verb
drop_bomb()
var/turf/t = get_step(dir, src)
if(t && !t.density)
new /obj/bomb(t)


Example 2:
obj/bomb
proc
place()
var/turf/t = get_step(src, dir)
if(t && !t.density)
loc = t

mob
var
list/bombs = list()
verb
drop_bomb(obj/bomb/b in bombs)
bombs -= b
b.place()
Login()
. = ..()
bombs += new /obj/bomb()


If you run either of these examples and use the "drop bomb" verb, no bomb will be placed on the ground. If you imagine that this code is part of a game with 2000 other lines of code, you'd have no idea where to start looking to find the problem. It could be one of many things:
• Is the player somehow out of bombs?
• Is turf.Enter() not allowing the bomb to enter?
• Is the bomb's icon/icon_state incorrect?
• Is there another drop_bomb command that's getting called instead?

The actual problem is that get_step is returning null. Since you're checking if(t && !t.density), the bomb isn't placed if t is null. In the first example the arguments are in the wrong order, it should be get_step(src, dir). In the second example, the wrong atom is being used to provide the arguments to get_step, it should be get_step(usr, usr.dir) <small>(or you can pass the mob placing the bomb as an argument if you're paranoid about someone seeing "usr" in your code)</small>.

Any place where you are dealing with multiple atoms and call get_step, you might accidentally use the wrong one as the argument. Getting null back from get_step could be a sign that you screwed up the arguments, but if you hide that run-time error you're not going to see that sign and you might suspect the problem is somewhere else in your code.
In response to Forum_account
In both of those scenario's the programmer has been an idiot. So, you suggest that we leave out checking for the turf to exist, which allows players to cause runtimes when they try to interact with a nonexistent turf (the edge of the map) just in case we've put our arguments in the wrong order or if we've used the wrong atom somewhere.

In other terms, we leave in a case that causes gameplay issues, because we are paranoid that we will hide a runtime we're expecting? Even in many many thousands of lines of code it would be simple to trace the issue back, even without a runtime error. This is why you take the time to compile and test your code at intermediate steps and not after you've completed everything. I just don't see the merit in leaving in game errors to save yourself a few moments when tracing issues that exist rarely.

I suppose if you prefer to tell players not to drop bombs off the map because it causes runtimes instead of changing your code to handle that case, that's your prerogative. Neither of the cases you mentioned were 'serious' issues. Besides, the runtime you get doesn't point directly to the problem either, you still have to trace it back. I consider this moot.
In response to Vermolius
Vermolius wrote:
In both of those scenario's the programmer has been an idiot.

If you'd call a programmer an idiot for mixing up the order of arguments, what would you call someone who puts an apostrophe in the plural form of "scenario"?

My two examples were both examples of honest mistakes. Everyone makes them, even you ([link]).

So, you suggest that we leave out checking for the turf to exist, which allows players to cause runtimes when they try to interact with a nonexistent turf (the edge of the map) just in case we've put our arguments in the wrong order or if we've used the wrong atom somewhere.
In other terms, we leave in a case that causes gameplay issues, because we are paranoid that we will hide a runtime we're expecting?

In my examples, dropping bombs off the edge of the map is not a problem. The arguments to get_step are reversed so it's not possible to drop bombs at all. This is a more critical problem that supercedes the first. In actuality, what you're doing would be fixing a problem that doesn't exist and covering up one that does.

I suggest that you fix problems as you encounter them. Preemptively fixing an error can hide other problems. This is especially important when offering code as help to someone else since you don't know what the rest of the code looks like. If the code you give someone causes an error, let them figure out why. If they can't figure it out, they know where the forum is.

You make it sound like a bad thing that someone would take some precaution just in case they made a mistake.

This is why you take the time to compile and test your code at intermediate steps and not after you've completed everything

This is a precaution that you take just in case you made a mistake.

Even in many many thousands of lines of code it would be simple to trace the issue back, even without a runtime error.

I mentioned several other bits of code that you might suspect to cause the problem given the observed behavior. The problem isn't impossible to track down, but it's not unreasonable to think that you might spend 15 minutes looking in the wrong place before finding the problem.

The run-time error would have been on the line "if(!t.density)". This puts you in the three line proc that contains the problem. You still have to figure out why t is null and how to fix it, but your starting point becomes a three line proc instead of a 2000 line program.

Neither of the cases you mentioned were 'serious' issues.

What issue is more serious than your code not doing what you want it to do?
In response to Forum_account
Forum_account wrote:
Vermolius wrote:
In both of those scenario's the programmer has been an idiot.

If you'd call a programmer an idiot for mixing up the order of arguments, what would you call someone who puts an apostrophe in the plural form of "scenario"?

Haha, an idiot. ;) I'm not outside admitting fault.. I've been adding apostrophes in plurality a lot lately. >.>

My two examples were both examples of honest mistakes. Everyone makes them, even you ([link]).

Dig something up from ten years ago, why don't you. How wise of you to make Forum_account to hide your past. I guess I'll go and register myself a new account, so people can't check if I was perfect when I was 13.

In my examples, dropping bombs off the edge of the map is not a problem. The arguments to get_step are reversed so it's not possible to drop bombs at all. This is a more critical problem that supercedes the first. In actuality, what you're doing would be fixing a problem that doesn't exist and covering up one that does.

Yes, and your argument is that what I've checked for isn't a problem because you said so. Thereby, I can defend myself via magical realism as well, the programmer hasn't flipped the arguments nor used the wrong atom, your scenarios are no longer a problem. See how far that got us?

I suggest that you fix problems as you encounter them. Preemptively fixing an error can hide other problems. This is especially important when offering code as help to someone else since you don't know what the rest of the code looks like. If the code you give someone causes an error, let them figure out why. If they can't figure it out, they know where the forum is.

Even then, you'll eventually fix the issue, which will hide potential runtimes which, in turn, will put you right back at what you're saying people shouldn't do.

You make it sound like a bad thing that someone would take some precaution just in case they made a mistake.

No, I'm saying that you shouldn't leave your game broken on the off chance that you will make a mistake.

This is a precaution that you take just in case you made a mistake.

Right, and it helps minimize idiocy errors.

I mentioned several other bits of code that you might suspect to cause the problem given the observed behavior. The problem isn't impossible to track down, but it's not unreasonable to think that you might spend 15 minutes looking in the wrong place before finding the problem.

The run-time error would have been on the line "if(!t.density)". This puts you in the three line proc that contains the problem. You still have to figure out why t is null and how to fix it, but your starting point becomes a three line proc instead of a 2000 line program.

In your given cases. You still have to trace it out if it happens to be an issue with the other suspect areas.

What issue is more serious than your code not doing what you want it to do?

Your code crashing when you already knew how to fix it. What is stopping you from putting in an else with some debug logging information in it? Rather than relying on a runtime.

var/turf/theTurf = get_step(src, dir)
if(theTurf) // You also want to make sure there is a turf before you try to do anything with it.
if(theTurf.density)
// code
else
world.log << "[__FILE__]:[__LINE__]:error: turf expected, found null."
world.log << "\t src.dir: [src.dir]"
world.log << "\t src.loc: [src.loc] [(src.loc) ? "- [src.loc.x],[src.loc.y],[src.loc.z]" : ""]"
world.log << "\t max-coords: world.maxx, world.maxy, world.maxz"


This keeps us from getting runtimes for dropping bombs off the map and allows us to give ourselves debugging information. I've added details such that we might notice quickly whether or not the log was added due to a player dropping the bombs off the map. We could write the debugging output however we wanted.