示例#1
0
//===========================================================================
// allocate memory and read a lump of a AAS file
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
char *AAS_LoadAASLump( FILE *fp, int offset, int length, void *buf ) {
	if ( !length ) {
		printf( "lump size 0\n" );
		return buf;
	} //end if
	  //seek to the data
	if ( fseek( fp, offset, SEEK_SET ) ) {
		AAS_Error( "can't seek to lump\n" );
		AAS_DumpAASData();
		fclose( fp );
		return 0;
	} //end if
	  //allocate memory
	if ( !buf ) {
		buf = (void *) GetClearedMemory( length );
	}
	//read the data
	if ( fread( (char *) buf, 1, length, fp ) != length ) {
		AAS_Error( "can't read lump\n" );
		FreeMemory( buf );
		AAS_DumpAASData();
		fclose( fp );
		return NULL;
	} //end if
	return buf;
} //end of the function AAS_LoadAASLump
示例#2
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_UpdatePortal(int areanum, int clusternum)
{
	int portalnum;
	aas_portal_t *portal;
	aas_cluster_t *cluster;

	//find the portal of the area
	for (portalnum = 1; portalnum < aasworld.numportals; portalnum++)
	{
		if (aasworld.portals[portalnum].areanum == areanum) break;
	} //end for
	//
	if (portalnum == aasworld.numportals)
	{
		AAS_Error("no portal of area %d", areanum);
		return qtrue;
	} //end if
	//
	portal = &aasworld.portals[portalnum];
	//if the portal is already fully updated
	if (portal->frontcluster == clusternum) return qtrue;
	if (portal->backcluster == clusternum) return qtrue;
	//if the portal has no front cluster yet
	if (!portal->frontcluster)
	{
		portal->frontcluster = clusternum;
	} //end if
	//if the portal has no back cluster yet
	else if (!portal->backcluster)
	{
		portal->backcluster = clusternum;
	} //end else if
	else
	{
		//remove the cluster portal flag contents
		aasworld.areasettings[areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL;
		Log_Write("portal area %d is seperating more than two clusters\r\n", areanum);
		return qfalse;
	} //end else
	if (aasworld.portalindexsize >= AAS_MAX_PORTALINDEXSIZE)
	{
		AAS_Error("AAS_MAX_PORTALINDEXSIZE");
		return qtrue;
	} //end if
	//set the area cluster number to the negative portal number
	aasworld.areasettings[areanum].cluster = -portalnum;
	//add the portal to the cluster using the portal index
	cluster = &aasworld.clusters[clusternum];
	aasworld.portalindex[cluster->firstportal + cluster->numportals] = portalnum;
	aasworld.portalindexsize++;
	cluster->numportals++;
	return qtrue;
} //end of the function AAS_UpdatePortal
示例#3
0
// Ridah, multiple AAS worlds
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AAS_SetCurrentWorld( int index ) {
	if ( index >= MAX_AAS_WORLDS || index < 0 ) {
		AAS_Error( "AAS_SetCurrentWorld: index out of range\n" );
		return;
	}

	// set the current world pointer
	aasworld = &aasworlds[index];
}
示例#4
0
//===========================================================================
//	writes the current route-table data to a .rtb file in tne maps folder
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AAS_RT_WriteRouteTable()
{
	int            ident, version;
	unsigned short crc_aas;
	fileHandle_t   fp;
	char           filename[MAX_QPATH];

	// open the file for writing
	Com_sprintf(filename, MAX_QPATH, "maps/%s.rtb", (*aasworld).mapname);
	botimport.Print(PRT_MESSAGE, "\nsaving route-table to %s\n", filename);
	botimport.FS_FOpenFile(filename, &fp, FS_WRITE);
	if (!fp)
	{
		AAS_Error("Unable to open file: %s\n", filename);
		return;
	}

	// ident
	ident = LittleLong(RTBID);
	botimport.FS_Write(&ident, sizeof(ident), fp);

	// version
	version = LittleLong(RTBVERSION);
	botimport.FS_Write(&version, sizeof(version), fp);

	// crc
	crc_aas = CRC_ProcessString((unsigned char *)(*aasworld).areas, sizeof(aas_area_t) * (*aasworld).numareas);
	botimport.FS_Write(&crc_aas, sizeof(crc_aas), fp);

	// save the table data

	// children
	botimport.FS_Write(&(*aasworld).routetable->numChildren, sizeof(int), fp);
	botimport.FS_Write((*aasworld).routetable->children, (*aasworld).routetable->numChildren * sizeof(aas_rt_child_t), fp);

	// parents
	botimport.FS_Write(&(*aasworld).routetable->numParents, sizeof(int), fp);
	botimport.FS_Write((*aasworld).routetable->parents, (*aasworld).routetable->numParents * sizeof(aas_rt_parent_t), fp);

	// parentChildren
	botimport.FS_Write(&(*aasworld).routetable->numParentChildren, sizeof(int), fp);
	botimport.FS_Write((*aasworld).routetable->parentChildren, (*aasworld).routetable->numParentChildren * sizeof(unsigned short int), fp);

	// visibleParents
	botimport.FS_Write(&(*aasworld).routetable->numVisibleParents, sizeof(int), fp);
	botimport.FS_Write((*aasworld).routetable->visibleParents, (*aasworld).routetable->numVisibleParents * sizeof(unsigned short int), fp);

	// parentLinks
	botimport.FS_Write(&(*aasworld).routetable->numParentLinks, sizeof(int), fp);
	botimport.FS_Write((*aasworld).routetable->parentLinks, (*aasworld).routetable->numParentLinks * sizeof(aas_rt_parent_link_t), fp);

	botimport.FS_FCloseFile(fp);
	return;
}
示例#5
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AAS_FloodCluster_r(int areanum, int clusternum)
{
	int i, otherareanum;
	aas_face_t *face;
	aas_area_t *area;

	//set cluster mark
	aasworld.areasettings[areanum].cluster = clusternum;
	//if the area is a portal
	//if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) return;
	//
	area = &aasworld.areas[areanum];
	//use area faces to flood into adjacent areas
	for (i = 0; i < area->numfaces; i++)
	{
		face = &aasworld.faces[abs(aasworld.faceindex[area->firstface + i])];
		//
		if (face->frontarea != areanum) otherareanum = face->frontarea;
		else otherareanum = face->backarea;
		//if there's no area at the other side
		if (!otherareanum) continue;
		//if the area is a portal
		if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
		//if the area is already marked
		if (aasworld.areasettings[otherareanum].cluster) continue;
		//
		AAS_FloodCluster_r(otherareanum, clusternum);
	} //end for
	//use the reachabilities to flood into other areas
	for (i = 0; i < aasworld.areasettings[areanum].numreachableareas; i++)
	{
		otherareanum = aasworld.reachability[
					aasworld.areasettings[areanum].firstreachablearea + i].areanum;
		if (!otherareanum)
		{
			continue;
			AAS_Error("reachability %d has zero area\n", aasworld.areasettings[areanum].firstreachablearea + i);
		} //end if
		//if the area is a portal
		if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
		//if the area is already marked
		if (aasworld.areasettings[otherareanum].cluster) continue;
		//
		AAS_FloodCluster_r(otherareanum, clusternum);
	} //end for
} //end of the function AAS_FloodCluster_r
示例#6
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
int AAS_FindClusters(void)
{
	int i;
	aas_cluster_t *cluster;

	AAS_RemoveClusterAreas();
	//
	for (i = 1; i < aasworld.numareas; i++)
	{
		//if the area is already part of a cluster
		if (aasworld.areasettings[i].cluster)
			continue;
		// if not flooding through faces only use areas that have reachabilities
		if (nofaceflood)
		{
			if (!aasworld.areasettings[i].numreachableareas)
				continue;
		} //end if
		//if the area is a cluster portal
		if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
			continue;
		if (aasworld.numclusters >= AAS_MAX_CLUSTERS)
		{
			AAS_Error("AAS_MAX_CLUSTERS");
			return qfalse;
		} //end if
		cluster = &aasworld.clusters[aasworld.numclusters];
		cluster->numareas = 0;
		cluster->numreachabilityareas = 0;
		cluster->firstportal = aasworld.portalindexsize;
		cluster->numportals = 0;
		//flood the areas in this cluster
		if (!AAS_FloodClusterAreas_r(i, aasworld.numclusters))
			return qfalse;
		if (!AAS_FloodClusterAreasUsingReachabilities(aasworld.numclusters))
			return qfalse;
		//number the cluster areas
		//AAS_NumberClusterPortals(aasworld.numclusters);
		AAS_NumberClusterAreas(aasworld.numclusters);
		//Log_Write("cluster %d has %d areas\r\n", aasworld.numclusters, cluster->numareas);
		aasworld.numclusters++;
	} //end for
	return qtrue;
} //end of the function AAS_FindClusters
示例#7
0
//===========================================================================
// gets adjacent areas with less presence types recursively
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_GetAdjacentAreasWithLessPresenceTypes_r(int *areanums, int numareas, int curareanum)
{
	int i, j, presencetype, otherpresencetype, otherareanum, facenum;
	aas_area_t *area;
	aas_face_t *face;

	areanums[numareas++] = curareanum;
	area = &aasworld.areas[curareanum];
	presencetype = aasworld.areasettings[curareanum].presencetype;
	for (i = 0; i < area->numfaces; i++)
	{
		facenum = abs(aasworld.faceindex[area->firstface + i]);
		face = &aasworld.faces[facenum];
		//if the face is solid
		if (face->faceflags & FACE_SOLID) continue;
		//the area at the other side of the face
		if (face->frontarea != curareanum) otherareanum = face->frontarea;
		else otherareanum = face->backarea;
		//
		otherpresencetype = aasworld.areasettings[otherareanum].presencetype;
		//if the other area has less presence types
		if ((presencetype & ~otherpresencetype) &&
				!(otherpresencetype & ~presencetype))
		{
			//check if the other area isn't already in the list
			for (j = 0; j < numareas; j++)
			{
				if (otherareanum == areanums[j]) break;
			} //end for
			//if the other area isn't already in the list
			if (j == numareas)
			{
				if (numareas >= MAX_PORTALAREAS)
				{
					AAS_Error("MAX_PORTALAREAS");
					return numareas;
				} //end if
				numareas = AAS_GetAdjacentAreasWithLessPresenceTypes_r(areanums, numareas, otherareanum);
			} //end if
		} //end if
	} //end for
	return numareas;
} //end of the function AAS_GetAdjacentAreasWithLessPresenceTypes_r
示例#8
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AAS_CreatePortals(void)
{
	int i;
	aas_portal_t *portal;

	for (i = 1; i < aasworld.numareas; i++)
	{
		//if the area is a cluster portal
		if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)
		{
			if (aasworld.numportals >= AAS_MAX_PORTALS)
			{
				AAS_Error("AAS_MAX_PORTALS");
				return;
			} //end if
			portal = &aasworld.portals[aasworld.numportals];
			portal->areanum = i;
			portal->frontcluster = 0;
			portal->backcluster = 0;
			aasworld.numportals++;
		} //end if
	} //end for
} //end of the function AAS_CreatePortals
示例#9
0
qboolean AAS_RT_ReadRouteTable(fileHandle_t fp)
{
	int                  ident, version, i;
	unsigned short int   crc, crc_aas;
	aas_rt_t             *routetable;
	aas_rt_child_t       *child;
	aas_rt_parent_t      *parent;
	aas_rt_parent_link_t *plink;
	unsigned short int   *psi;

	qboolean doswap;

#ifdef DEBUG_READING_TIME
	int pretime;

	pretime = Sys_MilliSeconds();
#endif

	routetable = (*aasworld).routetable;

	doswap = (LittleLong(1) != 1);

	// check ident
	AAS_RT_DBG_Read(&ident, sizeof(ident), fp);
	ident = LittleLong(ident);

	if (ident != RTBID)
	{
		AAS_Error("File is not an RTB file\n");
		botimport.FS_FCloseFile(fp);
		return qfalse;
	}

	// check version
	AAS_RT_DBG_Read(&version, sizeof(version), fp);
	version = LittleLong(version);

	if (version != RTBVERSION)
	{
		AAS_Error("File is version %i not %i\n", version, RTBVERSION);
		botimport.FS_FCloseFile(fp);
		return qfalse;
	}

	// read the CRC check on the AAS data
	AAS_RT_DBG_Read(&crc, sizeof(crc), fp);
	crc = LittleShort(crc);

	// calculate a CRC on the AAS areas
	crc_aas = CRC_ProcessString((unsigned char *)(*aasworld).areas, sizeof(aas_area_t) * (*aasworld).numareas);

	if (crc != crc_aas)
	{
		AAS_Error("Route-table is from different AAS file, ignoring.\n");
		botimport.FS_FCloseFile(fp);
		return qfalse;
	}

	// read the route-table

	// children
	botimport.FS_Read(&routetable->numChildren, sizeof(int), fp);
	routetable->numChildren = LittleLong(routetable->numChildren);
	routetable->children    = (aas_rt_child_t *) AAS_RT_GetClearedMemory(routetable->numChildren * sizeof(aas_rt_child_t));
	botimport.FS_Read(routetable->children, routetable->numChildren * sizeof(aas_rt_child_t), fp);
	child = &routetable->children[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numChildren; i++, child++)
		{
			child->areanum          = LittleShort(child->areanum);
			child->numParentLinks   = LittleLong(child->numParentLinks);
			child->startParentLinks = LittleLong(child->startParentLinks);
		}
	}

	// parents
	botimport.FS_Read(&routetable->numParents, sizeof(int), fp);
	routetable->numParents = LittleLong(routetable->numParents);
	routetable->parents    = (aas_rt_parent_t *) AAS_RT_GetClearedMemory(routetable->numParents * sizeof(aas_rt_parent_t));
	botimport.FS_Read(routetable->parents, routetable->numParents * sizeof(aas_rt_parent_t), fp);
	parent = &routetable->parents[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numParents; i++, parent++)
		{
			parent->areanum             = LittleShort(parent->areanum);
			parent->numParentChildren   = LittleLong(parent->numParentChildren);
			parent->startParentChildren = LittleLong(parent->startParentChildren);
			parent->numVisibleParents   = LittleLong(parent->numVisibleParents);
			parent->startVisibleParents = LittleLong(parent->startVisibleParents);
		}
	}

	// parentChildren
	botimport.FS_Read(&routetable->numParentChildren, sizeof(int), fp);
	routetable->numParentChildren = LittleLong(routetable->numParentChildren);
	routetable->parentChildren    = (unsigned short int *) AAS_RT_GetClearedMemory(routetable->numParentChildren * sizeof(unsigned short int));
	botimport.FS_Read(routetable->parentChildren, routetable->numParentChildren * sizeof(unsigned short int), fp);
	psi = &routetable->parentChildren[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numParentChildren; i++, psi++)
		{
			*psi = LittleShort(*psi);
		}
	}

	// visibleParents
	botimport.FS_Read(&routetable->numVisibleParents, sizeof(int), fp);
	routetable->numVisibleParents = LittleLong(routetable->numVisibleParents);
	routetable->visibleParents    = (unsigned short int *) AAS_RT_GetClearedMemory(routetable->numVisibleParents * sizeof(unsigned short int));
	botimport.FS_Read(routetable->visibleParents, routetable->numVisibleParents * sizeof(unsigned short int), fp);
	psi = &routetable->visibleParents[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numVisibleParents; i++, psi++)
		{
			*psi = LittleShort(*psi);
		}
	}

	// parentLinks
	botimport.FS_Read(&routetable->numParentLinks, sizeof(int), fp);
	routetable->numParentLinks = LittleLong(routetable->numParentLinks);
	routetable->parentLinks    = (aas_rt_parent_link_t *) AAS_RT_GetClearedMemory(routetable->numParentLinks * sizeof(aas_rt_parent_link_t));
	botimport.FS_Read(routetable->parentLinks, routetable->numParentLinks * sizeof(aas_parent_link_t), fp);
	plink = &routetable->parentLinks[0];
	if (doswap)
	{
		for (i = 0; i < routetable->numParentLinks; i++, plink++)
		{
			plink->childIndex = LittleShort(plink->childIndex);
			plink->parent     = LittleShort(plink->parent);
		}
	}

	// build the areaChildIndexes
	routetable->areaChildIndexes = (unsigned short int *) AAS_RT_GetClearedMemory((*aasworld).numareas * sizeof(unsigned short int));
	child                        = routetable->children;
	for (i = 0; i < routetable->numChildren; i++, child++)
	{
		routetable->areaChildIndexes[child->areanum] = i + 1;
	}

	botimport.Print(PRT_MESSAGE, "Total Parents: %d\n", routetable->numParents);
	botimport.Print(PRT_MESSAGE, "Total Children: %d\n", routetable->numChildren);
	botimport.Print(PRT_MESSAGE, "Total Memory Used: %d\n", memorycount);

