The online racing simulator
Explain
(18 posts, started )
Explain
if ((MCI.Info[i].Node >= 731) && ((MCI.Info[i].X / 196608) <= -203) && ((MCI.Info[i].Y / 196608) <= -63) && ((MCI.Info[i].Y / 196608) >= -147))
{

Please someone explainme that please. There i have X and Y but in another location i only have:

if ((MCI.Info[i].Node >= 65) && (MCI.Info[i].Node < 105))
{

I want to know what means that lines please.
If I remember this correctly, positioning in LFS is like this.

65536 = 1 metre
65536 * 3 = 196608.

posX / 196608 => Change by 1 means that a car has changed position by 3 meters in direction of X.
From the MCI packet, it is calling three different bits of data. The first is Node, the second and third are the X and Y.

Nodes are boxes laid out on the track that tell information about the track. For example, it gives information about direction, ensuring that the client is going the correct direction, and position. Node numbers get higher the further into the lap you get, this allows the LFS engine a very quick way to keep track of who is in front while on the same lap. As a higher number means they are further into the lap, it also means that the highest number has compleated that lap the most. In the case of a person being on the lead lap, and then having the highest node number, that person is in first. It's actually a very simple sorting algorithm to implement.

Now the second and third items that it takes from the MCI packets are also pretty interesting in that it provides information as to physically where they are in the world. X & Y start from the center of the whole map, with the X axis laying west (negative) to east (positive), and the Y axis providing north (positive) and south (negative) data on any object as it relates to the center of the map. But that's not all that is interesting about the X and Y information as it's format is not as one would expect. A value of 65536 (X), 65536 (Y) is saying that the object is 1 meter east (X) and 1 meter north (Y) of the center. As LFS is a native 32 bit game, and the base unit of measurement is a meter but that meter takes up 16 bits all by it's self, and the fact that we can have both positive and negative values we can assume that a 32 bit signed integer is provides the boundary of the track's world is 32,767 meters and -32,767 meters giving us a total area of about 40.7221825 square miles, or 65.536 square kilometers (I know, you did not see that one coming did ya!). Simply put ... The tracks could be HUGE!

Hope that helps with understanding what you're looking at. (I guess I should / someone should add this information to the LFSManual / LFS Wiki.
Something I just noticed ... I could fit my entire town into a LFS track if I could figure out it's format. My town (Levittown) is 6.9 sq mi (17.8 km²), I could, in fact fit it, and my neighboring town (Wantagh) 4.1 sq mi (10.7 km²) without running over the limit. It's aberration would be WL (For Wantagh-Levittown) and I could make race tracks around my town . That would be kinda cool too, as there are some great streets around here that would make an awesome track, huh. Now if only Eric would make an ambulance car model and put that into the game, I could use the track as a training tool also for the Volunteer Ambulance Corp that I'm also a member of! I wonder how much data I can pull from Google maps about the streets in my town. If I could get each streets coords, I'm sure I could some how put this into an LFS track.
How very interesting Dygear

Anyway, a slight warning, in the new test patch using open configs lfs does not send any node lap packets. Therefore anything relying on nodes might not fully work.
Isn't the area a LFS track could have actually much bigger?

1 metre = 65 536
32 bit signed int = 2^31 = 2 147 483 648
2 147 483 658 / 65 536 = 32 768
In both directions = 32 768 * 2 - 1 (zero is not pos or neg) = 65 535 meters.
65 535 ^ 2 ~ 4.3 e9 m2 ~ 4 300 km2?

( I had almost no sleep in like last 30 hrs, so feel free to tell me how big a BS I just wrote)
Quote from Dygear :Nodes are boxes laid out on the track that tell information about the track. For example, it gives information about direction, ensuring that the client is going the correct direction, and position. Node numbers get higher the further into the lap you get, this allows the LFS engine a very quick way to keep track of who is in front while on the same lap. As a higher number means they are further into the lap, it also means that the highest number has compleated that lap the most. In the case of a person being on the lead lap, and then having the highest node number, that person is in first. It's actually a very simple sorting algorithm to implement.

Just for clarification:
This is absolutely true in itself, but You'll have to consider that finishline usually is not the first node of the track.
In Westhill e.g. the finishline is around node 600 plus some spare nodes out of about 650 (more or less).

So, if the finishline was e.g. node 627 out of 647, then a higher nodenumber while being on the same lap would only mean further progress, if the higher one was less than 627 or the lower one was above 627
Okey so
if ((MCI.Info[i].Node >= 731) && ((MCI.Info[i].X / 196608) <= -203) && ((MCI.Info[i].Y / 196608) <= -63) && ((MCI.Info[i].Y / 196608) >= -147))
{

This is: (MCI.Info[i].Y / 196608) <= -63)

Y = 196608, but for what is <= -63 ?
That statement is true if car "i" is
- Past node 730
- Less than 610 meters South of the centre of the track
- Between 189 and 441 meters West of the centre of the track

If you have problems understanding these conditional statements, perhaps you should do some reading about programming basics first, it's essential to have them...
Quote from MadCatX :Isn't the area a LFS track could have actually much bigger?

1 metre = 65 536
32 bit signed int = 2^31 = 2 147 483 648
2 147 483 658 / 65 536 = 32 768

16bits = 65536;
31bits = 2147483648 (31 because 1 bit is used for the sign).

65536 = 1 Meter;
2147483648 / 65536 = 32,768 meters

1 mile = 1,609.344 meters
1 kilometer = 1,000 meters

32,768 meters / 1,609.344 = 20.3610912 miles.
32,768 meters / 1,000 = 32.768 kilometers.

20.3610912 * 2 = 40.7221824 miles square
32.768 * 2 = 65.536 kilometers square

Quote from MadCatX :I had almost no sleep in like last 30 hrs, so feel free to tell me how big a BS I just wrote

Get some sleep mate, I'm going to do the same.

Quote from avetere :You'll have to consider that finishline usually is not the first node of the track.

Yeah, I could not think what kind of shenanigans they had in mind with that one. I mean really, what was the point of this? But yes, this is correct, 0 is not always the start line, unfortunately. I'm tempted to submit this as a bug, so we can at least get a reason why this happened.
Sorry to be so pedantic, but an area of a square is A = a*a, not a*2
Quote from MadCatX :Sorry to be so pedantic, but an area of a square is A = a*a, not a*2

Yeah ... Ok, I see you're point now, lol! Sleep is a good idea, but the girlfriend is apparently coming over, as I can I think hear her ascend the stairs as I type this message. So I'm sure that I'll be going to bed soon, although I don't think I'll be getting to sleep. But after that, I'll watch the WWDC video on Engadget and then I hope pass out for quite a while. After that I'll go to the ambulance corp (I'm on duty) and I'll ponder this question again between the gun shot wounds, people getting hit by cars, and the babies being borne.

[EDIT] Wait a second, 1658.29614 square miles is larger then the COUNTY I live in. Huh ... the possibilities!
Quote from Dygear : I'm tempted to submit this as a bug, so we can at least get a reason why this happened.

Yeah, I was about ask that too, especially since nodes aren't shared between configs (which would at least have been an explanation).
Okey so and if i want to stop in a place and appaer something, how should i make?
It's not that hard to figure out, you just need to check for coordinates and speed. The logic goes like this:


if (carAtCoords(carID) && carIsStopped(carID)) {
//Display something or whatever
}

bool carAtCoords(int i)
{
if (MCI.Info[i].X == X_POSITION && MCI.Info[i].Y == Y_POSITION)
return true;
else
return false;
}

bool carIsStopped(int i)
{
int currentX = MCI.Info[i].X;
int currentY = MCI.Info[i].Y;

if (currentX == prevX && currentY == prevY)
return true;
else
return false;
}

where X_POSITION and Y_POSITION are the coordinates you want a car to stop at. You'll also need to store cars' positions and compare these to their current positions. If the position of a car is the same in the previous and current update, then the car isn't moving.
Quote from MadCatX :It's not that hard to figure out, you just need to check for coordinates and speed. The logic goes like this:


if (carAtCoords(carID) && carIsStopped(carID)) {
//Display something or whatever
}

bool carAtCoords(int i)
{
if (MCI.Info[i].X == X_POSITION && MCI.Info[i].Y == Y_POSITION)
return true;
else
return false;
}

bool carIsStopped(int i)
{
int currentX = MCI.Info[i].X;
int currentY = MCI.Info[i].Y;

if (currentX == prevX && currentY == prevY)
return true;
else
return false;
}

where X_POSITION and Y_POSITION are the coordinates you want a car to stop at. You'll also need to store cars' positions and compare these to their current positions. If the position of a car is the same in the previous and current update, then the car isn't moving.

Gah, sorry, but this is a pet hate of mine. This function...

bool carAtCoords(int i)
{
if (MCI.Info[i].X == X_POSITION && MCI.Info[i].Y == Y_POSITION)
return true;
else
return false;
}

should really be...

bool carAtCoords(int i)
{
return MCI.Info[i].X == X_POSITION && MCI.Info[i].Y == Y_POSITION;
}

and

bool carIsStopped(int i)
{
int currentX = MCI.Info[i].X;
int currentY = MCI.Info[i].Y;

if (currentX == prevX && currentY == prevY)
return true;
else
return false;
}

should be

bool carIsStopped(int i)
{
int currentX = MCI.Info[i].X;
int currentY = MCI.Info[i].Y;

return currentX == prevX && currentY == prevY;
}

I know that MadCatX probably already knows this, but I always see stuff like this and it deeply annoys me. The result of an expression can be passed around just like any other value. You don't need to explicitly return true and false, the result of the expression is a boolean anyway.

Anyway code-rant over.
If I were to use that code in my app, I'd go even further to the land of less readable code (OK, at least the first function there's actually no difference) and use something like


bool carIsStopped(int i)
{
return (MCI.Info[i].X == prevX) && (MCI.Info[i].Y == prevY);
}

but since impersona appears to be fighting a bit with the programming basics, I for once decided to use a code that's easy to read for everyone...
However it's good you pointed that out

BTW I dunno how about .NET and MSIL JIT compiler, but I'm quite sure that a modern C++ compiler would produce the same assembler code for both my and DarkTimes' code...
Yeah im learning c++ in school and having a good progress in INSIM.

But where should i put bool and if caratcords?
-
(impresora) DELETED by Dygear : Spam
-
(impresora) DELETED by Dygear : Spam

Explain
(18 posts, started )
FGED GREDG RDFGDR GSFDG