Two things about that section. First of all, you can't reliably compare two floats or doubles for equality. Second of all, it just prints a message, then moves on. Obviously it was supposed to contain a return.

For the original problem, I'll post a suggestion when I have had time to properly test what I have in mind. Unless someone posts a viable solution first. My general opinion is that do_trajectory() should report to the player then return, if any of arg2, arg3 or argument are not numbers. The general idea would go something like this:

This works because is_number would return false if any of the arguments are "inf". This would go below the one_argument lines, and before vx = atof( arg2 ) and friends. Then the erronous if-check with the float comparisons would simply be deleted.

Again, I don't have the opportunity to test it all properly just at this moment. So either someone else could do proper testing, or I'll do it later. Anyway, that's my personal opinion on how this should be fixed.

Looking over this thread again there seems to be a lot of uncertainty about when and why the spacecode deals with decimal numbers and not. Now, it's very important to understand how the space code works, because I wouldn't want to see any future fixes that makes a bigger mess out of the space code than there already is. So I'll do my best to explain some of these things.

From a player's point of view all coordinates are whole numbers. They never see any decimal parts at all. This is why it's perfectly fine to only accept integer type numbers from player input. Typically the decimal part is truncated like this:

ch_printf( ch, "Coordinates: %.0f %.0f %.0f", x, y, z );

But they ARE floats internally, and they must remain so for the vector calculations to work. Here's an exerpt from ship_data:

As has been mentioned the variable names are a bit obscure. So: vx, vy, vz represents the current position of the ship. I suppose the 'v' is supposed to mean vector or something. hx, hy, hz represents the heading (direction). jx, jy, jz are used for hyperjumps, and represents the position you'll arrive at in the target starsystem.

Note that there is no vector for "destination" within your current starsystem. So when you use the course/trajectory command(s) it is the heading vector that is altered. This is why you can't use integers. Because whenever the move_ships() function calculates the new position of your ship, it uses the heading and the speed. Now, if the heading was stored as integers you would lose much precision, and you'd be unlikely to actually end up where you wanted to go. In short, the code doesn't move you towards a destination, it moves you along a vector.

There are many problems already with the vector math used in the space code. In some cases the formulas are simply wrong (like in most distance calculations). And there are inconsistencies. Missile movement doesn't work the same way as ship movement, for instance, although it would likely simplify many things if they did.

Back to user input/output. There is no real reason why a player should be able to use decimal numbers. In all cases I can think of the code operates with a certain distance. For instance you start to orbit a planet when you get at a distance of 10 or less. You can land when you're within 200. Etc. Furthermore you'll always head straight for a planet if you feed its coordinates to do_trajectory(), because planets store their coordinates using integers (which, again, wouldn't be my first choice). The only time the player would actually need such precision is to ram another ship (because they have positions in floats, remember?). But in the case of SWRFUSS ship collision has been commented out anyway. And if you wanted to allow decimal input, you'd also have to display decimal output to the player. Wouldn't make sense otherwise.

I hope that clarifies some things. Or perhaps I've just made it look even more obscure. *shrug*

KayleOff the Edge of the MapGroupAdministratorsPosts1,195JoinedMar 21, 2006

Made perfect sense to me. Well, given your explanation of how things work, I'm going to have to re-read the bug and see what kind of fix I can come up with, once I get SWRFUSS up to gcc 4.3.x specs thanks you your lovely contribution of the const fixedness for it.

My guess, for why they used floats is that they liked the idea that the numbers could get extremly massive, coordiante wise in space. I think 2bil is enough though. Why not just swich them all to integers and keep checks to make sure they never go past the max?

KayleOff the Edge of the MapGroupAdministratorsPosts1,195JoinedMar 21, 2006

From my understanding of Caius's post, they used floats for precision, not the size of the number. And looking over a couple of the other posts, I think an overall cleanup of the space system might be in order. But, I'm still sorting through the SWR and SWFotE forums and fixlists figuring out what has, and hasn't been fixed. I'll start a thread detailing what still needs fixed, and what not when I finish.

All right. I have another suggestion. Darrik mentioned the INFINITY and NAN defines. Checking for inf works this way. Checking against NAN, however, did not. But we can catch both with the isfinite() macro in math.h:

Now the vx, vy and vz variables remain floats, and we ensure that the player can't use "inf" or "nan" in the arguments. I mentioned earlier that it's little point allowing the player to give decimal input. But it doesn't hurt either, and this way we get a very simple solution to this mess.

We may want to do a similar check in do_calculate(). Though that function stores the coordinates provided by the player as integers, as someone else mentioned.

All right. I have another suggestion. Darrik mentioned the INFINITY and NAN defines. Checking for inf works this way. Checking against NAN, however, did not. But we can catch both with the isfinite() macro in math.h:

Now the vx, vy and vz variables remain floats, and we ensure that the player can't use "inf" or "nan" in the arguments. I mentioned earlier that it's little point allowing the player to give decimal input. But it doesn't hurt either, and this way we get a very simple solution to this mess.

We may want to do a similar check in do_calculate(). Though that function stores the coordinates provided by the player as integers, as someone else mentioned.

I tried to apply your fix but its complaining about an undefined reference to isfinite in space.c, and math.h is defined.

Upon closer inspection it turns out isfinite() is from the C99 standard. If you compile with g++ it will work. If you compile as C you will have to use the C99 standard by adding -std=c99 to the compiler.

In short, this isn't a backwards compatible solution. On the other hand, the const-fixed swrfuss I gave Kayle is compiled with g++, so it works. Actually it won't compile as C. But neither will SmaugFUSS, due to the use of overloaded functions. So I guess there's not much point in insisting on using old standards anymore, since that train has left the station already.

Upon closer inspection it turns out isfinite() is from the C99 standard. If you compile with g++ it will work. If you compile as C you will have to use the C99 standard by adding -std=c99 to the compiler.

In short, this isn't a backwards compatible solution. On the other hand, the const-fixed swrfuss I gave Kayle is compiled with g++, so it works. Actually it won't compile as C. But neither will SmaugFUSS, due to the use of overloaded functions. So I guess there's not much point in insisting on using old standards anymore, since that train has left the station already.

But I leave that to Kayle to decide what to do.

I never argued anything about using any old standards. I pointed out that your fix didn't work for me...

It is my belief that SWR only uses floats for precision in code calculations. No where have I ever once used or heard of anyone else using floating points in their commands like course or calculate. Furthermore, players will never know the decimal values of their position because the various commands for displaying that info do not use floating points (specifically, they utilize %.0f where there are floating point data types which -- if I'm not mistaken -- hides all decimal values.) And yet further more, celestial bodies (planets, suns, starsystems) do not have floating point positions; only integer positions. And lastly, the scale that the stock space system uses makes any distance less than 1.0 unimportant at best -- even the largest ships generally travel at at least 20 units per space pulse. Ultimately, there will never be a need for anyone to input floating point coordinates with the stock space system.

If all that doesn't drive a nail in the coffin, I don't know what will.