Sorry for digging this up.
I wanna try to abuse this .nav files for NPC pathing but I did couldn't find any info on how to use get those zone info into amxx.
It been 8 years so idk if is there any info on this stuff?
I read ReGameDLL zBot but there is so much stuff I couldn't understand
Code:
void CNavArea::Load(SteamFile *file, unsigned int version)
{
// load ID
file->Read(&m_id, sizeof(unsigned int));
// update nextID to avoid collisions
if (m_id >= m_nextID)
m_nextID = m_id + 1;
// load attribute flags
file->Read(&m_attributeFlags, sizeof(unsigned char));
// load extent of area
file->Read(&m_extent, 6 * sizeof(float));
m_center.x = (m_extent.lo.x + m_extent.hi.x) / 2.0f;
m_center.y = (m_extent.lo.y + m_extent.hi.y) / 2.0f;
m_center.z = (m_extent.lo.z + m_extent.hi.z) / 2.0f;
// load heights of implicit corners
file->Read(&m_neZ, sizeof(float));
file->Read(&m_swZ, sizeof(float));
// load connections (IDs) to adjacent areas
// in the enum order NORTH, EAST, SOUTH, WEST
for (int d = 0; d < NUM_DIRECTIONS; d++)
{
// load number of connections for this direction
unsigned int count;
file->Read(&count, sizeof(unsigned int));
for (unsigned int i = 0; i < count; i++)
{
NavConnect connect;
file->Read(&connect.id, sizeof(unsigned int));
m_connect[d].push_back(connect);
}
}
// Load hiding spots
// load number of hiding spots
unsigned char hidingSpotCount = 0;
file->Read(&hidingSpotCount, sizeof(unsigned char));
if (version == 1)
{
// load simple vector array
Vector pos;
for (int h = 0; h < hidingSpotCount; h++)
{
file->Read(&pos, 3 * sizeof(float));
// create new hiding spot and put on master list
HidingSpot *spot = new HidingSpot(&pos, HidingSpot::IN_COVER);
m_hidingSpotList.push_back(spot);
}
}
else
{
// load HidingSpot objects for this area
for (int h = 0; h < hidingSpotCount; h++)
{
// create new hiding spot and put on master list
HidingSpot *spot = new HidingSpot;
spot->Load(file, version);
m_hidingSpotList.push_back(spot);
}
}
// Load number of approach areas
file->Read(&m_approachCount, sizeof(unsigned char));
// load approach area info (IDs)
unsigned char type = 0;
for (int a = 0; a < m_approachCount; a++)
{
file->Read(&m_approach[a].here.id, sizeof(unsigned int));
file->Read(&m_approach[a].prev.id, sizeof(unsigned int));
file->Read(&type, sizeof(unsigned char));
m_approach[a].prevToHereHow = (NavTraverseType)type;
file->Read(&m_approach[a].next.id, sizeof(unsigned int));
file->Read(&type, sizeof(unsigned char));
m_approach[a].hereToNextHow = (NavTraverseType)type;
}
// Load encounter paths for this area
unsigned int count;
file->Read(&count, sizeof(unsigned int));
if (version < 3)
{
// old data, read and discard
for (unsigned int e = 0; e < count; e++)
{
SpotEncounter encounter;
file->Read(&encounter.from.id, sizeof(unsigned int));
file->Read(&encounter.to.id, sizeof(unsigned int));
file->Read(&encounter.path.from.x, 3 * sizeof(float));
file->Read(&encounter.path.to.x, 3 * sizeof(float));
// read list of spots along this path
unsigned char spotCount = 0;
file->Read(&spotCount, sizeof(unsigned char));
for (int s = 0; s < spotCount; s++)
{
Vector pos;
file->Read(&pos, 3 * sizeof(float));
file->Read(&pos, sizeof(float));
}
}
return;
}
for (unsigned int e = 0; e < count; e++)
{
SpotEncounter encounter;
file->Read(&encounter.from.id, sizeof(unsigned int));
unsigned char dir = 0;
file->Read(&dir, sizeof(unsigned char));
encounter.fromDir = static_cast<NavDirType>(dir);
file->Read(&encounter.to.id, sizeof(unsigned int));
file->Read(&dir, sizeof(unsigned char));
encounter.toDir = static_cast<NavDirType>(dir);
// read list of spots along this path
unsigned char spotCount = 0;
file->Read(&spotCount, sizeof(unsigned char));
SpotOrder order;
for (int s = 0; s < spotCount; s++)
{
file->Read(&order.id, sizeof(unsigned int));
unsigned char t = 0;
file->Read(&t, sizeof(unsigned char));
order.t = float(t) / 255.0f;
encounter.spotList.push_back(order);
}
m_spotEncounterList.push_back(encounter);
}
if (version >= NAV_VERSION)
{
// Load Place data
PlaceDirectory::EntryType entry;
file->Read(&entry, sizeof(entry));
// convert entry to actual Place
SetPlace(placeDirectory.EntryToPlace(entry));
}
}
NavErrorType CNavArea::PostLoad()
{
NavErrorType error = NAV_OK;
// connect areas together
for (int d = 0; d < NUM_DIRECTIONS; d++)
{
for (auto& connect : m_connect[d])
{
auto id = connect.id;
connect.area = TheNavAreaGrid.GetNavAreaByID(id);
if (id && !connect.area)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Cannot connect Navigation Areas.\n");
error = NAV_CORRUPT_DATA;
}
}
}
// resolve approach area IDs
for (int a = 0; a < m_approachCount; a++)
{
m_approach[a].here.area = TheNavAreaGrid.GetNavAreaByID(m_approach[a].here.id);
if (m_approach[a].here.id && !m_approach[a].here.area)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Missing Approach Area (here).\n");
error = NAV_CORRUPT_DATA;
}
m_approach[a].prev.area = TheNavAreaGrid.GetNavAreaByID(m_approach[a].prev.id);
if (m_approach[a].prev.id && !m_approach[a].prev.area)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Missing Approach Area (prev).\n");
error = NAV_CORRUPT_DATA;
}
m_approach[a].next.area = TheNavAreaGrid.GetNavAreaByID(m_approach[a].next.id);
if (m_approach[a].next.id && !m_approach[a].next.area)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Missing Approach Area (next).\n");
error = NAV_CORRUPT_DATA;
}
}
// resolve spot encounter IDs
for (auto& spote : m_spotEncounterList)
{
spote.from.area = TheNavAreaGrid.GetNavAreaByID(spote.from.id);
if (!spote.from.area)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Missing \"from\" Navigation Area for Encounter Spot.\n");
error = NAV_CORRUPT_DATA;
}
spote.to.area = TheNavAreaGrid.GetNavAreaByID(spote.to.id);
if (!spote.to.area)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Missing \"to\" Navigation Area for Encounter Spot.\n");
error = NAV_CORRUPT_DATA;
}
if (spote.from.area && spote.to.area)
{
// compute path
float halfWidth;
ComputePortal(spote.to.area, spote.toDir, &spote.path.to, &halfWidth);
ComputePortal(spote.from.area, spote.fromDir, &spote.path.from, &halfWidth);
const float eyeHeight = HalfHumanHeight;
spote.path.from.z = spote.from.area->GetZ(&spote.path.from) + eyeHeight;
spote.path.to.z = spote.to.area->GetZ(&spote.path.to) + eyeHeight;
}
// resolve HidingSpot IDs
for (auto& order : spote.spotList)
{
order.spot = GetHidingSpotByID(order.id);
if (!order.spot)
{
CONSOLE_ECHO("ERROR: Corrupt navigation data. Missing Hiding Spot\n");
error = NAV_CORRUPT_DATA;
}
}
}
// build overlap list
// TODO: Optimize this
for (auto area : TheNavAreaList)
{
if (area == this)
continue;
if (IsOverlapping(area))
m_overlapList.push_back(area);
}
return error;
}
__________________