#ifdef DEBUG_READING_TIME
	botimport.Print(PRT_MESSAGE, "Route-Table read time: %i\n", Sys_MilliSeconds() - pretime);
#endif

	botimport.FS_FCloseFile(fp);
	return qtrue;
}
示例#10
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_FloodClusterAreas_r(int areanum, int clusternum)
{
	aas_area_t *area;
	aas_face_t *face;
	int facenum, i;

	//
	if (areanum <= 0 || areanum >= aasworld.numareas)
	{
		AAS_Error("AAS_FloodClusterAreas_r: areanum out of range");
		return qfalse;
	} //end if
	//if the area is already part of a cluster
	if (aasworld.areasettings[areanum].cluster > 0)
	{
		if (aasworld.areasettings[areanum].cluster == clusternum) return qtrue;
		//
		//there's a reachability going from one cluster to another only in one direction
		//
		AAS_Error("cluster %d touched cluster %d at area %d\r\n",
				clusternum, aasworld.areasettings[areanum].cluster, areanum);
		return qfalse;
	} //end if
	//don't add the cluster portal areas to the clusters
	if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL)
	{
		return AAS_UpdatePortal(areanum, clusternum);
	} //end if
	//set the area cluster number
	aasworld.areasettings[areanum].cluster = clusternum;
	aasworld.areasettings[areanum].clusterareanum =
				aasworld.clusters[clusternum].numareas;
	//the cluster has an extra area
	aasworld.clusters[clusternum].numareas++;

	area = &aasworld.areas[areanum];
	//use area faces to flood into adjacent areas
	if (!nofaceflood)
	{
		for (i = 0; i < area->numfaces; i++)
		{
			facenum = abs(aasworld.faceindex[area->firstface + i]);
			face = &aasworld.faces[facenum];
			if (face->frontarea == areanum)
			{
				if (face->backarea) if (!AAS_FloodClusterAreas_r(face->backarea, clusternum)) return qfalse;
			} //end if
			else
			{
				if (face->frontarea) if (!AAS_FloodClusterAreas_r(face->frontarea, clusternum)) return qfalse;
			} //end else
		} //end for
	} //end if
	//use the reachabilities to flood into other areas
	for (i = 0; i < aasworld.areasettings[areanum].numreachableareas; i++)
	{
		if (!aasworld.reachability[
					aasworld.areasettings[areanum].firstreachablearea + i].areanum)
		{
			continue;
		} //end if
		if (!AAS_FloodClusterAreas_r(aasworld.reachability[
				aasworld.areasettings[areanum].firstreachablearea + i].areanum, clusternum)) return qfalse;
	} //end for
	return qtrue;
} //end of the function AAS_FloodClusterAreas_r
示例#11
0
//===========================================================================
// load an aas file
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean AAS_LoadAASFile( char *filename, int fpoffset, int fplength ) {
	FILE *fp;
	aas_header_t header;
	int offset, length;

	//dump current loaded aas file
	AAS_DumpAASData();
	//open the file
	fp = fopen( filename, "rb" );
	if ( !fp ) {
		AAS_Error( "can't open %s\n", filename );
		return false;
	} //end if
	  //seek to the correct position (in the pak file)
	if ( fseek( fp, fpoffset, SEEK_SET ) ) {
		AAS_Error( "can't seek to file %s\n" );
		fclose( fp );
		return false;
	} //end if
	  //read the header
	if ( fread( &header, sizeof( aas_header_t ), 1, fp ) != 1 ) {
		AAS_Error( "can't read header of file %s\n", filename );
		fclose( fp );
		return false;
	} //end if
	  //check header identification
	header.ident = LittleLong( header.ident );
	if ( header.ident != AASID ) {
		AAS_Error( "%s is not an AAS file\n", filename );
		fclose( fp );
		return false;
	} //end if
	  //check the version
	header.version = LittleLong( header.version );
	if ( header.version != AASVERSION ) {
		AAS_Error( "%s is version %i, not %i\n", filename, header.version, AASVERSION );
		fclose( fp );
		return false;
	} //end if
	  //
	if ( header.version == AASVERSION ) {
		AAS_DData( (unsigned char *) &header + 8, sizeof( aas_header_t ) - 8 );
	} //end if
	( *aasworld ).bspchecksum = LittleLong( header.bspchecksum );
	//load the lumps:
	//bounding boxes
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_BBOXES].fileofs );
	length = LittleLong( header.lumps[AASLUMP_BBOXES].filelen );
	( *aasworld ).bboxes = (aas_bbox_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).bboxes );
	if ( !( *aasworld ).bboxes ) {
		return false;
	}
	( *aasworld ).numbboxes = length / sizeof( aas_bbox_t );
	//vertexes
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_VERTEXES].fileofs );
	length = LittleLong( header.lumps[AASLUMP_VERTEXES].filelen );
	( *aasworld ).vertexes = (aas_vertex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).vertexes );
	if ( !( *aasworld ).vertexes ) {
		return false;
	}
	( *aasworld ).numvertexes = length / sizeof( aas_vertex_t );
	//planes
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_PLANES].fileofs );
	length = LittleLong( header.lumps[AASLUMP_PLANES].filelen );
	( *aasworld ).planes = (aas_plane_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).planes );
	if ( !( *aasworld ).planes ) {
		return false;
	}
	( *aasworld ).numplanes = length / sizeof( aas_plane_t );
	//edges
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_EDGES].fileofs );
	length = LittleLong( header.lumps[AASLUMP_EDGES].filelen );
	( *aasworld ).edges = (aas_edge_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).edges );
	if ( !( *aasworld ).edges ) {
		return false;
	}
	( *aasworld ).numedges = length / sizeof( aas_edge_t );
	//edgeindex
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_EDGEINDEX].fileofs );
	length = LittleLong( header.lumps[AASLUMP_EDGEINDEX].filelen );
	( *aasworld ).edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).edgeindex );
	if ( !( *aasworld ).edgeindex ) {
		return false;
	}
	( *aasworld ).edgeindexsize = length / sizeof( aas_edgeindex_t );
	//faces
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_FACES].fileofs );
	length = LittleLong( header.lumps[AASLUMP_FACES].filelen );
	( *aasworld ).faces = (aas_face_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).faces );
	if ( !( *aasworld ).faces ) {
		return false;
	}
	( *aasworld ).numfaces = length / sizeof( aas_face_t );
	//faceindex
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_FACEINDEX].fileofs );
	length = LittleLong( header.lumps[AASLUMP_FACEINDEX].filelen );
	( *aasworld ).faceindex = (aas_faceindex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).faceindex );
	if ( !( *aasworld ).faceindex ) {
		return false;
	}
	( *aasworld ).faceindexsize = length / sizeof( int );
	//convex areas
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_AREAS].fileofs );
	length = LittleLong( header.lumps[AASLUMP_AREAS].filelen );
	( *aasworld ).areas = (aas_area_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).areas );
	if ( !( *aasworld ).areas ) {
		return false;
	}
	( *aasworld ).numareas = length / sizeof( aas_area_t );
	//area settings
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_AREASETTINGS].fileofs );
	length = LittleLong( header.lumps[AASLUMP_AREASETTINGS].filelen );
	( *aasworld ).areasettings = (aas_areasettings_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).areasettings );
	if ( !( *aasworld ).areasettings ) {
		return false;
	}
	( *aasworld ).numareasettings = length / sizeof( aas_areasettings_t );
	//reachability list
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_REACHABILITY].fileofs );
	length = LittleLong( header.lumps[AASLUMP_REACHABILITY].filelen );
	( *aasworld ).reachability = (aas_reachability_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).reachability );
	if ( length && !( *aasworld ).reachability ) {
		return false;
	}
	( *aasworld ).reachabilitysize = length / sizeof( aas_reachability_t );
	//nodes
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_NODES].fileofs );
	length = LittleLong( header.lumps[AASLUMP_NODES].filelen );
	( *aasworld ).nodes = (aas_node_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).nodes );
	if ( !( *aasworld ).nodes ) {
		return false;
	}
	( *aasworld ).numnodes = length / sizeof( aas_node_t );
	//cluster portals
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_PORTALS].fileofs );
	length = LittleLong( header.lumps[AASLUMP_PORTALS].filelen );
	( *aasworld ).portals = (aas_portal_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).portals );
	if ( length && !( *aasworld ).portals ) {
		return false;
	}
	( *aasworld ).numportals = length / sizeof( aas_portal_t );
	//cluster portal index
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_PORTALINDEX].fileofs );
	length = LittleLong( header.lumps[AASLUMP_PORTALINDEX].filelen );
	( *aasworld ).portalindex = (aas_portalindex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).portalindex );
	if ( length && !( *aasworld ).portalindex ) {
		return false;
	}
	( *aasworld ).portalindexsize = length / sizeof( aas_portalindex_t );
	//clusters
	offset = fpoffset + LittleLong( header.lumps[AASLUMP_CLUSTERS].fileofs );
	length = LittleLong( header.lumps[AASLUMP_CLUSTERS].filelen );
	( *aasworld ).clusters = (aas_cluster_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).clusters );
	if ( length && !( *aasworld ).clusters ) {
		return false;
	}
	( *aasworld ).numclusters = length / sizeof( aas_cluster_t );
	//swap everything
	AAS_SwapAASData();
	//aas file is loaded
	( *aasworld ).loaded = true;
	//close the file
	fclose( fp );
	return true;
} //end of the function AAS_LoadAASFile