-
Notifications
You must be signed in to change notification settings - Fork 42
AINavData
DummkopfOfHachtenduden edited this page Sep 25, 2023
·
12 revisions
// Header
1 byte version // expecting 1
4 uint simpleDungeonDataOffset
//AI_NAVIGATION Data
//CRefDungeon
2 ushort regionID
4 uint blockCount
for (int i = 0; i < blockCount; i++)
{
//CRefBlock
4 uint block.Index
4 uint block.CellCount // number of refCells in this block
4 uint block.EdgeCount // number of refEdges in this block
// CellLookupTable
// A table that when given a start and goal cell returns the index of the edge that should be used in order to reach the goal.
for(int goalCellID = 0; goalCellID < cellCount; goalCellID++)
{
for(int startCellID = 0; startCellID < cellCount; startCellID++)
{
2 short refEdgeIndex0; // refEdge to use when pathing forwards (start cell to goal cell)
2 short refEdgeIndex1; // refEdge to use when pathing backwards (goal cell to start cell)
}
}
// Links
4 uint linkCount
for (int i = 0; i < linkCount; i++)
{
4 uint link.ID // same as CellID
2 ushort link.CellID
2 ushort link.LinkedObjID // the other block
2 ushort link.LinkedObjRefEdgeIndex // a global edge of the other block
}
}
// BlockLookupTable
// A table that when given a start and goal block returns the index of the cell that should be used as subgoal in order to reach the actual goal.
for(int goalBlockID = 0; goalBlockID < blockCount; goalBlockID++)
{
for(int startBlockID = 0; startBlockID < blockCount; startBlockID++)
{
2 short refCellID // the memory for this is not zeroed and may contain garbage where startBlockID == goalBlockID which are invalid paths anyway.
}
}
4 uint int0 // expecting 0
//SimpleDungeonData
//simpleDungeonDataOffset will get you here
2 ushort regionID // yes twice
4 uint blockCount
for (uint i = 0; i < blockCount; i++)
{
4 uint edgeCount
for (uint i = 0; i < edgeCount; i++)
{
12 Vector3 edgeCenter
}
}
4 uint int1 // expecting 0
Some RefBlocks in AINavData may have be computed based on simplified mesh versions resulting in a mismatch of cell indices if you use the original mesh. This has been the major reason why this format took so long to figure out in the fist place. 😄
The simplified mesh is a retriangulated version of the original with only the most important points and some additional Steiner points. The actual algorithm is unknown to me but you may reverse engineer it at vsro_client.sub_0044BF10. It's also possible to patch the client into dumping these as the simplification code is still included despite not being used there.
Unsmoothed paths generated with AINavData.