From 5c0efda0ef811b2bafedb2b4f53b083a9b90e1b4 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Tue, 16 May 2006 20:41:57 +0000 Subject: * Removal of bot code * Refactored botlib parsing code into qcommon --- src/botlib/be_aas_cluster.c | 1546 ------------------------------------------- 1 file changed, 1546 deletions(-) delete mode 100644 src/botlib/be_aas_cluster.c (limited to 'src/botlib/be_aas_cluster.c') diff --git a/src/botlib/be_aas_cluster.c b/src/botlib/be_aas_cluster.c deleted file mode 100644 index 2805dc99..00000000 --- a/src/botlib/be_aas_cluster.c +++ /dev/null @@ -1,1546 +0,0 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. -Copyright (C) 2000-2006 Tim Angus - -This file is part of Tremulous. - -Tremulous is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Tremulous is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Tremulous; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ - -/***************************************************************************** - * name: be_aas_cluster.c - * - * desc: area clustering - * - * $Archive: /MissionPack/code/botlib/be_aas_cluster.c $ - * - *****************************************************************************/ - -#include "../qcommon/q_shared.h" -#include "l_memory.h" -#include "l_script.h" -#include "l_precomp.h" -#include "l_struct.h" -#include "l_log.h" -#include "l_memory.h" -#include "l_libvar.h" -#include "aasfile.h" -#include "botlib.h" -#include "be_aas.h" -#include "be_aas_funcs.h" -#include "be_aas_def.h" - -extern botlib_import_t botimport; - -#define AAS_MAX_PORTALS 65536 -#define AAS_MAX_PORTALINDEXSIZE 65536 -#define AAS_MAX_CLUSTERS 65536 -// -#define MAX_PORTALAREAS 1024 - -// do not flood through area faces, only use reachabilities -int nofaceflood = qtrue; - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveClusterAreas(void) -{ - int i; - - for (i = 1; i < aasworld.numareas; i++) - { - aasworld.areasettings[i].cluster = 0; - } //end for -} //end of the function AAS_RemoveClusterAreas -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_ClearCluster(int clusternum) -{ - int i; - - for (i = 1; i < aasworld.numareas; i++) - { - if (aasworld.areasettings[i].cluster == clusternum) - { - aasworld.areasettings[i].cluster = 0; - } //end if - } //end for -} //end of the function AAS_ClearCluster -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemovePortalsClusterReference(int clusternum) -{ - int portalnum; - - for (portalnum = 1; portalnum < aasworld.numportals; portalnum++) - { - if (aasworld.portals[portalnum].frontcluster == clusternum) - { - aasworld.portals[portalnum].frontcluster = 0; - } //end if - if (aasworld.portals[portalnum].backcluster == clusternum) - { - aasworld.portals[portalnum].backcluster = 0; - } //end if - } //end for -} //end of the function AAS_RemovePortalsClusterReference -//=========================================================================== -// -// 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 -//=========================================================================== -// -// 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 -//=========================================================================== -// try to flood from all areas without cluster into areas with a cluster set -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_FloodClusterAreasUsingReachabilities(int clusternum) -{ - int i, j, areanum; - - for (i = 1; i < aasworld.numareas; i++) - { - //if this area already has a cluster set - if (aasworld.areasettings[i].cluster) - continue; - //if this area is a cluster portal - if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL) - continue; - //loop over the reachable areas from this area - for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++) - { - //the reachable area - areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum; - //if this area is a cluster portal - if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) - continue; - //if this area has a cluster set - if (aasworld.areasettings[areanum].cluster) - { - if (!AAS_FloodClusterAreas_r(i, clusternum)) - return qfalse; - i = 0; - break; - } //end if - } //end for - } //end for - return qtrue; -} //end of the function AAS_FloodClusterAreasUsingReachabilities -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_NumberClusterPortals(int clusternum) -{ - int i, portalnum; - aas_cluster_t *cluster; - aas_portal_t *portal; - - cluster = &aasworld.clusters[clusternum]; - for (i = 0; i < cluster->numportals; i++) - { - portalnum = aasworld.portalindex[cluster->firstportal + i]; - portal = &aasworld.portals[portalnum]; - if (portal->frontcluster == clusternum) - { - portal->clusterareanum[0] = cluster->numareas++; - } //end if - else - { - portal->clusterareanum[1] = cluster->numareas++; - } //end else - } //end for -} //end of the function AAS_NumberClusterPortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_NumberClusterAreas(int clusternum) -{ - int i, portalnum; - aas_cluster_t *cluster; - aas_portal_t *portal; - - aasworld.clusters[clusternum].numareas = 0; - aasworld.clusters[clusternum].numreachabilityareas = 0; - //number all areas in this cluster WITH reachabilities - for (i = 1; i < aasworld.numareas; i++) - { - // - if (aasworld.areasettings[i].cluster != clusternum) continue; - // - if (!AAS_AreaReachability(i)) continue; - // - aasworld.areasettings[i].clusterareanum = aasworld.clusters[clusternum].numareas; - //the cluster has an extra area - aasworld.clusters[clusternum].numareas++; - aasworld.clusters[clusternum].numreachabilityareas++; - } //end for - //number all portals in this cluster WITH reachabilities - cluster = &aasworld.clusters[clusternum]; - for (i = 0; i < cluster->numportals; i++) - { - portalnum = aasworld.portalindex[cluster->firstportal + i]; - portal = &aasworld.portals[portalnum]; - if (!AAS_AreaReachability(portal->areanum)) continue; - if (portal->frontcluster == clusternum) - { - portal->clusterareanum[0] = cluster->numareas++; - aasworld.clusters[clusternum].numreachabilityareas++; - } //end if - else - { - portal->clusterareanum[1] = cluster->numareas++; - aasworld.clusters[clusternum].numreachabilityareas++; - } //end else - } //end for - //number all areas in this cluster WITHOUT reachabilities - for (i = 1; i < aasworld.numareas; i++) - { - // - if (aasworld.areasettings[i].cluster != clusternum) continue; - // - if (AAS_AreaReachability(i)) continue; - // - aasworld.areasettings[i].clusterareanum = aasworld.clusters[clusternum].numareas; - //the cluster has an extra area - aasworld.clusters[clusternum].numareas++; - } //end for - //number all portals in this cluster WITHOUT reachabilities - cluster = &aasworld.clusters[clusternum]; - for (i = 0; i < cluster->numportals; i++) - { - portalnum = aasworld.portalindex[cluster->firstportal + i]; - portal = &aasworld.portals[portalnum]; - if (AAS_AreaReachability(portal->areanum)) continue; - if (portal->frontcluster == clusternum) - { - portal->clusterareanum[0] = cluster->numareas++; - } //end if - else - { - portal->clusterareanum[1] = cluster->numareas++; - } //end else - } //end for -} //end of the function AAS_NumberClusterAreas -//=========================================================================== -// -// 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 -//=========================================================================== -// -// 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 -/* -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_MapContainsTeleporters(void) -{ - bsp_entity_t *entities, *ent; - char *classname; - - entities = AAS_ParseBSPEntities(); - - for (ent = entities; ent; ent = ent->next) - { - classname = AAS_ValueForBSPEpairKey(ent, "classname"); - if (classname && !strcmp(classname, "misc_teleporter")) - { - AAS_FreeBSPEntities(entities); - return qtrue; - } //end if - } //end for - return qfalse; -} //end of the function AAS_MapContainsTeleporters -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_NonConvexFaces(aas_face_t *face1, aas_face_t *face2, int side1, int side2) -{ - int i, j, edgenum; - aas_plane_t *plane1, *plane2; - aas_edge_t *edge; - - - plane1 = &aasworld.planes[face1->planenum ^ side1]; - plane2 = &aasworld.planes[face2->planenum ^ side2]; - - //check if one of the points of face1 is at the back of the plane of face2 - for (i = 0; i < face1->numedges; i++) - { - edgenum = abs(aasworld.edgeindex[face1->firstedge + i]); - edge = &aasworld.edges[edgenum]; - for (j = 0; j < 2; j++) - { - if (DotProduct(plane2->normal, aasworld.vertexes[edge->v[j]]) - - plane2->dist < -0.01) return qtrue; - } //end for - } //end for - for (i = 0; i < face2->numedges; i++) - { - edgenum = abs(aasworld.edgeindex[face2->firstedge + i]); - edge = &aasworld.edges[edgenum]; - for (j = 0; j < 2; j++) - { - if (DotProduct(plane1->normal, aasworld.vertexes[edge->v[j]]) - - plane1->dist < -0.01) return qtrue; - } //end for - } //end for - - return qfalse; -} //end of the function AAS_NonConvexFaces -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -qboolean AAS_CanMergeAreas(int *areanums, int numareas) -{ - int i, j, s, face1num, face2num, side1, side2, fn1, fn2; - aas_face_t *face1, *face2; - aas_area_t *area1, *area2; - - for (i = 0; i < numareas; i++) - { - area1 = &aasworld.areas[areanums[i]]; - for (fn1 = 0; fn1 < area1->numfaces; fn1++) - { - face1num = abs(aasworld.faceindex[area1->firstface + fn1]); - face1 = &aasworld.faces[face1num]; - side1 = face1->frontarea != areanums[i]; - //check if the face isn't a shared one with one of the other areas - for (s = 0; s < numareas; s++) - { - if (s == i) continue; - if (face1->frontarea == s || face1->backarea == s) break; - } //end for - //if the face was a shared one - if (s != numareas) continue; - // - for (j = 0; j < numareas; j++) - { - if (j == i) continue; - area2 = &aasworld.areas[areanums[j]]; - for (fn2 = 0; fn2 < area2->numfaces; fn2++) - { - face2num = abs(aasworld.faceindex[area2->firstface + fn2]); - face2 = &aasworld.faces[face2num]; - side2 = face2->frontarea != areanums[j]; - //check if the face isn't a shared one with one of the other areas - for (s = 0; s < numareas; s++) - { - if (s == j) continue; - if (face2->frontarea == s || face2->backarea == s) break; - } //end for - //if the face was a shared one - if (s != numareas) continue; - // - if (AAS_NonConvexFaces(face1, face2, side1, side2)) return qfalse; - } //end for - } //end for - } //end for - } //end for - return qtrue; -} //end of the function AAS_CanMergeAreas -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -qboolean AAS_NonConvexEdges(aas_edge_t *edge1, aas_edge_t *edge2, int side1, int side2, int planenum) -{ - int i; - vec3_t edgevec1, edgevec2, normal1, normal2; - float dist1, dist2; - aas_plane_t *plane; - - plane = &aasworld.planes[planenum]; - VectorSubtract(aasworld.vertexes[edge1->v[1]], aasworld.vertexes[edge1->v[0]], edgevec1); - VectorSubtract(aasworld.vertexes[edge2->v[1]], aasworld.vertexes[edge2->v[0]], edgevec2); - if (side1) VectorInverse(edgevec1); - if (side2) VectorInverse(edgevec2); - // - CrossProduct(edgevec1, plane->normal, normal1); - dist1 = DotProduct(normal1, aasworld.vertexes[edge1->v[0]]); - CrossProduct(edgevec2, plane->normal, normal2); - dist2 = DotProduct(normal2, aasworld.vertexes[edge2->v[0]]); - - for (i = 0; i < 2; i++) - { - if (DotProduct(aasworld.vertexes[edge1->v[i]], normal2) - dist2 < -0.01) return qfalse; - } //end for - for (i = 0; i < 2; i++) - { - if (DotProduct(aasworld.vertexes[edge2->v[i]], normal1) - dist1 < -0.01) return qfalse; - } //end for - return qtrue; -} //end of the function AAS_NonConvexEdges -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -qboolean AAS_CanMergeFaces(int *facenums, int numfaces, int planenum) -{ - int i, j, s, edgenum1, edgenum2, side1, side2, en1, en2, ens; - aas_face_t *face1, *face2, *otherface; - aas_edge_t *edge1, *edge2; - - for (i = 0; i < numfaces; i++) - { - face1 = &aasworld.faces[facenums[i]]; - for (en1 = 0; en1 < face1->numedges; en1++) - { - edgenum1 = aasworld.edgeindex[face1->firstedge + en1]; - side1 = (edgenum1 < 0) ^ (face1->planenum != planenum); - edgenum1 = abs(edgenum1); - edge1 = &aasworld.edges[edgenum1]; - //check if the edge is shared with another face - for (s = 0; s < numfaces; s++) - { - if (s == i) continue; - otherface = &aasworld.faces[facenums[s]]; - for (ens = 0; ens < otherface->numedges; ens++) - { - if (edgenum1 == abs(aasworld.edgeindex[otherface->firstedge + ens])) break; - } //end for - if (ens != otherface->numedges) break; - } //end for - //if the edge was shared - if (s != numfaces) continue; - // - for (j = 0; j < numfaces; j++) - { - if (j == i) continue; - face2 = &aasworld.faces[facenums[j]]; - for (en2 = 0; en2 < face2->numedges; en2++) - { - edgenum2 = aasworld.edgeindex[face2->firstedge + en2]; - side2 = (edgenum2 < 0) ^ (face2->planenum != planenum); - edgenum2 = abs(edgenum2); - edge2 = &aasworld.edges[edgenum2]; - //check if the edge is shared with another face - for (s = 0; s < numfaces; s++) - { - if (s == i) continue; - otherface = &aasworld.faces[facenums[s]]; - for (ens = 0; ens < otherface->numedges; ens++) - { - if (edgenum2 == abs(aasworld.edgeindex[otherface->firstedge + ens])) break; - } //end for - if (ens != otherface->numedges) break; - } //end for - //if the edge was shared - if (s != numfaces) continue; - // - if (AAS_NonConvexEdges(edge1, edge2, side1, side2, planenum)) return qfalse; - } //end for - } //end for - } //end for - } //end for - return qtrue; -} //end of the function AAS_CanMergeFaces*/ -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_ConnectedAreas_r(int *areanums, int numareas, int *connectedareas, int curarea) -{ - int i, j, otherareanum, facenum; - aas_area_t *area; - aas_face_t *face; - - connectedareas[curarea] = qtrue; - area = &aasworld.areas[areanums[curarea]]; - 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; - //get the area at the other side of the face - if (face->frontarea != areanums[curarea]) otherareanum = face->frontarea; - else otherareanum = face->backarea; - //check if the face is leading to one of the other areas - for (j = 0; j < numareas; j++) - { - if (areanums[j] == otherareanum) break; - } //end for - //if the face isn't leading to one of the other areas - if (j == numareas) continue; - //if the other area is already connected - if (connectedareas[j]) continue; - //recursively proceed with the other area - AAS_ConnectedAreas_r(areanums, numareas, connectedareas, j); - } //end for -} //end of the function AAS_ConnectedAreas_r -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -qboolean AAS_ConnectedAreas(int *areanums, int numareas) -{ - int connectedareas[MAX_PORTALAREAS], i; - - Com_Memset(connectedareas, 0, sizeof(connectedareas)); - if (numareas < 1) return qfalse; - if (numareas == 1) return qtrue; - AAS_ConnectedAreas_r(areanums, numareas, connectedareas, 0); - for (i = 0; i < numareas; i++) - { - if (!connectedareas[i]) return qfalse; - } //end for - return qtrue; -} //end of the function AAS_ConnectedAreas -//=========================================================================== -// 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 -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_CheckAreaForPossiblePortals(int areanum) -{ - int i, j, k, fen, ben, frontedgenum, backedgenum, facenum; - int areanums[MAX_PORTALAREAS], numareas, otherareanum; - int numareafrontfaces[MAX_PORTALAREAS], numareabackfaces[MAX_PORTALAREAS]; - int frontfacenums[MAX_PORTALAREAS], backfacenums[MAX_PORTALAREAS]; - int numfrontfaces, numbackfaces; - int frontareanums[MAX_PORTALAREAS], backareanums[MAX_PORTALAREAS]; - int numfrontareas, numbackareas; - int frontplanenum, backplanenum, faceplanenum; - aas_area_t *area; - aas_face_t *frontface, *backface, *face; - - //if it isn't already a portal - if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) return 0; - //it must be a grounded area - if (!(aasworld.areasettings[areanum].areaflags & AREA_GROUNDED)) return 0; - // - Com_Memset(numareafrontfaces, 0, sizeof(numareafrontfaces)); - Com_Memset(numareabackfaces, 0, sizeof(numareabackfaces)); - numareas = numfrontfaces = numbackfaces = 0; - numfrontareas = numbackareas = 0; - frontplanenum = backplanenum = -1; - //add any adjacent areas with less presence types - numareas = AAS_GetAdjacentAreasWithLessPresenceTypes_r(areanums, 0, areanum); - // - for (i = 0; i < numareas; i++) - { - area = &aasworld.areas[areanums[i]]; - for (j = 0; j < area->numfaces; j++) - { - facenum = abs(aasworld.faceindex[area->firstface + j]); - face = &aasworld.faces[facenum]; - //if the face is solid - if (face->faceflags & FACE_SOLID) continue; - //check if the face is shared with one of the other areas - for (k = 0; k < numareas; k++) - { - if (k == i) continue; - if (face->frontarea == areanums[k] || face->backarea == areanums[k]) break; - } //end for - //if the face is shared - if (k != numareas) continue; - //the number of the area at the other side of the face - if (face->frontarea == areanums[i]) otherareanum = face->backarea; - else otherareanum = face->frontarea; - //if the other area already is a cluter portal - if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) return 0; - //number of the plane of the area - faceplanenum = face->planenum & ~1; - // - if (frontplanenum < 0 || faceplanenum == frontplanenum) - { - frontplanenum = faceplanenum; - frontfacenums[numfrontfaces++] = facenum; - for (k = 0; k < numfrontareas; k++) - { - if (frontareanums[k] == otherareanum) break; - } //end for - if (k == numfrontareas) frontareanums[numfrontareas++] = otherareanum; - numareafrontfaces[i]++; - } //end if - else if (backplanenum < 0 || faceplanenum == backplanenum) - { - backplanenum = faceplanenum; - backfacenums[numbackfaces++] = facenum; - for (k = 0; k < numbackareas; k++) - { - if (backareanums[k] == otherareanum) break; - } //end for - if (k == numbackareas) backareanums[numbackareas++] = otherareanum; - numareabackfaces[i]++; - } //end else - else - { - return 0; - } //end else - } //end for - } //end for - //every area should have at least one front face and one back face - for (i = 0; i < numareas; i++) - { - if (!numareafrontfaces[i] || !numareabackfaces[i]) return 0; - } //end for - //the front areas should all be connected - if (!AAS_ConnectedAreas(frontareanums, numfrontareas)) return 0; - //the back areas should all be connected - if (!AAS_ConnectedAreas(backareanums, numbackareas)) return 0; - //none of the front faces should have a shared edge with a back face - for (i = 0; i < numfrontfaces; i++) - { - frontface = &aasworld.faces[frontfacenums[i]]; - for (fen = 0; fen < frontface->numedges; fen++) - { - frontedgenum = abs(aasworld.edgeindex[frontface->firstedge + fen]); - for (j = 0; j < numbackfaces; j++) - { - backface = &aasworld.faces[backfacenums[j]]; - for (ben = 0; ben < backface->numedges; ben++) - { - backedgenum = abs(aasworld.edgeindex[backface->firstedge + ben]); - if (frontedgenum == backedgenum) break; - } //end for - if (ben != backface->numedges) break; - } //end for - if (j != numbackfaces) break; - } //end for - if (fen != frontface->numedges) break; - } //end for - if (i != numfrontfaces) return 0; - //set the cluster portal contents - for (i = 0; i < numareas; i++) - { - aasworld.areasettings[areanums[i]].contents |= AREACONTENTS_CLUSTERPORTAL; - //this area can be used as a route portal - aasworld.areasettings[areanums[i]].contents |= AREACONTENTS_ROUTEPORTAL; - Log_Write("possible portal: %d\r\n", areanums[i]); - } //end for - // - return numareas; -} //end of the function AAS_CheckAreaForPossiblePortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FindPossiblePortals(void) -{ - int i, numpossibleportals; - - numpossibleportals = 0; - for (i = 1; i < aasworld.numareas; i++) - { - numpossibleportals += AAS_CheckAreaForPossiblePortals(i); - } //end for - botimport.Print(PRT_MESSAGE, "\r%6d possible portal areas\n", numpossibleportals); -} //end of the function AAS_FindPossiblePortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveAllPortals(void) -{ - int i; - - for (i = 1; i < aasworld.numareas; i++) - { - aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL; - } //end for -} //end of the function AAS_RemoveAllPortals - -#if 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 -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveTeleporterPortals(void) -{ - int i, j, areanum; - - for (i = 1; i < aasworld.numareas; i++) - { - for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++) - { - areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum; - if (aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].traveltype == TRAVEL_TELEPORT) - { - aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL; - aasworld.areasettings[areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL; - break; - } //end if - } //end for - } //end for -} //end of the function AAS_RemoveTeleporterPortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_FloodClusterReachabilities(int clusternum) -{ - int i, j, areanum; - - for (i = 1; i < aasworld.numareas; i++) - { - //if this area already has a cluster set - if (aasworld.areasettings[i].cluster) continue; - //if this area is a cluster portal - if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL) continue; - //loop over the reachable areas from this area - for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++) - { - //the reachable area - areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum; - //if this area is a cluster portal - if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) continue; - //if this area has a cluster set - if (aasworld.areasettings[areanum].cluster == clusternum) - { - AAS_FloodCluster_r(i, clusternum); - i = 0; - break; - } //end if - } //end for - } //end for -} //end of the function AAS_FloodClusterReachabilities - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_RemoveNotClusterClosingPortals(void) -{ - int i, j, k, facenum, otherareanum, nonclosingportals; - aas_area_t *area; - aas_face_t *face; - - AAS_RemoveTeleporterPortals(); - // - nonclosingportals = 0; - for (i = 1; i < aasworld.numareas; i++) - { - if (!(aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)) continue; - //find a non-portal area adjacent to the portal area and flood - //the cluster from there - area = &aasworld.areas[i]; - for (j = 0; j < area->numfaces; j++) - { - facenum = abs(aasworld.faceindex[area->firstface + j]); - face = &aasworld.faces[facenum]; - // - if (face->frontarea != i) otherareanum = face->frontarea; - else otherareanum = face->backarea; - // - if (!otherareanum) continue; - // - if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) - { - continue; - } //end if - //reset all cluster fields - AAS_RemoveClusterAreas(); - // - AAS_FloodCluster_r(otherareanum, 1); - AAS_FloodClusterReachabilities(1); - //check if all adjacent non-portal areas have a cluster set - for (k = 0; k < area->numfaces; k++) - { - facenum = abs(aasworld.faceindex[area->firstface + k]); - face = &aasworld.faces[facenum]; - // - if (face->frontarea != i) otherareanum = face->frontarea; - else otherareanum = face->backarea; - // - if (!otherareanum) continue; - // - if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) - { - continue; - } //end if - // - if (!aasworld.areasettings[otherareanum].cluster) break; - } //end for - //if all adjacent non-portal areas have a cluster set then the portal - //didn't seal a cluster - if (k >= area->numfaces) - { - aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL; - nonclosingportals++; - //recheck all the other portals again - i = 0; - break; - } //end if - } //end for - } //end for - botimport.Print(PRT_MESSAGE, "\r%6d non closing portals removed\n", nonclosingportals); -} //end of the function AAS_RemoveNotClusterClosingPortals - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== - -void AAS_RemoveNotClusterClosingPortals(void) -{ - int i, j, facenum, otherareanum, nonclosingportals, numseperatedclusters; - aas_area_t *area; - aas_face_t *face; - - AAS_RemoveTeleporterPortals(); - // - nonclosingportals = 0; - for (i = 1; i < aasworld.numareas; i++) - { - if (!(aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)) continue; - // - numseperatedclusters = 0; - //reset all cluster fields - AAS_RemoveClusterAreas(); - //find a non-portal area adjacent to the portal area and flood - //the cluster from there - area = &aasworld.areas[i]; - for (j = 0; j < area->numfaces; j++) - { - facenum = abs(aasworld.faceindex[area->firstface + j]); - face = &aasworld.faces[facenum]; - // - if (face->frontarea != i) otherareanum = face->frontarea; - else otherareanum = face->backarea; - //if not solid at the other side of the face - if (!otherareanum) continue; - //don't flood into other portals - if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue; - //if the area already has a cluster set - if (aasworld.areasettings[otherareanum].cluster) continue; - //another cluster is seperated by this portal - numseperatedclusters++; - //flood the cluster - AAS_FloodCluster_r(otherareanum, numseperatedclusters); - AAS_FloodClusterReachabilities(numseperatedclusters); - } //end for - //use the reachabilities to flood into other areas - for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++) - { - otherareanum = aasworld.reachability[ - aasworld.areasettings[i].firstreachablearea + j].areanum; - //this should never be qtrue but we check anyway - if (!otherareanum) continue; - //don't flood into other portals - if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue; - //if the area already has a cluster set - if (aasworld.areasettings[otherareanum].cluster) continue; - //another cluster is seperated by this portal - numseperatedclusters++; - //flood the cluster - AAS_FloodCluster_r(otherareanum, numseperatedclusters); - AAS_FloodClusterReachabilities(numseperatedclusters); - } //end for - //a portal must seperate no more and no less than 2 clusters - if (numseperatedclusters != 2) - { - aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL; - nonclosingportals++; - //recheck all the other portals again - i = 0; - } //end if - } //end for - botimport.Print(PRT_MESSAGE, "\r%6d non closing portals removed\n", nonclosingportals); -} //end of the function AAS_RemoveNotClusterClosingPortals - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== - -void AAS_AddTeleporterPortals(void) -{ - int j, area2num, facenum, otherareanum; - char *target, *targetname, *classname; - bsp_entity_t *entities, *ent, *dest; - vec3_t origin, destorigin, mins, maxs, end; - vec3_t bbmins, bbmaxs; - aas_area_t *area; - aas_face_t *face; - aas_trace_t trace; - aas_link_t *areas, *link; - - entities = AAS_ParseBSPEntities(); - - for (ent = entities; ent; ent = ent->next) - { - classname = AAS_ValueForBSPEpairKey(ent, "classname"); - if (classname && !strcmp(classname, "misc_teleporter")) - { - if (!AAS_VectorForBSPEpairKey(ent, "origin", origin)) - { - botimport.Print(PRT_ERROR, "teleporter (%s) without origin\n", target); - continue; - } //end if - // - target = AAS_ValueForBSPEpairKey(ent, "target"); - if (!target) - { - botimport.Print(PRT_ERROR, "teleporter (%s) without target\n", target); - continue; - } //end if - for (dest = entities; dest; dest = dest->next) - { - classname = AAS_ValueForBSPEpairKey(dest, "classname"); - if (classname && !strcmp(classname, "misc_teleporter_dest")) - { - targetname = AAS_ValueForBSPEpairKey(dest, "targetname"); - if (targetname && !strcmp(targetname, target)) - { - break; - } //end if - } //end if - } //end for - if (!dest) - { - botimport.Print(PRT_ERROR, "teleporter without destination (%s)\n", target); - continue; - } //end if - if (!AAS_VectorForBSPEpairKey(dest, "origin", destorigin)) - { - botimport.Print(PRT_ERROR, "teleporter destination (%s) without origin\n", target); - continue; - } //end if - destorigin[2] += 24; //just for q2e1m2, the dork has put the telepads in the ground - VectorCopy(destorigin, end); - end[2] -= 100; - trace = AAS_TraceClientBBox(destorigin, end, PRESENCE_CROUCH, -1); - if (trace.startsolid) - { - botimport.Print(PRT_ERROR, "teleporter destination (%s) in solid\n", target); - continue; - } //end if - VectorCopy(trace.endpos, destorigin); - area2num = AAS_PointAreaNum(destorigin); - //reset all cluster fields - for (j = 0; j < aasworld.numareas; j++) - { - aasworld.areasettings[j].cluster = 0; - } //end for - // - VectorSet(mins, -8, -8, 8); - VectorSet(maxs, 8, 8, 24); - // - AAS_PresenceTypeBoundingBox(PRESENCE_CROUCH, bbmins, bbmaxs); - // - VectorAdd(origin, mins, mins); - VectorAdd(origin, maxs, maxs); - //add bounding box size - VectorSubtract(mins, bbmaxs, mins); - VectorSubtract(maxs, bbmins, maxs); - //link an invalid (-1) entity - areas = AAS_AASLinkEntity(mins, maxs, -1); - // - for (link = areas; link; link = link->next_area) - { - if (!AAS_AreaGrounded(link->areanum)) continue; - //add the teleporter portal mark - aasworld.areasettings[link->areanum].contents |= AREACONTENTS_CLUSTERPORTAL | - AREACONTENTS_TELEPORTAL; - } //end for - // - for (link = areas; link; link = link->next_area) - { - if (!AAS_AreaGrounded(link->areanum)) continue; - //find a non-portal area adjacent to the portal area and flood - //the cluster from there - area = &aasworld.areas[link->areanum]; - for (j = 0; j < area->numfaces; j++) - { - facenum = abs(aasworld.faceindex[area->firstface + j]); - face = &aasworld.faces[facenum]; - // - if (face->frontarea != link->areanum) otherareanum = face->frontarea; - else otherareanum = face->backarea; - // - if (!otherareanum) continue; - // - if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) - { - continue; - } //end if - // - AAS_FloodCluster_r(otherareanum, 1); - } //end for - } //end for - //if the teleport destination IS in the same cluster - if (aasworld.areasettings[area2num].cluster) - { - for (link = areas; link; link = link->next_area) - { - if (!AAS_AreaGrounded(link->areanum)) continue; - //add the teleporter portal mark - aasworld.areasettings[link->areanum].contents &= ~(AREACONTENTS_CLUSTERPORTAL | - AREACONTENTS_TELEPORTAL); - } //end for - } //end if - } //end if - } //end for - AAS_FreeBSPEntities(entities); -} //end of the function AAS_AddTeleporterPortals - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_AddTeleporterPortals(void) -{ - int i, j, areanum; - - for (i = 1; i < aasworld.numareas; i++) - { - for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++) - { - if (aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].traveltype != TRAVEL_TELEPORT) continue; - areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum; - aasworld.areasettings[areanum].contents |= AREACONTENTS_CLUSTERPORTAL; - } //end for - } //end for -} //end of the function AAS_AddTeleporterPortals - -#endif - -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int AAS_TestPortals(void) -{ - int i; - aas_portal_t *portal; - - for (i = 1; i < aasworld.numportals; i++) - { - portal = &aasworld.portals[i]; - if (!portal->frontcluster) - { - aasworld.areasettings[portal->areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL; - Log_Write("portal area %d has no front cluster\r\n", portal->areanum); - return qfalse; - } //end if - if (!portal->backcluster) - { - aasworld.areasettings[portal->areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL; - Log_Write("portal area %d has no back cluster\r\n", portal->areanum); - return qfalse; - } //end if - } //end for - return qtrue; -} //end of the function -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CountForcedClusterPortals(void) -{ - int num, i; - - num = 0; - for (i = 1; i < aasworld.numareas; i++) - { - if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL) - { - Log_Write("area %d is a forced portal area\r\n", i); - num++; - } //end if - } //end for - botimport.Print(PRT_MESSAGE, "%6d forced portal areas\n", num); -} //end of the function AAS_CountForcedClusterPortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_CreateViewPortals(void) -{ - int i; - - for (i = 1; i < aasworld.numareas; i++) - { - if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL) - { - aasworld.areasettings[i].contents |= AREACONTENTS_VIEWPORTAL; - } //end if - } //end for -} //end of the function AAS_CreateViewPortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_SetViewPortalsAsClusterPortals(void) -{ - int i; - - for (i = 1; i < aasworld.numareas; i++) - { - if (aasworld.areasettings[i].contents & AREACONTENTS_VIEWPORTAL) - { - aasworld.areasettings[i].contents |= AREACONTENTS_CLUSTERPORTAL; - } //end if - } //end for -} //end of the function AAS_SetViewPortalsAsClusterPortals -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void AAS_InitClustering(void) -{ - int i, removedPortalAreas; - int n, total, numreachabilityareas; - - if (!aasworld.loaded) return; - //if there are clusters - if (aasworld.numclusters >= 1) - { -#ifndef BSPC - //if clustering isn't forced - if (!((int)LibVarGetValue("forceclustering")) && - !((int)LibVarGetValue("forcereachability"))) return; -#endif - } //end if - //set all view portals as cluster portals in case we re-calculate the reachabilities and clusters (with -reach) - AAS_SetViewPortalsAsClusterPortals(); - //count the number of forced cluster portals - AAS_CountForcedClusterPortals(); - //remove all area cluster marks - AAS_RemoveClusterAreas(); - //find possible cluster portals - AAS_FindPossiblePortals(); - //craete portals to for the bot view - AAS_CreateViewPortals(); - //remove all portals that are not closing a cluster - //AAS_RemoveNotClusterClosingPortals(); - //initialize portal memory - if (aasworld.portals) FreeMemory(aasworld.portals); - aasworld.portals = (aas_portal_t *) GetClearedMemory(AAS_MAX_PORTALS * sizeof(aas_portal_t)); - //initialize portal index memory - if (aasworld.portalindex) FreeMemory(aasworld.portalindex); - aasworld.portalindex = (aas_portalindex_t *) GetClearedMemory(AAS_MAX_PORTALINDEXSIZE * sizeof(aas_portalindex_t)); - //initialize cluster memory - if (aasworld.clusters) FreeMemory(aasworld.clusters); - aasworld.clusters = (aas_cluster_t *) GetClearedMemory(AAS_MAX_CLUSTERS * sizeof(aas_cluster_t)); - // - removedPortalAreas = 0; - botimport.Print(PRT_MESSAGE, "\r%6d removed portal areas", removedPortalAreas); - while(1) - { - botimport.Print(PRT_MESSAGE, "\r%6d", removedPortalAreas); - //initialize the number of portals and clusters - aasworld.numportals = 1; //portal 0 is a dummy - aasworld.portalindexsize = 0; - aasworld.numclusters = 1; //cluster 0 is a dummy - //create the portals from the portal areas - AAS_CreatePortals(); - // - removedPortalAreas++; - //find the clusters - if (!AAS_FindClusters()) - continue; - //test the portals - if (!AAS_TestPortals()) - continue; - // - break; - } //end while - botimport.Print(PRT_MESSAGE, "\n"); - //the AAS file should be saved - aasworld.savefile = qtrue; - //write the portal areas to the log file - for (i = 1; i < aasworld.numportals; i++) - { - Log_Write("portal %d: area %d\r\n", i, aasworld.portals[i].areanum); - } //end for - // report cluster info - botimport.Print(PRT_MESSAGE, "%6d portals created\n", aasworld.numportals); - botimport.Print(PRT_MESSAGE, "%6d clusters created\n", aasworld.numclusters); - for (i = 1; i < aasworld.numclusters; i++) - { - botimport.Print(PRT_MESSAGE, "cluster %d has %d reachability areas\n", i, - aasworld.clusters[i].numreachabilityareas); - } //end for - // report AAS file efficiency - numreachabilityareas = 0; - total = 0; - for (i = 0; i < aasworld.numclusters; i++) { - n = aasworld.clusters[i].numreachabilityareas; - numreachabilityareas += n; - total += n * n; - } - total += numreachabilityareas * aasworld.numportals; - // - botimport.Print(PRT_MESSAGE, "%6i total reachability areas\n", numreachabilityareas); - botimport.Print(PRT_MESSAGE, "%6i AAS memory/CPU usage (the lower the better)\n", total * 3); -} //end of the function AAS_InitClustering -- cgit