natives
natives copied to clipboard
Updating node documentation
Been doing some node research. Here are the findings.
Need to validate the forward and backward lanes before merging. I've made an assumption about which is which.
Validated. Green is src, red is dest. LanesBackward relates to dest > src lanes.
Example of bidirectional road with a width
set (gap in the middle)
Validated. Green is src, red is dest. LanesBackward relates to dest > src lanes.
I had the fuckers mixed up. Validated it's wrong lmao
Fixed and validated src and dest nodes order.
Blue is the node I'm passing to GET_CLOSEST_ROAD
Green is src
Red is dest
The purple line is the node heading though which is a bit weird, so maybe it's returning links connecting to the node in the opposite direction? Will check CW
Can confirm. src and dest were fine before. The node you're testing against is sometimes the src, sometimes the dest
Unsure that n
should be considered as such. It's only ever 1 in the rockstar scripts. In GTA IV it was 1 or 2 depending on the location of pos
I don't have much of CPathFind
documented, so these are my rough notes on this batch of natives. Unsure how valuable they will be to continue your research:
0x132F52BBA570FE92:
p3
looks like a node radius and is used to supplement n
, likely leading to your "A bit broken as it returns a random edge after n
" comment. For example, and using your naming convention, here is an outline of one of the distance checks:
if ((nodeForwardLanes + nodeBackwardLanes < n) || distance(node, linkedNode) <= p3)
closestDistance = rootManhattanDistance
else {
closestDistance = nodeManhattanDistance // (dy + dx) + (dz * 3.0)
...
}
0x80CA6A8B6C094CC4:
nodeType
looks like a bitfield/flag not an explicit type.
0x0568566ACBB5DEDC:
Some additional things to check:
0x10 -> Also used in interiors; 'Tunnels' may be a specific instance of this flag.
0x20 -> Maybe a combination of "Block If No Lanes" and "Narrowroad"? Grep script usage: iVar4 & 32 == 0 && iVar4 & 4 == 0?
0x100 -> Stop/TrafficLightStop
0x200 -> Intersection/Crosswalk
0x400 -> Water
If you are using Codewalker, here are the YndNode
mappings (I think):
0x1 = ((RawData.Flags0 & 8) != 0)
0x2 = ((RawData.Flags0 & 0x10) != 0)
0x4 = ((RawData.Flags0 & 0x20) != 0)
0x8 = ((RawData.Flags2 & 0x80) != 0)
0x10 = ((RawData.Flags3 & 1) != 0)
0x20 = ((RawData.Flags4 & 0x70) != 0)
0x40 = ((RawData.Flags2 & 0x40) != 0 && (RawData.Flags2 & 0x20) == 0)
0x80 = ((RawData.LinkCountFlags & 0x1) != 0)
0x100 = ((RawData.Flags1 & 0xF8) == 0x78)
0x200 = ((RawData.Flags1 & 0xF8) == 0x80)
0x400 = ((RawData.Flags2 & 0x20) != 0)
I don't have much of
CPathFind
documented, so these are my rough notes on this batch of natives. Unsure how valuable they will be to continue your research:0x132F52BBA570FE92:
p3
looks like a node radius and is used to supplementn
, likely leading to your "A bit broken as it returns a random edge aftern
" comment. For example, and using your naming convention, here is an outline of one of the distance checks:if ((nodeForwardLanes + nodeBackwardLanes < n) || distance(node, linkedNode) <= p3) closestDistance = rootManhattanDistance else { closestDistance = nodeManhattanDistance // (dy + dx) + (dz * 3.0) ... }
0x80CA6A8B6C094CC4:
nodeType
looks like a bitfield/flag not an explicit type.0x0568566ACBB5DEDC:
Some additional things to check:
0x10 -> Also used in interiors; 'Tunnels' may be a specific instance of this flag. 0x20 -> Maybe a combination of "Block If No Lanes" and "Narrowroad"? Grep script usage: iVar4 & 32 == 0 && iVar4 & 4 == 0? 0x100 -> Stop/TrafficLightStop 0x200 -> Intersection/Crosswalk 0x400 -> Water
If you are using Codewalker, here are the
YndNode
mappings (I think):0x1 = ((RawData.Flags0 & 8) != 0) 0x2 = ((RawData.Flags0 & 0x10) != 0) 0x4 = ((RawData.Flags0 & 0x20) != 0) 0x8 = ((RawData.Flags2 & 0x80) != 0) 0x10 = ((RawData.Flags3 & 1) != 0) 0x20 = ((RawData.Flags4 & 0x70) != 0) 0x40 = ((RawData.Flags2 & 0x40) != 0 && (RawData.Flags2 & 0x20) == 0) 0x80 = ((RawData.LinkCountFlags & 0x1) != 0) 0x100 = ((RawData.Flags1 & 0xF8) == 0x78) 0x200 = ((RawData.Flags1 & 0xF8) == 0x80) 0x400 = ((RawData.Flags2 & 0x20) != 0)
Thanks for replying. I've actually done a fair bit of extensive research on them that was never merged (need to touch base with dexy to figure out where it is). It was all figured out by cross referencing the incomplete paths.xml so the flags names should be accurate. Junction is also Flags2 & 4. I've yet to push that up. https://github.com/dexyfex/CodeWalker/pull/70/files
The flags
enum was figured out by cross referencing the node properties with this branch of codewalker.
Re. p3
. I'm not sure. It may be the minimum length of the edge. I'd need to do more testing. Rockstar never use it, it's always 0.0f
in their scripts.
Re. NodeType. I just copy pastad that from another native document. I've not put any research into it, but happy to do so. Rockstar do the following in their taxi script when the taxi is trying to find the point at the side of the road. So I think you could be right re. bitfield:
nodeType = 1;
if (!IsZoneSomething(pos))
{
nodeType = 9;
}
int IsZoneSomething(struct<3> Param0)
{
char* sVar0;
sVar0 = ZONE::GET_NAME_OF_ZONE(Param0);
if (((((((((((((((((((((((((((((((((((((((((((((MISC::ARE_STRINGS_EQUAL("SanAnd", sVar0) || MISC::ARE_STRINGS_EQUAL("Alamo", sVar0)) || MISC::ARE_STRINGS_EQUAL("ArmyB", sVar0)) || MISC::ARE_STRINGS_EQUAL("BhamCa", sVar0)) || MISC::ARE_STRINGS_EQUAL("Baytre", sVar0)) || MISC::ARE_STRINGS_EQUAL("BradT", sVar0)) || MISC::ARE_STRINGS_EQUAL("BradP", sVar0)) || MISC::ARE_STRINGS_EQUAL("CANNY", sVar0)) || MISC::ARE_STRINGS_EQUAL("CCreak", sVar0)) || MISC::ARE_STRINGS_EQUAL("ChamH", sVar0)) || MISC::ARE_STRINGS_EQUAL("CHU", sVar0)) || MISC::ARE_STRINGS_EQUAL("COSI", sVar0)) || MISC::ARE_STRINGS_EQUAL("CMSW", sVar0)) || MISC::ARE_STRINGS_EQUAL("Cypre", sVar0)) || MISC::ARE_STRINGS_EQUAL("Desrt", sVar0)) || MISC::ARE_STRINGS_EQUAL("ELGorl", sVar0)) || MISC::ARE_STRINGS_EQUAL("Galli", sVar0)) || MISC::ARE_STRINGS_EQUAL("Galfish", sVar0)) || MISC::ARE_STRINGS_EQUAL("Harmo", sVar0)) || MISC::ARE_STRINGS_EQUAL("HumLab", sVar0)) || MISC::ARE_STRINGS_EQUAL("Jail", sVar0)) || MISC::ARE_STRINGS_EQUAL("LAct", sVar0)) || MISC::ARE_STRINGS_EQUAL("LDam", sVar0)) || MISC::ARE_STRINGS_EQUAL("Lago", sVar0)) || MISC::ARE_STRINGS_EQUAL("MTChil", sVar0)) || MISC::ARE_STRINGS_EQUAL("MTJose", sVar0)) || MISC::ARE_STRINGS_EQUAL("MTGordo", sVar0)) || MISC::ARE_STRINGS_EQUAL("NCHU", sVar0)) || MISC::ARE_STRINGS_EQUAL("Oceana", sVar0)) || MISC::ARE_STRINGS_EQUAL("Palmpow", sVar0)) || MISC::ARE_STRINGS_EQUAL("PBluff", sVar0)) || MISC::ARE_STRINGS_EQUAL("Paleto", sVar0)) || MISC::ARE_STRINGS_EQUAL("PalCov", sVar0)) || MISC::ARE_STRINGS_EQUAL("PalFor", sVar0)) || MISC::ARE_STRINGS_EQUAL("PalHigh", sVar0)) || MISC::ARE_STRINGS_EQUAL("RTRAK", sVar0)) || MISC::ARE_STRINGS_EQUAL("Rancho", sVar0)) || MISC::ARE_STRINGS_EQUAL("SANDY", sVar0)) || MISC::ARE_STRINGS_EQUAL("TongvaH", sVar0)) || MISC::ARE_STRINGS_EQUAL("TongvaV", sVar0)) || MISC::ARE_STRINGS_EQUAL("Zenora", sVar0)) || MISC::ARE_STRINGS_EQUAL("Slab", sVar0)) || MISC::ARE_STRINGS_EQUAL("WindF", sVar0)) || MISC::ARE_STRINGS_EQUAL("Zancudo", sVar0)) || MISC::ARE_STRINGS_EQUAL("SanChia", sVar0)) || MISC::ARE_STRINGS_EQUAL("zQ_UAR", sVar0))
{
return 1;
}
return 0;
}
0x132F52BBA570FE92: p3 looks like a node radius and is used to supplement n, likely leading to your "A bit broken as it returns a random edge after n" comment. For example, and using your naming convention, here is an outline of one of the distance checks:
if ((nodeForwardLanes + nodeBackwardLanes < n) || distance(node, linkedNode) <= p3) closestDistance = rootManhattanDistance else { closestDistance = nodeManhattanDistance // (dy + dx) + (dz * 3.0) ... }
Interesting... 🤔
@gottfriedleibniz here are some examples of enumeraing "n
" until the response is 0
(p3 = 0.0f
). To me it looks like it gives relating nodes, like upcoming junctions/joins etc. What do you think?
But it also returns random ones:
@gottfriedleibniz I tried out your theory during lunch. You're bang on the money. p3
is minEdgeLength
and n
is minLaneCount
. Shall post the evidence after work.
At the bottom of the screen you see my characters heading * 0.1
. In the middle of the edge is the edge length. As you can see when the heading below the length of the edge, the edge is returned. When the heading goes above it's no longer valid and is not returned. Proving that p3
is minLength
.
In this one the white number is n
. The red number is forwardLanes + backwardLanes
. As you can see they match. A lane will also be returned if it has 4 total lanes, and I've entered n = 2
. Proving that n
is actually minLanes
@gottfriedleibniz started work on the nodeType
bitfield if you're interested. 0x1
is AllowDisabled
, 0x2
seems unused, and 0x4
excludes Junction
, LeftTurnOnly
, Stop
, SlipRoad
as well as edge Merges/Splits including Shortcut
splits. (Maybe secondary nodes?) A very useful flag!
Example of 0x4
is below. Green = inclusive, Red = Excluded
@AvarianKnight updated as per comments
I'm going to be updating the other path natives with the search flags. Do you want me to do that in this PR?